1
0
mirror of https://github.com/LDDestroier/CC/ synced 2024-12-15 12:40:29 +00:00
ldd-CC/lddprogs
LDDestroier ba2e3432ec
Add files via upload
Progdor file
2019-01-15 18:36:20 -05:00

18861 lines
667 KiB
Plaintext
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

false
{
[ "/util/map.lua" ] = {
"--[[",
" 'Map' (GPS Minimap) by EldidiStroyrr (LDDestroier)",
"",
" Get with",
" pastebin get x9ajKSc0 map",
" or",
" std pb x9ajKSc0 map",
" std ld map map",
"",
" This is a stable release. You fool!",
"--]]",
"",
"local mapRelease = \"main\"",
"local pastebinIDList = {",
" main = \"x9ajKSc0\",",
" beta = \"KJ4t2DM9\",",
"}",
"mapVersion = \"1.3.9\" --Version of Map. Must be string.",
"os.pullEvent = os.pullEventRaw",
"local scr_x, scr_y = term.getSize()",
"local parentDir = fs.combine(\"\",fs.getDir(shell.getRunningProgram()))",
"local configDir = fs.combine(parentDir,\".map\")",
"if fs.isReadOnly(configDir) then",
" configDir = \".map\"",
"end",
"if not fs.isDir(configDir) then",
" if fs.exists(configDir) then fs.delete(configDir) end",
" fs.makeDir(configDir)",
"end",
"if fs.isReadOnly(shell.resolve(shell.getRunningProgram())) then --In case Map is located in a write-protected directory.",
" waypointDir = fs.combine(fs.getName(configDir),\"waypoints\")",
" mapConfigFile = fs.combine(fs.getName(configDir),\"config\")",
" pathDir = fs.combine(fs.getName(configDir),\"paths\")",
"else",
" waypointDir = \"/\" .. fs.combine(configDir, \"waypoints\")",
" mapConfigFile = \"/\" .. fs.combine(configDir, \"config\")",
" pathDir = fs.combine(configDir,\"paths\")",
"end",
"if not fs.exists(waypointDir) then fs.makeDir(waypointDir) end",
"if not fs.exists(pathDir) then fs.makeDir(pathDir) end",
"defaultWaypointFile = \"waypoints\" --The name of the waypoint file that is written to.",
"mapNetworkWaypointsFile = fs.combine(waypointDir,\"networkPoints\")",
"local mapName",
"local function updateMapProgram(url)",
" if not fs.isReadOnly(shell.resolve(shell.getRunningProgram())) then",
" mapName = fs.combine(\"\",shell.getRunningProgram())",
" else",
" mapName = shell.getRunningProgram()",
" end",
" local updateFile",
" if url then",
" updateFile = http.get(url)",
" else",
" updateFile = http.get(\"http://pastebin.com/raw.php?i=\" .. pastebinIDList[mapRelease])",
" end",
" if updateFile then",
" updateFile = updateFile.readAll()",
" else",
" error(\"Could not connect.\")",
" end",
" local file = fs.open(mapName, \"w\")",
" file.write(updateFile)",
" file.close()",
" return fs.getSize(mapName)",
"end",
"",
"local function setColormode()",
" if term.isColor() and colorLimit >= 2 then",
" colormode = true",
" grayAllowed = true",
" else",
" colormode = false",
" if _VERSION and colorLimit >= 1 then",
" grayAllowed = true",
" else",
" grayAllowed = false",
" end",
" end",
"end",
"",
"local nothing = false",
"local tArg = {...}",
"if tArg[1] ~= nil then",
" if tArg[1] == \"cc\" then",
" if fs.exists(mapConfigFile) then",
" fs.delete(mapConfigFile)",
" print(\"Config cleared.\")",
" else",
" print(\"No config to clear.\")",
" end",
" fakeX = nil",
" fakeY = nil",
" fakeZ = nil",
" fakeDir = nil",
" return",
" elseif tArg[1] == \"cw\" then",
" if fs.exists(waypointDir) then",
" fs.delete(waypointDir)",
" print(\"Waypoints cleared.\")",
" else",
" print(\"No waypoints to clear.\")",
" end",
" return",
" elseif tArg[1] == \"oc\" then",
" shell.run(\"edit \"..mapConfigFile)",
" print(\"Config updated.\")",
" return",
" elseif tArg[1] == \"nothing\" then",
" nothing = true",
" elseif tArg[1] == \"update\" then",
" local file = tArg[2]",
" local updateURL",
" if not tArg[2] then",
" updateURL = pastebinIDList[mapRelease]",
" else",
" if pastebinIDList[file] then",
" updateURL = pastebinIDList[file]",
" else",
" print(\"Invalid update source.\")",
" return false",
" end",
" end",
" write(\"Updating \" .. shell.getRunningProgram() .. \"...\")",
" local mapName = shell.getRunningProgram()",
" local fileSize = updateMapProgram(\"http://pastebin.com/raw.php?i=\" .. updateURL)",
" print(\"done (got \" .. fs.getSize(mapName) .. \" bytes)\")",
" write(\"Updated from \"..mapVersion)",
" shell.run(fs.getName(shell.getRunningProgram()),\"nothing\")",
" if mapVersion then",
" print(\" to \"..mapVersion)",
" else",
" print(\"...whatever.\")",
" end",
" return true",
" elseif tArg[1] == \"help\" then",
" local helpText = [[",
"'map update' Updates program.",
"'map fast' Runs term.redirect(term.native()).",
"'map cw' Deletes waypoints.",
"'map cc' Deletes config.",
"'map oc' Opens config.",
"'map nothing' gets config, but doesn't run",
"Config path: ']]..mapConfigFile..[['",
"Waypoint directory: ']]..waypointDir..[[']]",
" print(helpText)",
" return true",
" elseif tArg[1] == \"fast\" then",
" term.redirect(term.native())",
" end",
"end",
"local function runMapProgramAlready() --This is to allow me to run pcall on the program.",
"function numberToColor(input)",
" if type(input) == \"number\" then",
" for k,v in pairs(colors) do",
" if input == v then",
" return \"colors.\"..k",
" end",
" end",
" elseif type(input) == \"table\" then",
" local output = {}",
" for a = 1, #input do",
" for k,v in pairs(colors) do",
" if input[a] == v then",
" table.insert(output,\"colors.\"..k)",
" end",
" end",
" end",
" return output",
" end",
" return false",
"end",
"local function yield()",
" os.queueEvent(\"yield\")",
" os.pullEvent(\"yield\")",
"end",
"local function seperateMethods(input)",
" local output={}",
" for key,value in pairs(input) do",
" table.insert(output, {key,value})",
" end",
" return output",
"end",
"local function defineMapBorders()",
" local mapCorners",
" if not monitorMode then",
" mapCorners = { --Top left corner, bottom right corner",
" {",
" 2,",
" 2,",
" },",
" {",
" scr_x - 1,",
" scr_y - 6,",
" }",
" }",
" else",
" mapCorners = {",
" {",
" 1,",
" 1,",
" },",
" {",
" scr_x,",
" scr_y - 3,",
" }",
" }",
" end",
" corner1 = mapCorners[1]",
" corner2 = mapCorners[2]",
" midPoint = {",
" math.floor((corner1[1] + corner2[1]) / 2),",
" math.floor((corner1[2] + corner2[2]) / 2)",
" }",
" mapDimensions = {",
" corner2[1] - corner1[1],",
" corner2[2] - corner1[2]",
" }",
"end",
"defineMapBorders()",
"--[[ In case adding this to the config messes something up, I want to easily fix it.",
" mapColors = { --This controls most of the colors in the program, except for some hardcoded colors. If you are using a normal computer, grayscale or not, colors will not be pulled from this list.",
" colors.gray, --Background color (default: colors.gray)",
" colors.white, --Border color (default: colors.white)",
" colors.yellow, --Waypoint color (default: colors.yellow)",
" colors.red, --Offscreen waypoint arrow color (default: colors.red)",
" colors.lightBlue, --Direction indicator color (default: colors.lightBlue)",
" colors.black, --Command list text color (default: colors.black)",
" colors.lightGray, --Command list background color (default: colors.lightGray)",
" colors.red, --Background color if not connected to GPS server (default: colors.red)",
" colors.black, --Map background color (default: colors.black)",
" }",
" ",
" directionSensitivity = 0.15 --This is used to prevent the arrow on the middle of the screen from going crazy.",
"--]]",
"displayStuffs = true",
"currentlyConnected = false --We don't know, so assume false because of glitch with numpad",
"isConnected = false --We still don't know, and it's just safer to assume false because of visual bugs",
"arrows = {",
" \">\",",
" \"v\",",
" \"<\",",
" \"^\"",
"}",
"youChar = \"O\" --This used to be a config item, too bad it was useless. Luckily, it was replaced with many, much more useful options for you to screw up.",
"playerChar = youChar",
"function displayTitleScreen()",
" term.clear()",
" term.setCursorPos(1,1)",
" if colormode then",
" paintutils.drawImage(mapTitleScreen_adv, 1, 1)",
" else",
" if grayAllowed then",
" paintutils.drawImage(mapTitleScreen_gray, 1, 1)",
" else",
" paintutils.drawImage(mapTitleScreen_norm, 1, 1)",
" end",
" end",
" if colormode then",
" term.setTextColor(colors.black)",
" term.setBackgroundColor(colors.lightBlue)",
" else",
" if grayAllowed then",
" term.setTextColor(colors.black)",
" term.setBackgroundColor(colors.white)",
" else",
" term.setTextColor(colors.black)",
" term.setBackgroundColor(colors.white)",
" end",
" end",
" term.setCursorPos(5,4)",
" print(\"Version \" .. mapVersion)",
" term.setCursorPos(5,3)",
" print(\"Made by EldidiStroyrr\")",
" sleep(0.1)",
" repeat",
" event, param1 = os.pullEvent()",
" until event == \"key\" or event == \"mouse_click\" or event == \"monitor_touch\"",
"end",
"function refreshOtherConfig()",
" local file = fs.open(mapConfigFile, \"w\")",
" local mapSettings = {",
" {",
" \"spoofMode = \" .. tostring(spoofMode),",
" \"boolean, set true if testing program in emulator. Replaces gps movement detection with arrow keys. Default: false\",",
" },",
" {",
" \"broadcastData = \" .. tostring(broadcastData),",
" \"boolean, set true if you want other people to see your location. Default: true\",",
" },",
" {",
" \"networkName = '\" .. tostring(networkName) .. \"'\",",
" \"string, what your name appears as for other Map clients. Default: 'mapuser'..math.random(1,9999)\",",
" },",
" {",
" \"mapProtocol = \" .. textutils.serialize(mapProtocol),",
" \"table, list of modem protocols of the data broadcasted to other clients. Default: {10666}\",",
" },",
" {",
" \"scaleFactor = \" .. tostring(scaleFactor),",
" \"number, the zoom factor for the minimap. Lower means wider range. Does not affect GPS range. Default: 0.25\",",
" },",
" {",
" \"displayTitle = \" .. tostring(displayTitle),",
" \"boolean, whether or not to display the title screen. I find it kind of garish, but I already did the work. Default: false\",",
" },",
" {",
" \"labelMode = \" .. tostring(labelMode),",
" \"boolean, true if waypoint labels are their names, false if their distances. Default: true\",",
" },",
" {",
" \"waypointChar = '\" .. tostring(waypointChar) .. \"'\",",
" \"string, the character that waypoints on the map are represented by. Default: '*'\",",
" },",
" {",
" \"blankChar = '\" .. tostring(blankChar) .. \"'\",",
" \"string, the blank character that the inside of the map is made of. Default: ' '\",",
" },",
" {",
" \"refreshSleep = \" .. tostring(refreshSleep),",
" \"number, the delay between each GPS request. Default: 0.4\",",
" },",
" {",
" \"autoUpdate = \" .. tostring(autoUpdate),",
" \"boolean, whether or not Map automatically updates to the latest version. this is reccommended FALSE because new updates could break the program into a state where it can't update again. Default: false\",",
" },",
" {",
" \"turtleMode = \" .. tostring(turtleMode),",
" \"boolean, whether Map should be tuned to turtle controlling. Especially useful if used in conjunction with Lyqyd's NSH. Default: false\",",
" },",
" {",
" \"keyAgoesRight = \" .. tostring(keyAgoesRight),",
" \"boolean, determines whether to invert the left/right turtle turning controls. Requires turtleMode=true. This option exists because the 'A' button turns the turtle left on the map, but not in minecraft world. Default: false\",",
" },",
" {",
" \"spoofStep = \" .. tostring(spoofStep),",
" \"number, amount you move in one keypress in spoof mode. Used to move faster. Default: 1\",",
" },",
" {",
" \"mapColors = \" .. string.gsub( textutils.serialize(numberToColor(mapColors)), \"\\\"\", \"\" ),",
" \"table, there are 9 items in this array, and this controls most of the colors in the program, except for some hardcoded colors and for normal computers. The colors are, in sequence: background color outside, border color, waypoint color, offscreen waypoint arrow color, direction indicator color, command screen text color, command screen background color, background color if not connected to GPS, background color inside. Do not input any values into this config option that isn't a color, or the program will crash. Default: {colors.gray, colors.white, colors.yellow, colors.red, colors.lightBlue, colors.black, colors.lightGray, colors.red, colors.black}\",",
" },",
" {",
" \"directionSensitivity = \" .. tostring(directionSensitivity),",
" \"number, this is used to prevent the arrow on the middle of the screen from going crazy. it will only change the middle indicator if you move that amount of meters. Default: 0.15\",",
" },",
" {",
" \"monitorTextScale = \" .. tostring(monitorTextScale), ",
" \"number, this determines what scale factor the text has if Map is being ran on a monitor. Default: 0.5\",",
" },",
" {",
" \"fakeX = \" .. tostring(fakeX),",
" \"number, this is the last recorded X position of the turtle/PDA. Is used in spoofMode, and updates when using turtleMode. Default: 0\",",
" },",
" {",
" \"fakeY = \" .. tostring(fakeY),",
" \"number, same as fakeX but for Y. Default: 66\",",
" },",
" {",
" \"fakeZ = \" .. tostring(fakeZ),",
" \"number, same as fakeX but for Z. Default: 0\",",
" },",
" {",
" \"fakeDir = \" .. tostring(fakeDir),",
" \"number, equal to 'f' in Debug mode in Minecraft (F3), range=0-3. Default: nil\",",
" },",
" {",
" \"doFlash = \" .. tostring(doFlash),",
" \"boolean, whether or not to do the flash animation when starting map up or exiting a menu. Default: false\",",
" },",
" {",
" \"colorLimit = \" .. tostring(colorLimit),",
" \"number, artificially limits the color palate. (0=monochrome,1=grayscale,2=colors). Default: 2\",",
" },",
" }",
" file.writeLine(\"-\" .. \"- Do not break the format of this config.\")",
" file.writeLine(\"-\" .. \"- This is for EldidiStroyrr/LDDestroier's 'Map' (GPS Minimap). Do 'map cc' to fix broken config.\")",
" file.writeLine(\"-\" .. \"- This config has been last used on version \" .. mapVersion .. \", for reference.\")",
" for a = 1, #mapSettings do",
" file.writeLine(mapSettings[a][1] .. \" -\" .. \"-\" .. mapSettings[a][2])",
" end",
" file.writeLine(\"\")",
" file.close()",
"end",
"",
"function getConfig(mode)",
" if not fs.exists(fs.combine(waypointDir, defaultWaypointFile)) or (not fs.isDir(waypointDir)) then",
" if fs.exists(\"/.waypoints\") and (not fs.isDir(\"/.waypoints\")) then",
" fs.move(\"/.waypoints\", \"/waypoints\")",
" fs.makeDir(waypointDir)",
" fs.move(\"/waypoints\", fs.combine(waypointDir, defaultWaypointFile))",
" else",
" fs.makeDir(waypointDir)",
" file = fs.open(fs.combine(waypointDir, defaultWaypointFile), \"w\")",
" file.write({})",
" file.close()",
" end",
" end",
" local wayFiles = fs.list(waypointDir)",
" waypoints = {}",
" fileWaypoints = {}",
" for a = 1, #wayFiles do",
" if not fs.isDir(fs.combine(waypointDir, wayFiles[a])) then",
" file = fs.open(fs.combine(waypointDir, wayFiles[a]), \"r\")",
" contents = file.readAll()",
" contents = textutils.unserialize(contents)",
" file.close()",
" for b = 1, #contents do",
" table.insert(waypoints, contents[b])",
" if wayFiles[a] == defaultWaypointFile then",
" table.insert(fileWaypoints, contents[b])",
" end",
" end",
" end",
" end",
" ",
" --This part has been modified to automatically fix missing config options, at the cost of the inability to add custom ones. Sorry, but this is more useful.",
" local modem = peripheral.find(\"modem\")",
" if modem and mapProtocol then",
" for a = 1, #mapProtocol do",
" modem.close(mapProtocol[a])",
" end",
" end",
" spoofMode = false",
" broadcastData = true",
" scaleFactor = 0.25",
" networkName = \"mapuser\"..math.random(1,9999)",
" mapProtocol = {10666}",
" displayTitle = false",
" labelMode = true",
" waypointChar = '*'",
" blankChar = ' '",
" refreshSleep = 0.4",
" autoUpdate = false",
" if turtle then",
" turtleMode = true",
" else",
" turtleMode = false",
" end",
" keyAgoesRight = false --Useless and probably cauyses problems..but whatever",
" spoofStep = 1",
" mapColors = { --This controls most of the colors in the program, except for some hardcoded colors. If you are using a normal computer, grayscale or not, colors will not be pulled from this list.",
" colors.gray, --Background color outside map square",
" colors.white, --Border color",
" colors.yellow, --Default waypoint color",
" colors.red, --Off-screen waypoint text color",
" colors.lightBlue, --Player color",
" colors.black, --Command screen text color",
" colors.lightGray, --Command screen background color",
" colors.red, --Background color if not connected to a GPS server",
" colors.black, --Background color inside map square",
" }",
" directionSensitivity = 0.15 --This is used to prevent the arrow on the middle of the screen from going crazy.",
" monitorTextScale = 0.5 --This determines what scale factor the text has if Map is being ran on a monitor.",
" fakeX = 0",
" fakeY = 66",
" fakeZ = 0",
" fakeDir = 0",
" doFlash = fals",
" colorLimit = 2",
" ",
" shell.run(mapConfigFile) --Get the existing config options.",
" setColormode()",
" ",
" if not type(networkName) == \"string\" then networkName = \"mapuser\"..math.random(1,9999) end",
" if not type(mapProtocol) == \"table\" then mapProtocol = {10666} end",
" ",
" refreshOtherConfig() --Set the config file to what the variables are.",
" ",
" if scr_x > 16 or scr_y > 10 then --Determines if Map is being ran on a single monitor block.",
" monitorMode = false",
" else",
" monitorMode = true",
" end",
" if not monitorTextScale then --This whole bit is for monitors, should you be arsed to use them with this.",
" monitorTextScale = 0.5",
" end",
" if monitorTextScale < 0.5 then",
" monitorTextScale = 0.5",
" elseif monitorTextScale > 5 then",
" monitorTextScale = 5",
" end",
" if type(monitorTextScale) ~= \"number\" then",
" monitorTextScale = 0.5",
" end",
"",
" local mon = peripheral.find(\"monitor\")",
" if mon then",
" if not monitorMode then",
" mon.setTextScale(monitorTextScale)",
" else",
" mon.setTextScale(0.5)",
" end",
" end",
" if mode == \"waypoint\" then",
" return fileWaypoints",
" else",
" return contents",
" end",
"end",
"getConfig()",
"function set(list) --Used to check if a phrase is in a table. Straight from StackOverflow, by Jon Ericson.",
" local set = {}",
" for _, l in ipairs(list) do",
" set[l] = true",
" end",
" return set",
"end",
"function stringToColor(color)",
" local stringColors = {\"white\",\"orange\",\"magneta\",\"lightBlue\",\"yellow\",\"lime\",\"pink\",\"gray\",\"lightGray\",\"cyan\",\"purple\",\"blue\",\"brown\",\"green\",\"red\",\"black\"}",
" local numberColors = {colors.white,colors.orange,colors.magneta,colors.lightBlue,colors.yellow,colors.lime,colors.pink,colors.gray,colors.lightGray,colors.cyan,colors.purple,colors.blue,colors.brown,colors.green,colors.red,colors.black}",
" if string.sub(color, 1, 7) == \"colors.\" then",
" color = string.sub(color, 8)",
" end",
" for a = 1, #stringColors do",
" if string.lower(color) == string.lower(stringColors[a]) then",
" return numberColors[a]",
" end",
" end",
" return false",
"end",
"function setConfig(pointname, mode, x, y, z, derf)",
" config = getConfig(\"waypoint\")",
" file = fs.open(fs.combine(waypointDir, defaultWaypointFile), \"w\")",
" if mode == \"delete\" then",
" for a = 1, #config do",
" point = config[a]",
" if point[1] == pointname then",
" table.remove(config, a)",
" file.writeLine(textutils.serialize(config))",
" file.close()",
" getConfig()",
" return true",
" end",
" end",
" file.close()",
" return false",
" elseif mode == \"add\" then",
" if x == nil or y == nil or z == nil then",
" file.close()",
" return false",
" end",
" table.insert(config, {pointname, x, y, z, derf})",
" file.writeLine(textutils.serialize(config))",
" file.close()",
" getConfig()",
" return true",
" elseif mode == \"rename\" then",
" for a = 1, #config do",
" point = config[a]",
" if point[1] == pointname then",
" table.remove(point, 1)",
" table.insert(point, 1, x)",
" file.writeLine(textutils.serialize(config))",
" file.close()",
" getConfig()",
" return true",
" end",
" end",
" file.close()",
" return false",
" end",
" file.close()",
"end",
"local function round(num, idp)",
" local mult=10^(idp or 0)",
" return math.floor(num * mult + 0.5 ) / mult",
"end",
"local function setDefaultBackgroundColor()",
" if isConnected then",
" if colormode then",
" term.setBackgroundColor(mapColors[1])",
" else",
" if grayAllowed then",
" term.setBackgroundColor(colors.gray)",
" else",
" term.setBackgroundColor(colors.black)",
" end",
" end",
" else",
" if colormode then",
" term.setBackgroundColor(mapColors[8])",
" else",
" term.setBackgroundColor(colors.white)",
" end",
" end",
"end",
"local function setDefaultTextColor()",
" if colormode then",
" term.setTextColor(mapColors[2])",
" else",
" if isConnected then",
" term.setTextColor(colors.white)",
" else",
" term.setTextColor(colors.black)",
" end",
" end",
"end",
"local function setDefaultColors()",
" setDefaultTextColor()",
" setDefaultBackgroundColor()",
"end",
"local recordBuffer = {}",
"if not oldCoord_x then",
" oldCoord_x, oldCoord_y, oldCoord_z = 0,0,0",
" posX, posY, posZ = 0,0,0",
"end",
"local function savePath(path)",
" if not path then return false, \"you need a table.\" end",
" local pathpath",
" setDefaultColors()",
" term.clear()",
" term.setCursorPos(1,2)",
" print(\"Save path as: (blank for cancel)\")",
" repeat",
" write(\">\")",
" pathpath = read()",
" if pathpath == \"\" then",
" print(\"Cancelling.\")",
" sleep(0.2)",
" return false",
" end",
" if fs.exists(fs.combine(pathDir,pathpath)) then",
" pathpath = \"\"",
" print(\"That already exists.\")",
" end",
" until pathpath ~= \"\"",
" pathpath = fs.combine(pathDir,pathpath)",
" local file = fs.open(pathpath,\"w\")",
" file.writeLine(textutils.serialize(path))",
" file.close()",
" print(\"Okay!\")",
" sleep(0.2)",
" return true",
"end",
"local function getCoordinates()",
" if spoofMode then",
" isConnected = true",
" currentlyConnected = true",
" os.queueEvent(\"gpsRequest\", true)",
" return {fakeX, fakeY, fakeZ}",
" else",
" oldCoord_x, oldCoord_y, oldCoord_z = coord_x, coord_y, coord_z",
" coord_x, coord_y, coord_z = gps.locate(5)",
" if (coord_x == nil) and isConnected then",
" currentlyConnected = false",
" os.queueEvent(\"gpsRequest\", false)",
" if displayStuffs then",
" term.setCursorPos(1,1)",
" if colormode then",
" term.setTextColor(colors.lightGray)",
" else",
" term.setTextColor(colors.white)",
" end",
" end",
" if isConnected then",
" if displayStuffs then",
" term.clearLine()",
" print(\"GPS not found...searching\")",
" end",
" for a = 1, 5 do",
" coord_x, coord_y, coord_z = gps.locate(1)",
" if coord_x == nil then os.queueEvent(\"gpsRequest\", false) end",
" end",
" if displayStuffs then",
" if coord_x == nil then",
" term.clearLine()",
" end",
" end",
" end",
" end",
" if coord_x == nil then",
" isConnected = false",
" os.queueEvent(\"gpsRequest\", false)",
" return nil",
" else",
" isConnected = true",
" currentlyConnected = true",
" os.queueEvent(\"gpsRequest\", true)",
" fakeX, fakeY, fakeZ = coord_x, coord_y, coord_z",
" if recording then",
" if (math.floor(coord_x) ~= math.floor(oldCoord_x)) or (math.floor(coord_y) ~= math.floor(oldCoord_y)) or (math.floor(coord_z) ~= math.floor(oldCoord_z)) then",
" table.insert(recordBuffer,{math.floor(coord_x),math.floor(coord_y),math.floor(coord_z)})",
" end",
" else",
" if #recordBuffer > 0 then",
" currentLocation = \"savePath\"",
" displayStuffs = false",
" savePath(recordBuffer)",
" displayStuffs = true",
" redrawMap = true",
" renderCommands()",
" currentLocation = \"renderMap\"",
" end",
" recordBuffer = {}",
" end",
" return {coord_x, coord_y, coord_z}",
" end",
" end",
"end",
"",
"local function rollOver(input, max)",
" return math.floor(input % max)",
"end",
"",
"local function drawMovingLine(ypos, size, speed, spacesize)",
" for a = 1, size do",
" if currentLocation == \"waypointSettings\" then",
" term.setCursorPos(1,ypos)",
" if colormode then",
" term.setTextColor(colors.orange)",
" else",
" if grayAllowed then",
" term.setTextColor(colors.lightGray)",
" else",
" if isConnected then",
" term.setTextColor(colors.white)",
" else",
" term.setTextColor(colors.black)",
" end",
" end",
" end",
" for x = 1, scr_x do",
" if rollOver(x - a, size) < spacesize then",
" write(\" \")",
" else",
" write(\"-\")",
" end",
" end",
" sleep(speed)",
" end",
" end",
"end",
"",
"function flashScreen(times)",
" if (not times) or (type(times) ~= \"number\") then",
" times = 1",
" end",
" if colormode or grayAllowed then",
" flashes = {",
" colors.black,",
" colors.gray,",
" colors.lightGray,",
" colors.white,",
" colors.lightGray,",
" colors.black,",
" }",
" else",
" flashes = {",
" colors.black,",
" colors.white,",
" }",
" end",
" if doFlash then",
" for a = 1, times do",
" for b = 1, #flashes do",
" term.setBackgroundColor(flashes[b])",
" term.clear()",
" sleep(0)",
" end",
" end",
" end",
" flashes = nil",
" setDefaultColors()",
"end",
"",
"--These functions were made by PhyscoKillerMonkey. It's subject to change...",
"local function forward()",
" while not mapturt.forward() do",
"-- print(\"Can't move, checking fuel\")",
" if turtle.getFuelLevel() == 0 then",
" turtle.select(1)",
" turtle.refuel(1)",
" end",
" if digBlocks then",
" turtle.dig()",
" else",
" mapturt.up()",
" goneUp = goneUp + 1",
" cy = cy + 1",
" end",
" end",
" if dir == 0 then cz = cz + 1",
" elseif dir == 1 then cx = cx - 1",
" elseif dir == 2 then cz = cz - 1",
" elseif dir == 3 then cx = cx + 1 end",
" while goneUp > 0 and not turtle.detectDown() do",
" mapturt.down()",
" goneUp = goneUp - 1",
" cy = cy - 1",
" end",
"end",
"local function up()",
" while not mapturt.up() do",
"-- print(\"Can't move, checking fuel\")",
" if turtle.getFuelLevel() == 0 then",
" turtle.select(1)",
" turtle.refuel(1)",
" end",
" if digBlocks then",
" turtle.digUp()",
" end",
" end",
" cy = cy + 1",
"end",
"local function down()",
" while not mapturt.down() do",
"-- print(\"Can't move, checking fuel\")",
" if turtle.getFuelLevel() == 0 then",
" turtle.select(1)",
" turtle.refuel(1)",
" end",
" if digBlocks then",
" turtle.digDown()",
" end",
" end",
" cy = cy - 1",
"end",
"local function getPos()",
"-- print(\"Getting position\")",
" local cx, cy, cz = gps.locate(5)",
" print(cx, cy, cz)",
"end",
"local function getDir()",
"-- print(\"Getting direction\")",
" getPos()",
" local ox, oy, oz = cx, cy, cz",
" forward()",
" getPos()",
" if oz > cz then dir = 0",
" elseif oz < cz then dir = 2",
" elseif ox < cx then dir = 1",
" elseif ox > cx then dir = 3 end",
" --print(dir)",
" mapturt.back()",
" getPos()",
"end",
"local function turn(d)",
"-- getDir()",
"-- print(\"Aligning\")",
"-- print(dir, d)",
" while dir ~= d do",
" mapturt.turnRight()",
" dir = dir + 1",
" if dir == 4 then dir = 0 end",
" end",
"end",
"local function moveX()",
"-- print(\"Moving X\")",
"-- getPos()",
" if gox > cx then",
" turn(1)",
" for x = 1, gox - cx do",
" forward()",
" cx = cx + 1",
" end",
" elseif gox < cx then",
" turn(3)",
" for x = 1, cx - gox do",
" forward()",
" cx = cx - 1",
" end",
" end",
"end",
"local function moveZ()",
"-- print(\"Moving Z\")",
"-- getPos()",
" if goz > cz then",
" turn(2)",
" for z = 1, goz - cz do",
" forward()",
" cz = cz + 1",
" end",
" elseif goz < cz then",
" turn(0)",
" for z = 1, cz - goz do",
" forward()",
" cz = cz - 1",
" end",
" end",
"end",
"local function moveY()",
"-- print(\"Moving Y\")",
"-- getPos()",
" if goy > cy then",
" for z = 1, goy - cy do",
" up()",
" cy = cy + 1",
" end",
" elseif goy < cy then",
" for z = 1, cy - goy do",
" down()",
" cy = cy - 1",
" end",
" end",
"end",
"",
"function clearMap()",
" if displayStuffs then",
" if not doGrid then",
" setDefaultTextColor()",
" if colormode then",
" term.setBackgroundColor(mapColors[9])",
" else",
" term.setBackgroundColor(colors.black)",
" end",
" local mapLengthInner = (corner2[1]) - (corner1[1]) - 1",
" local longBlankChar1 = string.rep(blankChar, mapLengthInner)",
" for y = corner1[2] + 1, corner2[2] - 1 do",
" term.setCursorPos(corner1[1]+1,y)",
" if y == math.floor(midPoint[2]) then",
" write(string.rep(blankChar, math.ceil(mapLengthInner/2)-1))",
" term.setCursorPos(midPoint[1]+1,y)",
" write(string.rep(blankChar, math.floor(mapLengthInner/2)))",
" else",
" write(longBlankChar1)",
" end",
" end",
" setDefaultColors()",
" for y = corner1[2], corner2[2] do",
" term.setCursorPos(corner1[1]-1,y)",
" write(\" \") --I do \" \" because 'blankChar' is for the inside of the map.",
" end",
" for y = corner1[2], corner2[2] do",
" term.setCursorPos(corner2[1]+1,y)",
" write(\" \") --Same here.",
" end",
" if isConnected then",
" term.setCursorPos(1,corner1[2]-1)",
" term.clearLine()",
" end",
" end",
" end",
" return",
"end",
"local commandXYPoses",
"function drawBorder()",
" defineMapBorders()",
" if displayStuffs then",
" if colormode then",
" term.setTextColor(colors.lightGray)",
" term.setBackgroundColor(mapColors[2])",
" else",
" if isConnected then",
" term.setTextColor(colors.white)",
" term.setBackgroundColor(colors.white)",
" else",
" if grayAllowed then",
" term.setTextColor(colors.white)",
" term.setBackgroundColor(colors.gray)",
" else",
" term.setTextColor(colors.white)",
" term.setBackgroundColor(colors.black)",
" end",
" end",
" end",
" local mapLength = corner2[1] - corner1[1]",
" local mapHeight = corner2[2] - corner1[2]",
" local longMapChar = string.rep(\" \", mapLength)",
" local longMapCharHalf = string.rep(\" \", math.floor(mapLength/2))",
" term.setCursorPos(corner1[1],corner1[2])",
" write(longMapCharHalf)",
" term.setCursorPos(midPoint[1]+1,corner1[2])",
" write(longMapCharHalf)",
" term.setCursorPos(corner1[1],corner2[2])",
" write(longMapChar)",
" for b = corner1[2], corner2[2] do",
" term.setCursorPos(corner1[1],b)",
" if b ~= midPoint[2] then",
" write(\" \")",
" else",
" write(\"X\")",
" end",
" end",
" for b = corner1[2], corner2[2] do",
" term.setCursorPos(corner2[1],b)",
" write(\" \")",
" end",
" ",
" term.setCursorPos(midPoint[1],corner1[2])",
" write(\"Z\")",
"-- term.setCursorPos(corner1[1],midPoint[2])",
"-- write(\"X\")",
" setDefaultColors()",
" end",
" return",
"end",
"",
"function drawScaleIndicator()",
" if math.floor(scaleFactor*100000) == 0 then",
" scaleFactor = 0.01",
" end",
" if displayStuffs then",
" scaleX = corner1[1] + 1",
" if not monitorMode then",
" scaleY = corner2[2] + 1",
" else",
" scaleY = scr_y - 2",
" end",
" term.setCursorPos(scaleX,scaleY)",
" setDefaultColors()",
" term.clearLine()",
" if isConnected then",
" term.setTextColor(colors.white)",
" else",
" if colormode then",
" term.setTextColor(colors.white)",
" else",
" if grayAllowed then",
" term.setTextColor(colors.gray)",
" else",
" term.setTextColor(colors.black)",
" end",
" end",
" end",
" write(\"Scale: \")",
" if colormode then",
" term.setTextColor(colors.orange)",
" else",
" if grayAllowed then",
" term.setTextColor(colors.lightGray)",
" else",
" if isConnected then",
" term.setTextColor(colors.white)",
" else",
" term.setTextColor(colors.black)",
" end",
" end",
" end",
" if not monitorMode then",
" write(table.concat({string.sub(scaleFactor, 1, 12),\"x\"}))",
" else",
" write(table.concat({string.sub(scaleFactor, 1, 6),\"x\"}))",
" end",
" end",
"end",
"",
"local function printOutput(commie)",
" local oldCurX, oldCurY = term.getCursorPos()",
" if type(commie) == \"table\" then",
" for a = 1, #commie do",
" term.setCursorPos(2,scr_y-(#commie-a))",
" if colormode then",
" term.setTextColor(colors.gray)",
" term.setBackgroundColor(colors.lightGray)",
" else",
" term.setTextColor(colors.black)",
" term.setBackgroundColor(colors.white)",
" end",
" term.clearLine()",
" write(tostring(commie[a]))",
" end",
" else",
" setDefaultColors()",
" term.setCursorPos(1,scr_y-1)",
" term.clearLine()",
" term.setCursorPos(2,scr_y)",
" if colormode then",
" term.setTextColor(colors.gray)",
" term.setBackgroundColor(colors.lightGray)",
" else",
" term.setTextColor(colors.black)",
" term.setBackgroundColor(colors.white)",
" end",
" term.clearLine()",
" write(tostring(commie))",
" if turtle then",
" if type(turtle.getFuelLevel()) ~= \"string\" then",
" if turtle.getFuelLevel() < 1 then",
" write(\" (out of fuel)\")",
" else",
" write(\" (fuel:\" .. turtle.getFuelLevel() .. \")\")",
" end",
" else",
" write(\" (fuel:\" .. turtle.getFuelLevel() .. \")\")",
" end",
" end",
" end",
" term.setCursorPos(oldCurX,oldCurY)",
" setDefaultColors()",
" return commie",
"end",
"",
"local renderMap = function()",
" getCoordinates()",
" setDefaultColors()",
" term.clear()",
" drawBorder()",
" clearMap()",
" redrawMap = true",
" renderCommands()",
" changedDirection = false",
" if turtleMode then printOutput(\"turtleMode activated!\") end",
" local poses",
" while true do",
" if displayStuffs then",
" wasConnected = true",
" repeat",
" poses = getCoordinates()",
" if not isConnected then",
" if displayStuffs then",
" if colormode then",
" term.setBackgroundColor(mapColors[8])",
" else",
" term.setBackgroundColor(colors.white)",
" end",
" term.clear()",
" drawBorder()",
" renderCommands()",
" end",
" repeat",
" poses = getCoordinates()",
" sleep(0)",
" until isConnected",
" if displayStuffs then",
" setDefaultColors()",
" term.clear()",
" renderCommands()",
" drawBorder()",
" end",
" end",
" until isConnected",
" if displayStuffs then",
" setDefaultColors()",
" end",
" end",
" oldCoord_x = posX",
" oldCoord_y = posY",
" oldCoord_z = posZ",
" posX = poses[1]",
" posY = poses[2]",
" posZ = poses[3]",
" if oldCoord_x ~= nil then",
" if math.abs(oldCoord_x - posX) > directionSensitivity or math.abs(oldCoord_z - posZ) > directionSensitivity and not (turtleMode and changedDirection and turtle) then",
" if math.abs(oldCoord_x - posX) > math.abs(oldCoord_z - posZ) and oldCoord_x - posX > 0 then",
" direction_long = \"east\"",
" direction = \"east\"",
" changedDirection = true",
" elseif math.abs(oldCoord_x - posX) > math.abs(oldCoord_z - posZ) and oldCoord_x - posX < 0 then",
" direction_long = \"west\"",
" direction = \"west\"",
" changedDirection = true",
" elseif math.abs(oldCoord_z - posZ) > math.abs(oldCoord_x - posX) and oldCoord_z - posZ > 0 then",
" direction_lat = \"south\"",
" direction = \"south\"",
" changedDirection = true",
" elseif math.abs(oldCoord_z - posZ) > math.abs(oldCoord_x - posX) and oldCoord_z - posZ < 0 then",
" direction_lat = \"north\"",
" direction = \"north\"",
" changedDirection = true",
" end",
" end",
" end",
" if displayStuffs then",
" setDefaultColors()",
" if ((oldCoord_x ~= posX or oldCoord_z ~= posZ) or hadCleared) and displayStuffs then",
" drawBorder()",
" clearMap()",
" hadCleared = false",
" end",
" if oldCoord_x ~= posX or oldCoord_z ~= posZ or oldCoord_y ~= posY or redrawMap == true then",
" redrawMap = false",
" for a = 1, #waypoints do",
" point = waypoints[a]",
" wayX = point[2]",
" wayY = point[3]",
" wayZ = point[4]",
" waypointColor = point[5]",
" waypointNewchar = point[6]",
" ",
" oldItemX = itemX",
" oldItemZ = itemZ",
" ",
" itemX = math.floor((midPoint[1] + (posX - math.floor(wayX)) * scaleFactor))",
" itemZ = math.floor((midPoint[2] + (posZ - math.floor(wayZ)) * scaleFactor))",
" term.setCursorPos(itemX,itemZ)",
" if itemX >= corner1[1] and itemX <= corner2[1] and itemZ <= corner2[2] and itemZ >= corner1[2] then",
" if not (itemX == math.floor(midPoint[1]) and itemZ == math.floor(midPoint[2])) then",
" if isConnected then",
" if ((itemZ == corner1[2] or itemZ == corner2[2]) or (itemX == corner1[1] or itemX == corner2[1])) and ((itemX >= corner1[1] and itemX <= corner2[1]) and (itemZ >= corner1[2] and itemZ <= corner2[2])) then",
" term.setCursorPos(itemX,itemZ)",
" if colormode then",
" if waypointColor then",
" term.setTextColor(waypointColor)",
" else",
" term.setTextColor(mapColors[3])",
" end",
" term.setBackgroundColor(mapColors[2])",
" else",
" if grayAllowed then",
" term.setTextColor(colors.gray)",
" term.setBackgroundColor(colors.white)",
" else",
" term.setTextColor(colors.black)",
" term.setBackgroundColor(colors.white)",
" end",
" end",
" else",
" if colormode then",
" if waypointColor then",
" term.setTextColor(waypointColor)",
" else",
" term.setTextColor(mapColors[3])",
" end",
" term.setBackgroundColor(mapColors[9])",
" else",
" term.setTextColor(colors.white)",
" term.setBackgroundColor(colors.black)",
" end",
" end",
" if not waypointNewchar then",
" write(waypointChar)",
" else",
" write(tostring(waypointNewchar))",
" end",
" else",
" if colormode then",
" term.setTextColor(mapColors[8])",
" else",
" term.setTextColor(colors.black)",
" end",
" end",
" end",
" else",
" if colormode then",
" if waypointColor then",
" term.setTextColor(waypointColor)",
" else",
" term.setTextColor(mapColors[4])",
" end",
" term.setBackgroundColor(mapColors[2])",
" else",
" term.setTextColor(colors.black)",
" term.setBackgroundColor(colors.white)",
" end",
" if itemX <= corner1[1] and itemZ <= corner2[2] and itemZ >= corner1[2] then",
" term.setCursorPos(corner1[1],itemZ)",
" write(\"<\")",
" elseif itemX <= corner1[1] and itemZ <= corner1[2] then",
" term.setCursorPos(corner1[1],corner1[2])",
" if (itemX+corner1[1]) * -1 >= (itemZ+corner1[2]) * -1 then",
" write(\"<\")",
" else",
" write(\"^\")",
" end",
" elseif itemX <= corner1[1] and itemZ >= corner2[2] then",
" term.setCursorPos(corner1[1],corner2[2])",
" if (itemX+corner1[1]) * -1 >= (itemZ-corner2[2]) then",
" write(\"<\")",
" else",
" write(\"v\")",
" end",
" elseif itemX >= corner2[1] and itemZ <= corner2[2] and itemZ >= corner1[2] then",
" term.setCursorPos(corner2[1],itemZ)",
" write(\">\")",
" elseif itemX >= corner2[1] and itemZ <= corner1[2] then",
" term.setCursorPos(corner2[1],corner1[2])",
" if (itemX-corner1[1]) >= (itemZ+corner1[2]) * -1 then",
" write(\">\")",
" else",
" write(\"^\")",
" end",
" elseif itemX >= corner2[1] and itemZ >= corner2[2] then",
" term.setCursorPos(corner2[1],corner2[2])",
" if (itemX-corner2[1]) >= (itemZ-corner2[2]) then",
" write(\">\")",
" else",
" write(\"v\")",
" end",
" elseif itemX >= corner1[1] and itemX <= corner2[1] and itemZ <= corner1[2] then",
" term.setCursorPos(itemX,corner1[2])",
" write(\"^\")",
" elseif itemX >= corner1[1] and itemX <= corner2[1] and itemZ >= corner2[2] then",
" term.setCursorPos(itemX,corner2[2])",
" write(\"v\")",
" end",
" ",
" if colormode then",
" term.setTextColor(mapColors[3])",
" else",
" term.setTextColor(colors.white)",
" term.setBackgroundColor(colors.black)",
" end",
" end",
" setDefaultColors()",
" if itemZ < corner2[2] + 2 then",
" if labelMode == true then",
" pointName = point[1]",
" pointMidX = math.ceil(itemX - (#pointName / 2))",
" pointMidZ = itemZ - 1",
" term.setCursorPos(pointMidX,pointMidZ)",
" elseif labelMode == false then",
" pointName = tostring(round(math.sqrt((point[2]-posX)^2 + (point[3]-posY)^2 + (point[4]-posZ)^2), 2))",
" pointMidX = itemX - math.floor(#pointName / 2)",
" pointMidZ = itemZ - 1",
" term.setCursorPos(pointMidX,pointMidZ)",
" end",
" if pointMidX + #pointName >= scr_x then",
" subLength = (scr_x - pointMidX) + 1",
" subName = string.sub(pointName, 1, subLength)",
" if pointMidX <= scr_x + 1 then",
" pointName = subName",
" end",
" end",
" if pointMidX <= scr_x then",
" for i = 1, #pointName do",
" labelPosX, labelPosY = term.getCursorPos()",
" term.setCursorPos(labelPosX,labelPosY)",
" if ((labelPosY == corner1[2] or labelPosY == corner2[2]) or (labelPosX == corner1[1] or labelPosX == corner2[1])) and ((labelPosX >= corner1[1] and labelPosX <= corner2[1]) and (labelPosY >= corner1[2] and labelPosY <= corner2[2])) then",
" if colormode then",
" term.setTextColor(mapColors[1])",
" term.setBackgroundColor(mapColors[2])",
" else",
" if grayAllowed then",
" term.setTextColor(colors.gray)",
" term.setBackgroundColor(colors.white)",
" else",
" term.setTextColor(colors.black)",
" term.setBackgroundColor(colors.white)",
" end",
" end",
" else",
" if colormode then",
" term.setBackgroundColor(mapColors[9])",
" if wayY >= posY then",
" term.setTextColor(mapColors[3])",
" else",
" term.setTextColor(colors.lightGray)",
" end",
" else",
" if grayAllowed then",
" term.setBackgroundColor(colors.black) ",
" if wayY >= posY then",
" term.setTextColor(colors.white)",
" else",
" term.setTextColor(colors.lightGray)",
" end",
" else",
" if wayY >= posY then",
" term.setTextColor(colors.white)",
" term.setBackgroundColor(colors.black)",
" else",
" term.setTextColor(colors.white)",
" term.setBackgroundColor(colors.black)",
" end",
" end",
" end",
" end",
" if (labelPosX == 1 or labelPosX == scr_x or labelPosY-1 % corner2[2] == 0) then",
" term.setBackgroundColor(mapColors[1])",
" end",
" write(string.sub(pointName, i, i))",
" end",
" end",
" end",
" setDefaultColors()",
" end",
" end --Do not remove this end.",
" term.setCursorPos(midPoint[1],midPoint[2])",
" if colormode then",
" if recording then",
" term.setTextColor(colors.white)",
" else",
" term.setTextColor(mapColors[5])",
" end",
" term.setBackgroundColor(mapColors[9])",
" else",
" if grayAllowed then",
" if recording then",
" term.setTextColor(colors.black)",
" else",
" term.setTextColor(colors.lightGray)",
" end",
" if isConnected then",
" term.setBackgroundColor(colors.black)",
" else",
" term.setBackgroundColor(colors.white)",
" end",
" else",
" if recording then",
" term.setTextColor(colors.black)",
" else",
" term.setTextColor(colors.white)",
" end",
" if isConnected then",
" term.setBackgroundColor(colors.black)",
" else",
" term.setBackgroundColor(colors.white)",
" end",
" end",
" end",
" if not turtleMode then",
" if direction == \"east\" then",
" playerChar = \">\"",
" elseif direction == \"west\" then",
" playerChar = \"<\"",
" elseif direction == \"south\" then",
" playerChar = \"v\"",
" elseif direction == \"north\" then",
" playerChar = \"^\"",
" else",
" playerChar = \"O\"",
" end",
" else",
" if fakeDir == 0 then",
" playerChar = \"^\"",
" elseif fakeDir == 1 then",
" playerChar = \">\"",
" elseif fakeDir == 2 then",
" playerChar = \"v\"",
" elseif fakeDir == 3 then",
" playerChar = \"<\"",
" else",
" playerChar = \"O\"",
" end",
" end",
" write(playerChar)",
" end",
" if not spoofMode then",
" sleep(refreshSleep)",
" else",
" sleep(0)",
" end",
" end",
"end",
"",
"local commands = {",
" \"(L)abel/dist\",",
" \"Optio(n)s\",",
" \"E(x)it\",",
"}",
"",
"function renderCommands()",
" commandXYPoses = {} --Allows me to click on the commands with captureMouseInput()",
" if not isConnected and not monitorMode then",
" term.setCursorPos(2,1)",
" if colormode then",
" term.setTextColor(colors.gray)",
" else",
" term.setTextColor(colors.black)",
" end",
" gpsNotFoundString = \"GPS not found.\"",
" term.clearLine()",
" write(gpsNotFoundString)",
" end",
" startX = 2",
" if not monitorMode then",
" startY = corner2[2] + 1",
" else",
" startY = scr_y - 3",
" end",
" commandX = startX",
" commandY = startY + 1",
" if displayStuffs then",
" term.setCursorPos(commandX,commandY)",
" if colormode then",
" term.setTextColor(mapColors[6])",
" term.setBackgroundColor(mapColors[7])",
" else",
" term.setTextColor(colors.black)",
" if grayAllowed then",
" term.setBackgroundColor(colors.lightGray)",
" else",
" term.setBackgroundColor(colors.white)",
" end",
" end",
" term.clearLine()",
" for f = 1, #commands do",
" comPosX, comPosY = term.getCursorPos()",
" if scr_x - comPosX <= string.len(commands[f]) + 1 then",
" term.setCursorPos(startX,comPosY+1)",
" term.clearLine()",
" comPosX, comPosY = term.getCursorPos()",
" end",
" write(commands[f])",
" table.insert(commandXYPoses, {comPosX, comPosY})",
" if not monitorMode then",
" if f ~= #commands then",
" write(\", \")",
" end",
" else",
" if f < 2 then",
" write(\", \")",
" end",
" end",
" end",
" drawScaleIndicator()",
" end",
" return",
"end",
"term.setBackgroundColor(colors.black)",
"term.clear()",
"renderCommands()",
"function displayHelp()",
" term.setCursorPos(1,2)",
" setDefaultColors()",
" if colormode then",
" term.setTextColor(colors.orange)",
" end",
" print(\"GPS Minimap program by EldidiStroyrr.\")",
" setDefaultColors()",
" local helpItems = {",
" \"'map cc' clears config.\",",
" \"'map cw' clears waypoints.\",",
" \"'map oc' opens config\",",
" \"Do 'map update <main/beta>' to update.\",",
" \"Do 'map help' for help. Duh.\",",
" \"Pressing numpad '+' or '-' will zoom by 0.1\",",
" }",
" local starterX, starterY = term.getCursorPos()",
" local yOffset = 0",
" for a = 1, #helpItems do",
" term.setCursorPos(2,(a-1)+starterY+yOffset)",
" if colormode or grayAllowed then",
" term.setTextColor(colors.lightGray)",
" else",
" term.setTextColor(colors.white)",
" end",
" write(\"*\")",
" setDefaultColors()",
" local curX1, curY1 = term.getCursorPos()",
" print(tostring(helpItems[a]))",
" local curX2, curY2 = term.getCursorPos()",
" yOffset = yOffset + ((curY2 - curY1) - 1)",
" end",
" sleep(0.1)",
" if colormode or grayAllowed then",
" term.setTextColor(colors.lightGray)",
" end",
" print(\"\")",
" print(\"Press a key to continue.\")",
" sleep(0)",
" local event, key = os.pullEvent(\"key\")",
" return",
"end",
"function doesColorExist(color)",
" if type(color) == \"string\" then",
" local colors = set({\"white\",\"orange\",\"magneta\",\"lightBlue\",\"yellow\",\"lime\",\"pink\",\"gray\",\"lightGray\",\"cyan\",\"purple\",\"blue\",\"brown\",\"green\",\"red\",\"black\"})",
" if string.sub(color, 1, 7) == \"colors.\" then",
" if colors[string.sub(color, 8)] == true then",
" return true",
" else",
" return false",
" end",
" else",
" if colors[color] == true then",
" return true",
" else",
" return false",
" end",
" end",
" else",
" local colors = set({colors.white,colors.orange,colors.magneta,colors.lightBlue,colors.yellow,colors.lime,colors.pink,colors.gray,colors.lightGray,colors.cyan,colors.purple,colors.blue,colors.brown,colors.green,colors.red,colors.black})",
" if colors[color] == true then",
" return true",
" else",
" return false",
" end",
" end",
"end",
"function setWaypoint()",
" term.setCursorPos(1,2)",
" setDefaultColors()",
" defaultNewPointName = \"way\" --Not used, in favor of a way to cancel.",
" print(\"Set waypoint.\")",
" print(\"Call it what?\")",
" sleep(0)",
" write(\">\")",
" newName = tostring(read())",
" if newName == \"\" then",
" print(\"Cancelling.\")",
" sleep(0.2)",
" return",
" end",
" print(\"What X? (default: current xyz)\")",
" write(\">\")",
" newX = tonumber(read())",
" if newX == nil then",
" if isConnected then",
" newX = posX",
" newY = posY",
" newZ = posZ",
" else",
" print(\"Since you aren't connected to GPS, I can't set waypoints to where you are.\")",
" yield()",
" os.pullEvent(\"key\")",
" return",
" end",
" else",
" print(\"What Y? (default: here)\")",
" write(\">\")",
" newY = tonumber(read())",
" if newY == nil then",
" newY = posY",
" end",
" print(\"What Z? (default: here)\")",
" write(\">\")",
" newZ = tonumber(read())",
" if newZ == nil then",
" newZ = posZ",
" end",
" end",
" print(\"What color?\")",
" write(\">\")",
" newColor = tostring(read())",
" if not doesColorExist(newColor) then",
" print(\"Not a color. Defaulting to 'yellow'\")",
" sleep(0.2)",
" newColor = nil",
" else",
" newColor = stringToColor(newColor)",
" end",
" setConfig(newName, \"add\", newX, newY, newZ, newColor)",
" refreshOtherConfig()",
" print(\"Waypoint '\" .. newName .. \"' set!\")",
" getConfig()",
" sleep(0.2)",
"end",
"function setScale()",
" term.setCursorPos(1,2)",
" setDefaultColors()",
" print(\"Set scale factor. Currently \" .. scaleFactor .. \".\")",
" repeat",
" yield()",
" newScale = nil",
" write(\">\")",
" newScaleRaw = read()",
" if tostring(newScaleRaw) == \"\" then",
" print(\"Cancelling.\")",
" sleep(0.2)",
" return",
" end",
" newScale = tonumber(newScaleRaw)",
" if newScale == nil then",
" print(\"That's not a number!\")",
" end",
" until type(newScale) == \"number\"",
" scaleFactor = newScale",
" print(\"Scale factor set to \" .. scaleFactor .. \".\")",
" refreshOtherConfig()",
" getConfig()",
" sleep(0.2)",
" return true",
"end",
"",
"function deleteWaypoint()",
" term.setCursorPos(1,2)",
" setDefaultColors()",
" print(\"Delete what waypoint?\")",
" if colormode then",
" term.setTextColor(colors.orange)",
" end",
" for a = 1, #waypoints do",
" point = waypoints[a]",
" print(\" -'\" .. point[1] .. \"'\")",
" end",
" if colormode then",
" term.setTextColor(colors.white)",
" end",
" sleep(0)",
" write(\">\")",
" delName = tostring(read())",
" for a = 1, #waypoints do",
" point = waypoints[a]",
" if point[1] == delName then",
" setConfig(delName, \"delete\")",
" print(\"Deleted '\" .. delName .. \"'.\")",
" refreshOtherConfig()",
" getConfig()",
" sleep(0.2)",
" return true",
" end",
" end",
" print(\"Invalid waypoint '\" .. delName .. \"'!\")",
" sleep(0.2)",
" return false",
"end",
"function renameWaypoint()",
" term.setCursorPos(1,2)",
" setDefaultColors()",
" print(\"Rename which waypoint?\")",
" if colormode then",
" term.setTextColor(colors.orange)",
" end",
" for a = 1, #fileWaypoints do",
" point = fileWaypoints[a]",
" print(\" -'\" .. point[1] .. \"'\")",
" end",
" if colormode then",
" term.setTextColor(colors.white)",
" end",
" write(\">\")",
" sleep(0)",
" local renName = tostring(read())",
" print(\"Rename to what?\")",
" write(\">\")",
" renOutput = tostring(read())",
" for a = 1, #fileWaypoints do",
" local point = fileWaypoints[a]",
" if point[1] == renName then",
" setConfig(renName, \"rename\", renOutput)",
" print(\"Renamed '\" .. renName .. \"' to '\" .. renOutput .. \"'.\")",
" refreshOtherConfig()",
" getConfig()",
" sleep(0.2)",
" return true",
" end",
" end",
" print(\"Invalid waypoint '\" .. renName .. \"'!\")",
" sleep(0.2)",
" return false",
"end",
"function redrawSceen()",
" drawBorder()",
"end",
"function inspectWaypoint()",
" term.clear()",
" term.setCursorPos(1,2)",
" print(\"Inspect which waypoint?\")",
" print(\"(get x,y,z,etc.):\")",
" print(string.rep(\"-\",scr_x))",
" if colormode then",
" term.setTextColor(colors.orange)",
" end",
" for a = 1, #waypoints do",
" point = waypoints[a]",
" print(\" -'\" .. point[1] .. \"'\")",
" end",
" if colormode then",
" term.setTextColor(colors.white)",
" end",
" sleep(0)",
" write(\">\")",
" local inspName = tostring(read())",
" for a = 1, #waypoints do",
" local point = waypoints[a]",
" if point[1] == inspName then",
" term.clear()",
" term.setCursorPos(1,2)",
" print(\"Info of '\"..inspName..\"':\")",
" print(string.rep(\"-\",scr_x))",
" print(\"X = \"..point[2]..\" (you = \"..posX..\")\")",
" print(\"Y = \"..point[3]..\" (you = \"..posY..\")\")",
" print(\"Z = \"..point[4]..\" (you = \"..posZ..\")\")",
" print(\"Distance = \"..math.sqrt((point[2]-posX)^2+(point[3]-posY)^2+(point[4]-posZ)^2))",
" if type(point[7]) == \"number\" and point[7] ~= -1 then",
" write(\"Type = \")",
" if point[7] == 1 then",
" print(\"Pocket\")",
" elseif point[7] == 2 then",
" print(\"Turtle\")",
" elseif point[7] == 3 then",
" print(\"PC\")",
" end",
" write(\"\\n\")",
" end",
" if point[3] < posY then",
" print(\"It is below you.\")",
" elseif point[3] > posY then",
" print(\"It is above you.\")",
" else",
" print(\"Your altitudes are equal.\")",
" end",
" sleep(0.1)",
" os.pullEvent(\"key\")",
" return true",
" end",
" end",
" print(\"No such waypoint! Cancelling.\")",
" sleep(0.3)",
" return false",
"end",
"local function displayTurtleControls()",
" term.setCursorPos(1,2)",
" print(\"Turtle Control Scheme:\")",
" for a = 1, scr_x do write(\"-\") end",
" print(\"\")",
" print(\" Q W E U I O P <up\")",
" print(\" A S D J K L ; <front\")",
" print(\" TAB M , . / <down\")",
" print(\"\")",
" print(\" Q = down, E = up\")",
" print(\" WASD = move\")",
" print(\" U J M = hit 7 8 9 red\")",
" print(\" I K , = place 4 5 6 stone\")",
" print(\" O L . = dig 1 2 3 ctrl\")",
" print(\" P ; / = inspect\")",
" write(\" TAB = refuel\")",
" sleep(0.1)",
" os.pullEvent(\"key\")",
" return",
"end",
"function choice(input)",
" repeat",
" event, key = os.pullEvent(\"key\")",
" if type(key) == \"number\" then key = keys.getName(key) end",
" if key == nil then key = \" \" end",
" until string.find(input, key)",
" return key",
"end",
"function waypointSettings()",
" displayStuffs = false",
" setDefaultColors()",
" sleep(0)",
" term.setCursorPos(1,2)",
" print(\" Map Options:\")",
" term.setCursorPos(1,4)",
" if colormode then",
" term.setTextColor(colors.orange)",
" end",
" print(\" * (C)reate Waypoint\")",
" print(\" * (D)elete Waypoint\")",
" print(\" * (R)ename Waypoint\")",
" print(\" * Edit C(o)nfig\")",
" print(\" * (S)et Scale\")",
" print(\" * Show (H)elp\")",
" if turtleMode then print(\" * Show (t)urtle controls\") end",
" if turtleMode then print(\" * Send turtle to (p)oint\") end",
" print(\" * (I)nspect waypoint\")",
" write(\" * E(x)it\")",
" if turtleMode then",
" key = choice(\"cdroshtpix\")",
" else",
" key = choice(\"cdroshix\")",
" end",
" if key == \"d\" then",
" currentLocation = \"deleteWaypoint\"",
" setDefaultColors() displayStuffs = false",
" term.clear()",
" sleep(0)",
" deleteWaypoint()",
" term.clear()",
" currentLocation = \"renderMap\"",
" sleep(0)",
" flashScreen(1)",
" displayStuffs = true",
" redrawSceen()",
" return",
" end",
" if key == \"r\" then",
" currentLocation = \"renameWaypoint\"",
" setDefaultColors()",
" term.clear()",
" sleep(0)",
" renameWaypoint()",
" term.clear()",
" currentLocation = \"renderMap\"",
" sleep(0)",
" flashScreen(1)",
" displayStuffs = true",
" redrawSceen()",
" return",
" end",
" if key == \"s\" then",
" currentLocation = \"setScale\"",
" setDefaultColors()",
" term.clear()",
" sleep(0)",
" setScale()",
" term.clear()",
" currentLocation = \"renderMap\"",
" sleep(0)",
" flashScreen(1)",
" displayStuffs = true",
" redrawSceen()",
" drawScaleIndicator()",
" return",
" end",
" if key == \"o\" then",
" currentLocation = \"editConfig\"",
" setDefaultBackgroundColor()",
" term.clear()",
" sleep(0.1)",
" shell.run(\"edit \" .. mapConfigFile)",
" currentLocation = \"renderMap\"",
" sleep(0)",
" flashScreen(1)",
" displayStuffs = true",
" getConfig()",
" setDefaultColors()",
" term.clear()",
" redrawSceen()",
" return",
" end",
" if key == \"c\" then",
" currentLocation = \"setWaypoint\"",
" setDefaultColors()",
" term.clear()",
" sleep(0)",
" setWaypoint()",
" term.clear()",
" currentLocation = \"renderMap\"",
" sleep(0)",
" flashScreen(1)",
" displayStuffs = true",
" redrawSceen()",
" end",
" if key == \"h\" then",
" currentLocation = \"displayHelp\"",
" setDefaultColors()",
" term.clear()",
" sleep(0)",
" displayHelp()",
" term.clear()",
" currentLocation = \"renderMap\"",
" sleep(0)",
" flashScreen(1)",
" displayStuffs = true",
" clearMap()",
" drawBorder()",
" renderCommands()",
" end",
" if key == \"i\" then",
" currentLocation = \"inspectWaypoint\"",
" setDefaultColors()",
" term.clear()",
" sleep(0)",
" inspectWaypoint()",
" term.clear()",
" currentLocation = \"renderMap\"",
" sleep(0)",
" flashScreen(1)",
" displayStuffs = true",
" clearMap()",
" drawBorder()",
" renderCommands()",
" end",
" if key == \"t\" and turtleMode then",
" currentLocation = \"displayTurtleControls\"",
" setDefaultColors()",
" term.clear()",
" sleep(0)",
" displayTurtleControls()",
" term.clear()",
" currentLocation = \"renderMap\"",
" sleep(0)",
" flashScreen(1)",
" displayStuffs = true",
" clearMap()",
" drawBorder()",
" renderCommands()",
" end",
" if key == \"p\" and turtleMode then",
" currentLocation = \"turtleToPoint\"",
" setDefaultColors()",
" term.clear()",
" term.setCursorPos(1,2)",
" if isConnected then",
" print(\"Go to coordinates or waypoint?\")",
" print(\"[c/w/X]\")",
" repeat",
" sleep(0)",
" event, key = os.pullEvent(\"key\")",
" if type(key) == \"number\" then key = keys.getName(key) end",
" if key == nil then key = \" \" end",
" until string.find(\"cwx\", key)",
" print(\"\")",
" local destinationX, destinationY, destinationZ",
" if key == \"c\" then",
" print(\"Enter destination...\")",
" print(\"...X:\")",
" sleep(0)",
" destinationX = tonumber(read())",
" if destinationX == nil then",
" print(\"Not a number! Cancelling.\")",
" sleep(0.2)",
" flashScreen(1)",
" return",
" end",
" print(\"...Y:\")",
" sleep(0)",
" destinationY = tonumber(read())",
" if destinationY == nil then",
" print(\"Not a number! Cancelling.\")",
" sleep(0.2)",
" flashScreen(1)",
" return",
" end",
" print(\"...Z:\")",
" sleep(0)",
" destinationZ = tonumber(read())",
" if destinationZ == nil then",
" print(\"Not a number! Cancelling.\")",
" sleep(0.2)",
" flashScreen(1)",
" return",
" end",
" term.clear()",
" term.setCursorPos(1,2)",
" write(\"Going...\")",
" local result, bool = printOutput(goToCoordinates(destinationX, destinationY, destinationZ))",
" if not bool == false then",
" print(\"done!\")",
" sleep(0.2)",
" else",
" sleep(0.1)",
" print(\"Press a key to continue\")",
" os.pullEvent(\"key\")",
" end",
" elseif key == \"w\" then",
" print(\"Which waypoint?\")",
" if colormode then",
" term.setTextColor(colors.orange)",
" end",
" for a = 1, #waypoints do",
" point = waypoints[a]",
" print(\" -'\" .. point[1] .. \"'\")",
" end",
" if colormode then",
" term.setTextColor(colors.white)",
" end",
" sleep(0)",
" local destWaypoint = tostring(read())",
" if destWaypoint == \"\" then",
" print(\"Cancelling.\")",
" sleep(0.1)",
" flashScreen(1)",
" return",
" end",
" write(\"Going...\")",
" printOutput(goToCoordinates(tostring(destWaypoint)))",
" print(\"finished.\")",
" sleep(0.2)",
" end",
" else",
" print(\"You are not connected to a GPS server, so you cannot send turtles.\")",
" print(\"Press a key to continue\")",
" sleep(0)",
" os.pullEvent(\"key\")",
" end",
" currentLocation = \"renderMap\"",
" flashScreen(1)",
" term.clear()",
" sleep(0)",
" displayStuffs = true",
" clearMap()",
" drawBorder()",
" renderCommands()",
" redrawMap = true",
" end",
" if key == \"x\" then",
" currentLocation = \"renderMap\"",
" sleep(0)",
" flashScreen(1)",
" return",
" end",
" currentLocation = \"renderMap\"",
" return",
"end",
"function refuelTurtle(amount)",
" local originalSlot = turtle.getSelectedSlot()",
" for a = 1, 16 do",
" turtle.select(a)",
" if turtle.refuel(0) then",
" turtle.refuel(amount)",
" turtle.select(originalSlot)",
" return \"refuelled \" .. amount",
" end",
" end",
" turtle.select(originalSlot)",
" return \"can't refuel \" .. amount",
"end",
"function goToCoordinates(destX, destY, destZ)",
" if not turtleMode then",
" return \"turtleMode is not true\"",
" end",
" if destY == nil then",
" local pointName = destX",
" for a = 1, #waypoints do",
" point = waypoints[a]",
" if point[1] == pointName then",
" destX = tonumber(point[2])",
" destY = tonumber(point[3])",
" destZ = tonumber(point[4])",
" end",
" end",
" if destY == nil then",
" return \"no such waypoint\"",
" end",
" if turtle then",
" if type(turtle.getFuelLevel()) == \"number\" then",
" if math.abs(destX-posX)+math.abs(destY-posY)+math.abs(destZ-posZ) > turtle.getFuelLevel() then",
" return \"insufficient fuel\", false",
" end",
" end",
" printOutput(\"going to waypoint '\" .. pointName .. \"'\")",
" end",
" else",
" if turtle then",
" if type(turtle.getFuelLevel()) == \"number\" then",
" if math.abs(destX-posX)+math.abs(destY-posY)+math.abs(destZ-posZ) > turtle.getFuelLevel() then",
" return \"insufficient fuel\", false",
" end",
" end",
" printOutput(\"going to \" .. destX .. \",\" .. destY .. \",\" .. destZ .. \"...\")",
" end",
" end",
" --Credit to PhyscoKillerMonkey for the goto script.",
" gox = tonumber(destX)",
" goy = tonumber(destY)",
" goz = tonumber(destZ)",
" digBlocks = true",
" goneUp = 0 --dir and goneUp are used to keep track of position",
" dir = 0",
" getPos()",
" getDir()",
" if goy > cy then",
" moveY()",
" moveX()",
" moveZ()",
" else",
" moveX()",
" moveZ()",
" moveY()",
" end",
" --End of script by PhyscoKillerMonkey.",
" return \"went to coordinates \" .. destX .. \",\" .. destY .. \",\" .. destZ .. \".\"",
"end",
"local function turtleTurnLeft()",
" if direction == \"north\" then direction = \"west\"",
" elseif direction == \"west\" then direction = \"south\"",
" elseif direction == \"south\" then direction = \"east\"",
" elseif direction == \"east\" then direction = \"north\" end",
" printOutput(mapturt.turnLeft())",
"end",
"local function turtleTurnRight()",
" if direction == \"north\" then direction = \"east\"",
" elseif direction == \"east\" then direction = \"south\"",
" elseif direction == \"south\" then direction = \"west\"",
" elseif direction == \"west\" then direction = \"north\" end",
" printOutput(mapturt.turnRight())",
"end",
"local function textingPrompt()",
" term.setCursorPos(1,1)",
" term.clearLine()",
" write(\">\")",
" sleep(0)",
" local message = read()",
" if message == \"\" then",
" return false",
" else",
" local modem = peripheral.find(\"modem\")",
" if not modem then",
" return false",
" end",
" local msg = {networkName,message}",
" for a = 1, #mapProtocol do",
" modem.transmit(mapProtocol[a],mapProtocol[a],msg)",
" end",
" return true",
" end",
"end",
"local function keyPress() --Captures keypresses when normally viewing the map.",
" recording = false",
" displayStuffs = true",
" while true do",
" currentLocation = \"renderMap\"",
" local event, key = os.pullEvent(\"key\")",
" if type(key) == \"number\" then key = tostring(keys.getName(key)) end",
" if spoofMode and not turtleMode then",
" if key == \"left\" then",
" fakeX = fakeX + spoofStep",
" refreshOtherConfig()",
" sleep(0)",
" end",
" if key == \"right\" then",
" fakeX = fakeX - spoofStep",
" refreshOtherConfig()",
" sleep(0)",
" end",
" if key == \"down\" then",
" fakeZ = fakeZ - spoofStep",
" refreshOtherConfig()",
" sleep(0)",
" end",
" if key == \"up\" then",
" fakeZ = fakeZ + spoofStep",
" refreshOtherConfig()",
" sleep(0)",
" end",
" end",
" if currentlyConnected or (currentlyConnected == false and isConnected == false) then",
" if key == \"space\" then",
" recording = not recording",
" end",
" if key == \"l\" then",
" if labelMode == true then",
" labelMode = false",
" elseif labelMode == false then",
" labelMode = true",
" end",
" refreshOtherConfig()",
" drawBorder()",
" clearMap()",
" redrawMap = true",
" end",
" if key == \"t\" then",
" currentLocation = \"textingPrompt\"",
" displayStuffs = false",
" setDefaultColors()",
" textingPrompt()",
" sleep(0)",
" displayStuffs = true",
" clearMap()",
" drawBorder()",
" renderCommands()",
" redrawMap = true",
" end",
" if key == \"n\" then",
" currentLocation = \"waypointSettings\"",
" displayStuffs = false",
" setDefaultColors()",
" term.clear()",
" sleep(0)",
" os.queueEvent(\"gpsRequest\") --To make sure the line animation in the settings works.",
" waypointSettings()",
" currentLocation = \"renderMap\"",
" term.clear()",
" sleep(0)",
" displayStuffs = true",
" clearMap()",
" drawBorder()",
" renderCommands()",
" redrawMap = true",
" if turtleMode then printOutput(\"turtleMode activated!\") end",
" end",
" if key == \"numPadAdd\" or key == \"add\" then",
" scaleFactor = scaleFactor + 0.01",
" refreshOtherConfig()",
" clearMap()",
" drawBorder()",
" drawScaleIndicator()",
" redrawMap = true",
" elseif (key == \"minus\" or key == \"numPadSubtract\") and scaleFactor > 0.01 then",
" scaleFactor = scaleFactor - 0.01",
" refreshOtherConfig()",
" clearMap()",
" drawBorder()",
" drawScaleIndicator()",
" redrawMap = true",
" end",
" ",
" if turtleMode then --Used for turtle control, and is helpful with Lyqyd's NSH.",
" if turtle then",
" if key == \"w\" then printOutput(mapturt.forward()) end",
" if key == \"s\" then printOutput(mapturt.back()) end",
" if key == \"a\" then",
" if keyAgoesRight then",
" turtleTurnRight()",
" else",
" turtleTurnLeft()",
" end",
" end",
" if key == \"d\" then",
" if keyAgoesRight then",
" turtleTurnLeft()",
" else",
" turtleTurnRight()",
" end",
" end",
" ",
" if key == \"q\" then printOutput(mapturt.down()) end",
" if key == \"e\" then printOutput(mapturt.up()) end",
" ",
" if key == \"i\" then printOutput(turtle.placeUp()) end",
" if key == \"k\" then printOutput(turtle.place()) end",
" if key == \"comma\" then printOutput(turtle.placeDown()) end",
" ",
" if key == \"o\" then printOutput(turtle.digUp()) end",
" if key == \"l\" then printOutput(turtle.dig()) end",
" if key == \"period\" then printOutput(turtle.digDown()) end",
" ",
" if key == \"p\" then",
" bool, inspection = turtle.inspectUp()",
" inspection = {inspection[\"name\"], inspection[\"metadata\"]}",
" printOutput(inspection)",
" end",
" if key == \"semiColon\" then",
" bool, inspection = turtle.inspect()",
" inspection = {inspection[\"name\"], inspection[\"metadata\"]}",
" printOutput(inspection)",
" end",
" if key == \"slash\" then",
" bool, inspection = turtle.inspectDown()",
" inspection = {inspection[\"name\"], inspection[\"metadata\"]}",
" printOutput(inspection)",
" end",
" ",
" if key == \"u\" then printOutput(turtle.attackUp()) end",
" if key == \"j\" then printOutput(turtle.attack()) end",
" if key == \"m\" then printOutput(turtle.attackDown()) end",
"",
" if key == \"tab\" then printOutput(refuelTurtle(1)) end",
" ",
" if key == \"numPad8\" then",
" local rsSide = \"front\"",
" if redstone.getOutput(rsSide) == false then",
" redstone.setOutput(rsSide, true)",
" printOutput(rsSide .. \" RS on\")",
" else",
" redstone.setOutput(rsSide, false)",
" printOutput(rsSide .. \" RS off\")",
" end",
" end",
" if key == \"numPad2\" then",
" local rsSide = \"back\"",
" if redstone.getOutput(rsSide) == false then",
" redstone.setOutput(rsSide, true)",
" printOutput(rsSide .. \" RS on\")",
" else",
" redstone.setOutput(rsSide, false)",
" printOutput(rsSide .. \" RS off\")",
" end",
" end",
" if key == \"numPad4\" then",
" local rsSide = \"left\"",
" if redstone.getOutput(rsSide) == false then",
" redstone.setOutput(rsSide, true)",
" printOutput(rsSide .. \" RS on\")",
" else",
" redstone.setOutput(rsSide, false)",
" printOutput(rsSide .. \" RS off\")",
" end",
" end",
" if key == \"numPad6\" then",
" local rsSide = \"right\"",
" if redstone.getOutput(rsSide) == false then",
" redstone.setOutput(rsSide, true)",
" printOutput(rsSide .. \" RS on\")",
" else",
" redstone.setOutput(rsSide, false)",
" printOutput(rsSide .. \" RS off\")",
" end",
" end",
" if key == \"numPad7\" then",
" local rsSide = \"top\"",
" if redstone.getOutput(rsSide) == false then",
" redstone.setOutput(rsSide, true)",
" printOutput(rsSide .. \" RS on\")",
" else",
" redstone.setOutput(rsSide, false)",
" printOutput(rsSide .. \" RS off\")",
" end",
" end",
" if key == \"numPad9\" then",
" local rsSide = \"bottom\"",
" if redstone.getOutput(rsSide) == false then",
" redstone.setOutput(rsSide, true)",
" printOutput(rsSide .. \" RS on\")",
" else",
" redstone.setOutput(rsSide, false)",
" printOutput(rsSide .. \" RS off\")",
" end",
" end",
" else",
" printOutput(\"Not a turtle.\")",
" end",
" end",
" end",
" if key == \"x\" then",
" yield()",
" return",
" end",
" end",
"end",
"local function captureMouseInput()",
" while true do",
" event, param1, x, y = os.pullEvent()",
" if currentLocation == \"renderMap\" then --Very important.",
" if event == \"mouse_scroll\" and y == scaleY and (x >= scaleX and x <= (7+scaleX+#string.sub(scaleFactor, 1, 12))) then",
" if param1 == -1 then",
" scaleFactor = scaleFactor + 0.01",
" elseif param1 == 1 then",
" if scaleFactor > 0.01 then",
" scaleFactor = scaleFactor - 0.01",
" else",
" scaleFactor = 0.01",
" end",
" end",
" refreshOtherConfig()",
" clearMap()",
" drawBorder()",
" drawScaleIndicator()",
" redrawMap = true",
" elseif (event == \"mouse_click\" and param1 == 1) or (event == \"monitor_touch\") then",
" for a = 1, #commands do",
" if y == commandXYPoses[a][2] and (x >= commandXYPoses[a][1] and x <= (#commands[a]+commandXYPoses[a][1])) then",
" commandID = a",
" break",
" end",
" end",
" --I know the key event is supposed to return a number...",
" if commandID == 1 then os.queueEvent(\"key\", \"l\") end",
" if commandID == 2 then os.queueEvent(\"key\", \"n\") end",
" if commandID == 3 then os.queueEvent(\"key\", \"x\") end",
" commandID = nil",
" end",
" elseif (currentLocation == \"waypointSettings\" and ((event == \"mouse_click\" and param1 == 1)) or (event == \"monitor_touch\")) then",
" if y == 4 then os.queueEvent(\"key\", \"c\") end -- Create waypoint",
" if y == 5 then os.queueEvent(\"key\", \"d\") end -- Delete waypoint",
" if y == 6 then os.queueEvent(\"key\", \"r\") end -- Rename waypoint",
" if y == 7 then os.queueEvent(\"key\", \"o\") end -- Edit config",
" if y == 8 then os.queueEvent(\"key\", \"s\") end -- Set scale",
" if y == 9 then os.queueEvent(\"key\", \"h\") end -- Show help",
" if turtleMode then",
" if y == 10 then os.queueEvent(\"key\", \"t\") end -- Turtle controls",
" if y == 11 then os.queueEvent(\"key\", \"p\") end -- Send turtle to point",
" if y == 12 then os.queueEvent(\"key\", \"i\") end -- Inspect waypoint",
" if y == 13 then os.queueEvent(\"key\", \"x\") end -- Exit",
" else",
" if y == 10 then os.queueEvent(\"key\", \"i\") end -- Inspect waypoint",
" if y == 11 then os.queueEvent(\"key\", \"x\") end -- Exit",
" end",
" end",
" end",
"end",
"local function drawAnimations()",
" local spinwheel = {\"/\",\"-\",\"\\\\\",\"|\"}",
" while true do",
" if currentLocation == \"waypointSettings\" then",
" sleep(0.1)",
" repeat",
" term.setTextColor(colors.white)",
" drawMovingLine(3, 12, 0, 2)",
" until currentLocation ~= \"waypointSettings\"",
" end",
" if currentLocation == \"renderMap\" then",
" for a = 1, #spinwheel do",
" if currentLocation ~= \"renderMap\" then break end",
" event, status = os.pullEvent(\"gpsRequest\")",
" if currentLocation == \"renderMap\" then",
" if colormode then",
" if turtleMode then term.setBackgroundColor(colors.lightGray) end",
" if status == true then",
" term.setTextColor(colors.green)",
" else",
" term.setTextColor(colors.orange)",
" end",
" else",
" if grayAllowed then",
" if turtleMode then term.setBackgroundColor(colors.lightGray) end",
" if status == true then",
" term.setTextColor(colors.lightGray)",
" else",
" term.setTextColor(colors.gray)",
" end",
" else",
" if status == true then",
" term.setTextColor(colors.black)",
" else",
" term.setTextColor(colors.white)",
" end",
" end",
" end",
" term.setCursorPos(scr_x,1)",
" setDefaultBackgroundColor()",
" write(spinwheel[a])",
" if currentlyConnected then",
" term.setCursorPos(1,1)",
" term.setTextColor(colors.white)",
" write(\"X=\"..math.floor(posX)..\" Y=\"..math.floor(posY)..\" Z=\"..math.floor(posZ))",
" end",
" else",
" break",
" end",
" end",
" end",
" sleep(0)",
" end",
"end",
"local function waitForResize()",
" while true do",
" scr_x, scr_y = term.getSize()",
" event = os.pullEvent()",
" if event == \"monitor_resize\" or event == \"term_resize\" and displayStuffs == true then",
" scr_x, scr_y = term.getSize()",
" if scr_x > 16 or scr_y > 10 then --Determines if Map is being ran on a single monitor block.",
" monitorMode = false",
" else",
" monitorMode = true",
" end",
" mon = peripheral.find(\"monitor\")",
" if mon then",
" if monitorTextScale ~= 0.5 then",
" mon.setTextScale(0.5)",
" else",
" mon.setTextScale(1)",
" end",
" if not monitorMode then",
" mon.setTextScale(monitorTextScale)",
" else",
" mon.setTextScale(0.5)",
" end",
" end",
" setDefaultColors()",
" term.clear()",
" defineMapBorders()",
" drawBorder()",
" clearMap()",
" renderCommands()",
" redrawMap = true",
" end",
" end",
"end",
"local function broadcastMapData()",
" local compType",
" if pocket then",
" compType = 1",
" elseif turtle then",
" compType = 2",
" else",
" compType = 3",
" end",
" while true do",
" if broadcastData then",
" local data = {",
" name = networkName,",
" x = posX,",
" y = posY,",
" z = posZ,",
" isFake = spoofMode,",
" comp = compType,",
" ver = mapVersion,",
" dirChar = playerChar,",
" }",
" local modem = peripheral.find(\"modem\")",
" if modem then",
" for a = 1, #mapProtocol do",
" modem.open(mapProtocol[a])",
" modem.transmit(mapProtocol[a],mapProtocol[a],data)",
" end",
" end",
" end",
" sleep(0)",
" end",
"end",
"local function _rawListenForMapData() --Thanks, Bomb Bloke!",
" otherWaypoints = {}",
" while true do",
" local scr_x, scr_y = term.getSize()",
" local modem = peripheral.find(\"modem\")",
" if modem then",
" for a = 1, #mapProtocol do",
" modem.open(mapProtocol[a])",
" end",
" end",
" local event, side, sendChan, repChan, data, distance = os.pullEvent(\"modem_message\")",
" if (type(data) == \"table\") then",
" if (type(data.x) == \"number\") and (type(data.y) == \"number\") and (type(data.z) == \"number\") and (type(data.name) == \"string\") and (type(data.dirChar) == \"string\") then",
" otherWaypoints[data.name] = {data.x,data.y,data.z,colors.red,data.dirChar}",
" if data.comp then",
" table.insert(otherWaypoints[data.name],data.comp)",
" else",
" table.insert(otherWaypoints[data.name],-1)",
" end",
" elseif #data == 2 then",
" if (type(data[1]) == \"string\") and (type(data[2]) == \"string\") then",
" finalMessage = string.sub(\"<\"..data[1]..\"> \"..data[2],1,(scr_x*2)-1)",
" printOutput(finalMessage)",
" end",
" end",
" end",
" end",
"end",
"local function listenForMapData()",
" netWayPoints = {}",
" while true do",
" parallel.waitForAny(function() sleep(0.3) end, _rawListenForMapData)",
" local seppoint = seperateMethods(otherWaypoints)",
" local oldNetWayPoints = newWayPoints",
" netWayPoints = {}",
" for a = 1, #seppoint do",
" table.insert(netWayPoints,{seppoint[a][1],table.unpack(seppoint[a][2])})",
" end",
" local file = fs.open(mapNetworkWaypointsFile,\"w\")",
" file.write(textutils.serialize(netWayPoints))",
" file.close()",
" getConfig()",
" if (oldNetWayPoints ~= netWayPoints) and displayStuffs then",
" hadCleared = true",
" redrawMap = true",
" end",
" end",
"end",
"getConfig()",
"local mon = peripheral.find(\"monitor\")",
"if mon then",
" if not monitorMode then",
" mon.setTextScale(monitorTextScale)",
" else",
" mon.setTextScale(0.5)",
" end",
"end",
"if spoofMode then --Used if spoofMode == true, if not then these are set in the event that it is later set true.",
" if not fakeDir then",
" print(\"Spoof mode is activated.\")",
" print(\"Enter current X:\")",
" repeat",
" fakeX = tonumber(read())",
" until fakeX",
" print(\"Enter current Y:\")",
" repeat",
" fakeY = tonumber(read())",
" until fakeY",
" print(\"Enter current Z:\")",
" repeat",
" fakeZ = tonumber(read())",
" until fakeZ",
" print(\"Enter direction ('f' in F3 mode):\")",
" repeat",
" fakeDir = tonumber(read())",
" until fakeDir",
" refreshOtherConfig()",
" end",
"else",
" fakeX = 0",
" fakeY = 66",
" fakeZ = 0",
" fakeDir = 0 --Look at variable 'f' in DEBUG mode in minecraft. (F3)",
"end",
"mapturt = { -- I redefine the turtle moving functions to simplify things.",
" [\"forward\"] = function() turtle.forward() fakeX=fakeX-(math.sin(90*fakeDir)) fakeZ=fakeZ+(math.cos(90*fakeDir)) refreshOtherConfig() end,",
" [\"back\"] = function() turtle.back() fakeX=fakeX+(math.sin(90*fakeDir)) fakeZ=fakeZ-(math.cos(90*fakeDir)) refreshOtherConfig() end,",
" [\"up\"] = function() turtle.up() fakeY=fakeY+1 refreshOtherConfig() end,",
" [\"down\"] = function() turtle.down() fakeY=fakeY-1 refreshOtherConfig() end,",
" [\"turnLeft\"] = function() turtle.turnLeft() fakeDir=rollOver(fakeDir-1,4) refreshOtherConfig() end,",
" [\"turnRight\"] = function() turtle.turnRight() fakeDir=rollOver(fakeDir+1,4) refreshOtherConfig() end,",
"}",
"--[[The following...huge...tables are the title screens for advanced, grayscale, and monochrome computers.",
"In order to edit these, you need to somehow convert it back to the default paint format, then use oeed's Sketch--]]",
"mapTitleScreen_adv = {{8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,},{8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,},{8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,},{8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,},{8,8,8,32768,32768,32768,32768,32768,32768,32768,32768,32768,32768,32768,32768,32768,32768,32768,32768,32768,32768,32768,32768,32768,32768,32768,32768,32768,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,},{8,8,8,32768,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,32768,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,},{8,8,8,32768,16,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,16,32768,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,},{8,8,8,32768,16,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,16,32768,32768,32768,32768,32768,32768,32768,32768,32768,32768,8,8,8,8,8,8,8,8,8,8,8,8,8,8,},{8,8,8,32768,16,128,128,32768,1,1,32768,1,1,128,128,32768,1,1,128,32768,1,1,1,128,128,128,16,32768,256,256,256,256,256,256,256,256,32768,8,8,8,8,8,8,8,8,8,8,8,8,8,8,},{8,8,8,32768,16,128,32768,1,128,32768,1,128,32768,1,32768,1,128,32768,1,32768,1,128,32768,1,128,128,16,32768,32768,32768,32768,32768,32768,32768,32768,256,32768,8,8,8,8,8,8,8,8,8,8,8,8,8,8,},{8,8,8,32768,16,128,32768,1,128,32768,1,128,32768,1,32768,1,1,1,1,32768,1,1,1,1,128,128,16,32768,32768,32768,32768,32768,32768,32768,32768,256,32768,8,8,8,8,8,8,8,8,8,8,8,8,8,8,},{8,8,8,32768,16,128,32768,1,128,32768,1,128,32768,1,32768,1,128,32768,1,32768,1,128,128,128,128,128,16,32768,32768,1,1,1,32768,32768,32768,256,32768,8,8,8,8,8,8,8,8,8,8,8,8,8,8,},{8,8,8,32768,16,128,32768,1,128,128,128,128,32768,1,32768,1,128,32768,1,32768,1,128,128,128,128,128,16,32768,32768,1,32768,32768,1,32768,32768,256,32768,8,8,8,8,8,8,8,8,8,8,8,8,8,8,},{8,8,8,32768,16,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,16,32768,32768,1,1,1,1,32768,32768,256,32768,8,8,8,8,8,8,8,8,8,8,8,8,8,8,},{8,8,8,32768,16,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,16,32768,32768,1,32768,32768,32768,32768,32768,256,32768,8,8,8,8,8,8,8,8,8,8,8,8,8,8,},{8192,8192,8192,32768,16,256,256,256,256,128,256,256,256,128,128,128,256,256,128,128,128,256,256,256,256,256,16,32768,32768,1,32768,32768,32768,32768,32768,256,32768,8192,8192,8192,8192,8192,8192,8192,8192,8192,8192,8192,8192,8192,8192,},{32,32,32,32768,16,1,1,1,1,128,1,1,1,128,1,1,128,1,128,1,1,128,1,1,1,1,16,32768,32768,32768,32768,32768,32768,32768,32768,256,32768,32,32,32,32,32,32,32,32,32,32,32,32,32,32,},{32,32,32,32768,16,1,1,1,1,128,1,1,1,128,1,1,128,1,128,1,1,128,1,1,1,1,16,32768,32768,32768,32768,32768,32768,32768,32768,256,32768,32,32,32,32,32,32,32,32,32,32,32,32,32,32,},{32,32,32,32768,16,1,1,1,1,128,128,128,1,128,128,128,1,1,128,128,128,1,1,1,1,1,16,32768,1,1,1,1,1,1,32768,256,32768,32,32,32,32,32,32,32,32,32,32,32,32,32,32,},{32,32,32,32768,16,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,16,32768,1,1,1,1,1,1,32768,256,32768,32,32,32,32,32,32,1,1,1,1,1,1,1,1,},}",
"mapTitleScreen_norm = {{1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,},{1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,},{1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,},{1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,},{1,1,1,32768,32768,32768,32768,32768,32768,32768,32768,32768,32768,32768,32768,32768,32768,32768,32768,32768,32768,32768,32768,32768,32768,32768,32768,32768,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,},{1,1,1,32768,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,32768,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,},{1,1,1,32768,1,32768,32768,32768,32768,32768,32768,32768,32768,32768,32768,32768,32768,32768,32768,32768,32768,32768,32768,32768,32768,32768,1,32768,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,},{1,1,1,32768,1,32768,32768,32768,32768,32768,32768,32768,32768,32768,32768,32768,32768,32768,32768,32768,32768,32768,32768,32768,32768,32768,1,32768,32768,32768,32768,32768,32768,32768,32768,32768,32768,1,1,1,1,1,1,1,1,1,1,1,1,1,1,},{1,1,1,32768,1,32768,32768,32768,1,1,32768,1,1,32768,32768,32768,1,1,32768,32768,1,1,1,32768,32768,32768,1,32768,1,1,1,1,1,1,1,1,32768,1,1,1,1,1,1,1,1,1,1,1,1,1,1,},{1,1,1,32768,1,32768,32768,1,32768,32768,1,32768,32768,1,32768,1,32768,32768,1,32768,1,32768,32768,1,32768,32768,1,32768,32768,32768,32768,32768,32768,32768,32768,1,32768,1,1,1,1,1,1,1,1,1,1,1,1,1,1,},{1,1,1,32768,1,32768,32768,1,32768,32768,1,32768,32768,1,32768,1,1,1,1,32768,1,1,1,1,32768,32768,1,32768,32768,32768,32768,32768,32768,32768,32768,1,32768,1,1,1,1,1,1,1,1,1,1,1,1,1,1,},{1,1,1,32768,1,32768,32768,1,32768,32768,1,32768,32768,1,32768,1,32768,32768,1,32768,1,32768,32768,32768,32768,32768,1,32768,32768,1,1,1,32768,32768,32768,1,32768,1,1,1,1,1,1,1,1,1,1,1,1,1,1,},{1,1,1,32768,1,32768,32768,1,32768,32768,32768,32768,32768,1,32768,1,32768,32768,1,32768,1,32768,32768,32768,32768,32768,1,32768,32768,1,32768,32768,1,32768,32768,1,32768,1,1,1,1,1,1,1,1,1,1,1,1,1,1,},{1,1,1,32768,1,32768,32768,32768,32768,32768,32768,32768,32768,32768,32768,32768,32768,32768,32768,32768,32768,32768,32768,32768,32768,32768,1,32768,32768,1,1,1,1,32768,32768,1,32768,1,1,1,1,1,1,1,1,1,1,1,1,1,1,},{1,1,1,32768,1,32768,32768,32768,32768,32768,32768,32768,32768,32768,32768,32768,32768,32768,32768,32768,32768,32768,32768,32768,32768,32768,1,32768,32768,1,32768,32768,32768,32768,32768,1,32768,1,1,1,1,1,1,1,1,1,1,1,1,1,1,},{32768,32768,32768,32768,1,1,1,1,1,32768,1,1,1,32768,32768,32768,1,1,32768,32768,32768,1,1,1,1,1,1,32768,32768,1,32768,32768,32768,32768,32768,1,32768,32768,32768,32768,32768,32768,32768,32768,32768,32768,32768,32768,32768,32768,32768,},{32768,32768,32768,32768,1,1,1,1,1,32768,1,1,1,32768,1,1,32768,1,32768,1,1,32768,1,1,1,1,1,32768,32768,32768,32768,32768,32768,32768,32768,1,32768,32768,32768,32768,32768,32768,32768,32768,32768,32768,32768,32768,32768,32768,32768,},{32768,32768,32768,32768,1,1,1,1,1,32768,1,1,1,32768,1,1,32768,1,32768,1,1,32768,1,1,1,1,1,32768,32768,32768,32768,32768,32768,32768,32768,1,32768,32768,32768,32768,32768,32768,32768,32768,32768,32768,32768,32768,32768,32768,32768,},{32768,32768,32768,32768,1,1,1,1,1,32768,32768,32768,1,32768,32768,32768,1,1,32768,32768,32768,1,1,1,1,1,1,32768,1,1,1,1,1,1,1,1,32768,32768,32768,32768,32768,32768,32768,32768,32768,32768,32768,32768,32768,32768,32768,},{32768,32768,32768,32768,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,32768,1,1,1,1,1,1,1,1,32768,32768,32768,32768,32768,32768,32768,32768,32768,32768,32768,32768,32768,32768,32768,},}",
"mapTitleScreen_gray = {{1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,},{1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,},{1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,},{1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,},{1,1,1,32768,32768,32768,32768,32768,32768,32768,32768,32768,32768,32768,32768,32768,32768,32768,32768,32768,32768,32768,32768,32768,32768,32768,32768,32768,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,},{1,1,1,32768,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,32768,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,},{1,1,1,32768,1,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,1,32768,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,},{1,1,1,32768,1,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,1,32768,32768,32768,32768,32768,32768,32768,32768,32768,32768,1,1,1,1,1,1,1,1,1,1,1,1,1,1,},{1,1,1,32768,1,128,128,32768,1,1,32768,1,1,128,128,32768,1,1,128,32768,1,1,1,128,128,128,1,32768,256,256,256,256,256,256,256,256,32768,1,1,1,1,1,1,1,1,1,1,1,1,1,1,},{1,1,1,32768,1,128,32768,1,128,32768,1,128,32768,1,32768,1,128,32768,1,32768,1,128,32768,1,128,128,1,32768,32768,32768,32768,32768,32768,32768,32768,256,32768,1,1,1,1,1,1,1,1,1,1,1,1,1,1,},{1,1,1,32768,1,128,32768,1,128,32768,1,128,32768,1,32768,1,1,1,1,32768,1,1,1,1,128,128,1,32768,32768,32768,32768,32768,32768,32768,32768,256,32768,1,1,1,1,1,1,1,1,1,1,1,1,1,1,},{1,1,1,32768,1,128,32768,1,128,32768,1,128,32768,1,32768,1,128,32768,1,32768,1,128,128,128,128,128,1,32768,32768,1,1,1,32768,32768,32768,256,32768,1,1,1,1,1,1,1,1,1,1,1,1,1,1,},{1,1,1,32768,1,128,32768,1,128,128,128,128,32768,1,32768,1,128,32768,1,32768,1,128,128,128,128,128,1,32768,32768,1,32768,32768,1,32768,32768,256,32768,1,1,1,1,1,1,1,1,1,1,1,1,1,1,},{1,1,1,32768,1,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,1,32768,32768,1,1,1,1,32768,32768,256,32768,1,1,1,1,1,1,1,1,1,1,1,1,1,1,},{1,1,1,32768,1,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,1,32768,32768,1,32768,32768,32768,32768,32768,256,32768,1,1,1,1,1,1,1,1,1,1,1,1,1,1,},{128,128,128,32768,1,256,256,256,256,128,256,256,256,128,128,128,256,256,128,128,128,256,256,256,256,256,1,32768,32768,1,32768,32768,32768,32768,32768,256,32768,128,128,128,128,128,128,128,128,128,128,128,128,128,128,},{256,256,256,32768,1,1,1,1,1,128,1,1,1,128,1,1,128,1,128,1,1,128,1,1,1,1,1,32768,32768,32768,32768,32768,32768,32768,32768,256,32768,256,256,256,256,256,256,256,256,256,256,256,256,256,256,},{256,256,256,32768,1,1,1,1,1,128,1,1,1,128,1,1,128,1,128,1,1,128,1,1,1,1,1,32768,32768,32768,32768,32768,32768,32768,32768,256,32768,256,256,256,256,256,256,256,256,256,256,256,256,256,256,},{256,256,256,32768,1,1,1,1,1,128,128,128,1,128,128,128,1,1,128,128,128,1,1,1,1,1,1,32768,1,1,1,1,1,1,1,256,32768,256,256,256,256,256,256,256,256,256,256,256,256,256,256,},{256,256,256,32768,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,32768,1,1,1,1,1,1,1,256,32768,256,256,256,256,256,256,256,256,256,256,1,1,1,1,},}",
"defineMapBorders() --why do I have a function for this again...? For the screen resizing!",
"if displayTitle then",
" displayTitleScreen() --New title screens for norm/adv/gray computers in 1.3.4!",
"end",
"if autoUpdate then",
" write(\"Automagically updating Map...\") --Yes I know I misspelled that, that was on purpose.",
" updateMapProgram()",
" print(\"up to date!\")",
"end",
"flashScreen(1)",
"local parallelFunctions = { --Look, I wanted to simplify it...",
" renderMap,",
" keyPress,",
" captureMouseInput,",
" waitForResize,",
" drawAnimations,",
" listenForMapData,",
" broadcastMapData,",
"}",
"parallel.waitForAny(table.unpack(parallelFunctions))",
"end --This end is to close the runMapProgramAlready() function, so don't remove it.",
"function handleMapErrorMessage(errorMsg)",
" local errorMessage = errorMsg",
" local interjects = {",
" \"Oh nose!\",",
" \"Golly gee!\",",
" \"Eh, shit.\",",
" \"Holy Spaghetti and Meatballs, Batman!\",",
" \"Holy Rusted Metal, Batman!\",",
" \"Jiminy!\",",
" \"Leaping leptons!\",",
" \"Cripes!\",",
" \"Khaaaaaaannnnn!!\",",
" \"GURU MEDITATION\",",
" \"It appears that\",",
" \"Exclamation!\",",
" \"Holy Hamburger, Batman!\",",
" \"Holy Priceless Collection of Etruscan Snoods, Batman!\",",
" \"Holy Uncanny Photographic Mental Processes, Batman!\",",
" \"Aw shucks!\",",
" \"Holy Contributing to the Delinquency of Minors, Batman!\",",
" \"Holy Remote Control Robot, Batman!\",",
" \"Holy Euphemism!\",",
" \"Holy Hardest Metal In The World, Batman!\",",
" \"Holy Astringent Plum-like Fruit, Batman!\",",
" \"Holy Greetings Cards, Batman!\",",
" \"Holy One Track Bat Computer Mind, Batman!\",",
" \"Sweet Zombie Jesus!\",",
" \"Holy Batshit, Robin!\",",
" \"Holy Mongolian Clusterfuck!\",",
" \"Holy jumping mother o'God in a side-car with chocolate jimmies and a lobster bib!\",",
" \"string.rep(\\\"NEIN \\\",1000)\",",
" \"Oh, how sad.\",",
" \"NYEH HEH HEH!!!!\", --This error message fills you with DETERMINATION.",
" \"One of us messed up.\",",
" \"Holy balls!\",",
" \"ASS!\",",
" \"You piece of shit!\",",
" \"Damn it, Jim!\",",
" \"Ohhh nooo...\",",
" \"Funny splash text!\",",
" }",
" if colormode then",
" table.insert(interjects,\"It's so red!\")",
" else",
" if grayAllowed then",
" table.insert(interjects,\"It's so gray!\")",
" else",
" table.insert(interjects,\"It's so white!\")",
" end",
" end",
" local interjection = interjects[math.random(1, #interjects)]",
" local message = {",
" interjection,",
" \"Map v\" .. mapVersion .. \" has gotten\",",
" \"an error:\",",
" \"\",",
" tostring(errorMessage),",
" }",
" if colormode then",
" term.setBackgroundColor(colors.red)",
" else",
" if grayAllowed then",
" term.setBackgroundColor(colors.gray)",
" else",
" term.setBackgroundColor(colors.white)",
" end",
" end",
" term.clear()",
" scr_x, scr_y = term.getSize()",
" term.setCursorPos(1,1)",
" for y = 1, 2 do",
" for x = 1, scr_x do",
" if x % 2 == 0 then",
" if colormode then",
" term.setBackgroundColor(colors.black)",
" term.setTextColor(colors.lightGray)",
" else",
" if grayAllowed then",
" term.setBackgroundColor(colors.black)",
" term.setTextColor(colors.lightGray)",
" else",
" term.setBackgroundColor(colors.black)",
" term.setTextColor(colors.white)",
" end",
" end",
" write(\"x\")",
" else",
" if colormode then",
" term.setBackgroundColor(colors.white)",
" term.setTextColor(colors.orange)",
" else",
" if grayAllowed then",
" term.setBackgroundColor(colors.white)",
" term.setTextColor(colors.gray)",
" else",
" term.setBackgroundColor(colors.white)",
" term.setTextColor(colors.black)",
" end",
" end",
" write(\"X\")",
" end",
" end",
" term.setCursorPos(1,scr_y)",
" end",
" midPoint = {",
" scr_x / 2,",
" scr_y / 2,",
" }",
" local yoffset = 0",
" for a = 1, #message do",
" term.setCursorPos(midPoint[1]-math.floor(#message[a]/2)+1,a+3+yoffset)",
" if a == 5 then",
" if colormode then",
" term.setBackgroundColor(colors.gray)",
" term.setTextColor(colors.white)",
" else",
" if grayAllowed then",
" term.setBackgroundColor(colors.black)",
" term.setTextColor(colors.white)",
" else",
" term.setBackgroundColor(colors.black)",
" term.setTextColor(colors.white)",
" end",
" end",
" else",
" if colormode then",
" term.setBackgroundColor(colors.red)",
" term.setTextColor(colors.white)",
" else",
" if grayAllowed then",
" term.setBackgroundColor(colors.lightGray)",
" term.setTextColor(colors.black)",
" else",
" term.setBackgroundColor(colors.white)",
" term.setTextColor(colors.black)",
" end",
" end",
" end",
" if #message[a] > scr_x then",
" for b = 1, math.ceil(#message[a]/scr_x) do",
" local curPosX, curPosY = term.getCursorPos()",
" local subString = string.sub(message[a],((b-1)*scr_x)+1,(b*scr_x))",
" if #subString < scr_x then",
" term.setCursorPos(midPoint[1]-math.ceil(#string.sub(message[a], scr_x)/2),a+2+yoffset)",
" else",
" term.setCursorPos(1,a+2+yoffset+(b-1))",
" end",
" print(subString)",
" if b ~= math.ceil(#message[a]/scr_x) then",
" yoffset = yoffset + 1",
" end",
" end",
" else",
" print(message[a])",
" end",
" end",
" if colormode then",
" term.setBackgroundColor(colors.yellow)",
" term.setTextColor(colors.black)",
" else",
" if grayAllowed then",
" term.setBackgroundColor(colors.lightGray)",
" term.setTextColor(colors.black)",
" else",
" term.setBackgroundColor(colors.white)",
" term.setTextColor(colors.black)",
" end",
" end",
" local msg = \" E(x)it, or (R)estart? \"",
" term.setCursorPos(math.ceil(midPoint[1]-(#msg/2)),scr_y-2)",
" print(msg)",
" local event, key",
" repeat",
" sleep(0.1) --To prevent premature keypresses.",
" event, key = os.pullEvent(\"char\") --We don't need any key output other than letters.",
" key = string.lower(key) --In case shift+key returns a capital key.",
" until string.find(\"xr\", key)",
" local message = nil",
" if key == \"x\" then",
" return false",
" elseif key == \"r\" then",
" return true",
" else",
" return false",
" end",
" error(\"How did you get here??\")",
"end",
"if nothing then return end",
"while true do",
" local status, error = pcall(runMapProgramAlready) --Finally, good error handling.",
" if status == false then",
" local outcome = handleMapErrorMessage(error)",
" if outcome == false then",
" break",
" end",
" else",
" break",
" end",
"end",
"term.setTextColor(colors.white)",
"term.setBackgroundColor(colors.black)",
"term.clear()",
"term.setCursorPos(1,1)",
"print(\"Thanks for using Map v\" .. mapVersion .. \"!\")",
"print(\"(code: \" .. pastebinIDList[mapRelease] .. \")\")",
"if math.random(1,64)==64 then print(\"May you live in interesting times!\") end",
"sleep(0)",
},
[ "/game/data/sprites/stickdude/walkshoot1.nft" ] = {
"ž0f f0„e†",
"‹Ÿe“",
"  f0•  fe‚",
"˜‰",
"•  f0•",
},
[ "/game/cc2d.lua" ] = {
"-- pastebin run W5ZkVYSi LDDestroier CC2D",
"",
"local deriveControls = function(keyList)",
" return {",
" up = keyList[keys.up],",
" down = keyList[keys.down],",
" left = keyList[keys.left],",
" right = keyList[keys.right],",
" jump = keyList[keys.x],",
" slide = keyList[keys.c],",
" shoot = keyList[keys.z]",
" }",
"end",
"",
"local config = {}",
"config.downJumpSlide = true",
"",
"local game = {}",
"game.path = fs.combine(fs.getDir(shell.getRunningProgram()),\"data\")",
"game.apiPath = fs.combine(game.path, \"api\")",
"game.spritePath = fs.combine(game.path, \"sprites\")",
"game.mapPath = fs.combine(game.path, \"maps\")",
"game.imagePath = fs.combine(game.path, \"image\")",
"",
"local scr_x, scr_y = term.getSize()",
"local mapname = \"testmap\"",
"",
"local scrollX = 0",
"local scrollY = 0",
"local killY = 100",
"",
"local keysDown = {}",
"",
"local tsv = function(visible)",
" if term.current().setVisible then",
" --term.current().setVisible(visible)",
" end",
"end",
"",
"local getAPI = function(apiName, apiPath, apiURL, doDoFile)",
" apiPath = fs.combine(game.apiPath, apiPath)",
" if not fs.exists(apiPath) then",
" write(\"Getting \" .. apiName .. \"...\")",
" local prog = http.get(apiURL)",
" if prog then",
" print(\"success!\")",
" local file = fs.open(apiPath, \"w\")",
" file.write(prog.readAll())",
" file.close()",
" else",
" error(\"fail!\")",
" end",
" end",
" if doDoFile then",
" _ENV[fs.getName(apiPath)] = dofile(apiPath)",
" else",
" os.loadAPI(apiPath)",
" end",
"end",
"",
"getAPI(\"NFT Extra\", \"nfte\", \"https://github.com/LDDestroier/NFT-Extra/raw/master/nfte\", false)",
"",
"-- load sprites from sprite folder",
"-- sprites are separated into \"sets\", but the only one here is \"megaman\" so whatever",
"",
"local sprites, maps = {}, {}",
"for k, set in pairs(fs.list(game.spritePath)) do",
" sprites[set] = {}",
" for num, name in pairs(fs.list(fs.combine(game.spritePath, set))) do",
" sprites[set][name:gsub(\".nft\", \"\")] = nfte.loadImage(fs.combine(game.spritePath, set .. \"/\" .. name))",
" print(\"Loaded sprite \" .. name:gsub(\".nft\",\"\"))",
" end",
"end",
"for num, name in pairs(fs.list(game.mapPath)) do",
" maps[name:gsub(\".nft\", \"\")] = nfte.loadImage(fs.combine(game.mapPath, name))",
" print(\"Loaded map \" .. name:gsub(\".nft\",\"\"))",
"end",
"",
"local projectiles = {}",
"local players = {}",
"",
"local newPlayer = function(name, spriteset, x, y)",
" return {",
" name = name, -- player name",
" spriteset = spriteset, -- set of sprites to use",
" sprite = \"stand\", -- current sprite",
" direction = 1, -- 1 is right, -1 is left",
" xsize = 3, -- hitbox x size",
" ysize = 5, -- hitbox y size",
" x = x, -- x position",
" y = y, -- y position",
" xadj = 0, -- adjust x for good looks",
" yadj = 0, -- adjust y for good looks",
" xvel = 0, -- x velocity",
" yvel = 0, -- y velocity",
" maxVelocity = 8, -- highest posible speed in any direction",
" jumpHeight = 2, -- height of jump",
" jumpAssist = 0.5, -- assists jump while in air",
" moveSpeed = 2, -- speed of walking",
" gravity = 0.75, -- force of gravity",
" slideSpeed = 4, -- speed of sliding",
" grounded = false, -- is on solid ground",
" shots = 0, -- how many shots onscreen",
" maxShots = 5, -- maximum shots onscreen",
" lemonSpeed = 3, -- speed of megabuster shots",
" chargeLevel = 0, -- current charged buster level",
" cycle = { -- used for animation cycles",
" run = 0, -- used for run sprite",
" shoot = 0, -- determines duration of shoot sprite",
" shootHold = 0, -- forces user to release then push shoot",
" stand = 0, -- used for high-octane eye blinking action",
" slide = 0, -- used to limit slide length",
" slideHold = 0, -- used to prevent supersliding",
" jump = 0, -- used to prevent auto-bunnyhopping",
" shootCharge = 0, -- records how charged your megabuster is",
" ouch = 0, -- records hitstun",
" iddqd = 0 -- records invincibility frames",
" },",
" chargeDiscolor = { -- swaps colors during buster charging",
" [0] = {{}},",
" [1] = { -- charge level one",
" {",
" [\"b\"] = \"a\"",
" },",
" {",
" [\"b\"] = \"b\"",
" }",
" },",
" [2] = { -- woAH charge level two",
" {",
" --[\"f\"] = \"b\",",
" [\"b\"] = \"3\",",
" [\"3\"] = \"f\"",
" },",
" {",
" --[\"f\"] = \"3\",",
" [\"3\"] = \"b\",",
" [\"b\"] = \"f\"",
" },",
" {",
" --[\"f\"] = \"3\",",
" [\"3\"] = \"b\",",
" [\"b\"] = \"8\"",
" }",
" }",
" },",
" control = { -- inputs",
" up = false, -- move up ladders",
" down = false, -- move down ladders, or slide",
" left = false, -- point and walk left",
" right = false, -- point and walk right",
" jump = false, -- jump, or slide",
" shoot = false -- fire your weapon",
" }",
" }",
"end",
"",
"you = 1",
"players[1] = newPlayer(\"LDD\", \"stickdude\", 40, 8)",
"",
"-- main colision function",
"local isSolid = function(x, y)",
" x = math.floor(x)",
" y = math.floor(y)",
" if (not maps[mapname][1][y]) or (x < 1) then",
" return false",
" else",
" if (maps[mapname][1][y]:sub(x,x) == \" \" or",
" maps[mapname][1][y]:sub(x,x) == \"\") and",
" (maps[mapname][3][y]:sub(x,x) == \" \" or",
" maps[mapname][3][y]:sub(x,x) == \"\") then",
" return false",
" else",
" return true",
" end",
" end",
"end",
"",
"local isPlayerTouchingSolid = function(player, xmod, ymod, ycutoff)",
" for y = player.y + (ycutoff or 0), player.ysize + player.y - 1 do",
" for x = player.x, player.xsize + player.x - 1 do",
" if isSolid(x + (xmod or 0), y + (ymod or 0)) then",
" return \"map\"",
" end",
" -- player/player collision doesn't work, alas",
" for num, p in pairs(players) do",
" if player ~= p then",
" if x >= p.x and y <= (p.xsize + p.x - 1) then",
" if y >= p.y and y <= (p.ysize + p.y - 1) then",
" --return \"player\"",
" end",
" end",
" end",
" end",
" end",
" end",
" return false",
"end",
"",
"local movePlayer = function(player, x, y)",
" i = player.yvel / math.abs(player.yvel)",
" for y = 1, math.abs(player.yvel) do",
" if isPlayerTouchingSolid(player, 0, -i, (player.cycle.slide > 0 and 2 or 0)) then",
" if player.yvel < 0 then",
" player.grounded = true",
" end",
" player.yvel = 0",
" break",
" else",
" player.y = player.y - i",
" player.grounded = false",
" end",
" end",
" i = player.xvel / math.abs(player.xvel)",
" for x = 1, math.abs(player.xvel) do",
" if isPlayerTouchingSolid(player, i, 0, (player.cycle.slide > 0 and 2 or 0)) then",
" if player.grounded and not isPlayerTouchingSolid(player, i, -1) then -- upward slope detection",
" player.y = player.y - 1",
" player.x = player.x + i",
" else",
" player.xvel = 0",
" break",
" end",
" else",
" if player.grounded and (isPlayerTouchingSolid(player, i, 2) and not isPlayerTouchingSolid(player, i, 1)) then -- downward slope detection",
" player.y = player.y + 1",
" end",
" player.x = player.x + i",
" end",
" end",
"end",
"",
"-- types of projectiles",
"",
"local bullet = {",
" lemon = {",
" damage = 1,",
" element = \"neutral\",",
" sprites = {",
" sprites[\"megaman\"][\"buster1\"]",
" },",
" },",
" lemon2 = {",
" damage = 1,",
" element = \"neutral\",",
" sprites = {",
" sprites[\"megaman\"][\"buster2-1\"],",
" sprites[\"megaman\"][\"buster2-2\"]",
" }",
" },",
" lemon3 = {",
" damage = 4,",
" element = \"neutral\",",
" sprites = {",
" sprites[\"megaman\"][\"buster3-1\"],",
" sprites[\"megaman\"][\"buster3-2\"],",
" sprites[\"megaman\"][\"buster3-3\"],",
" sprites[\"megaman\"][\"buster3-4\"],",
" }",
" }",
"}",
"",
"local spawnProjectile = function(boolit, owner, x, y, xvel, yvel)",
" projectiles[#projectiles+1] = {",
" owner = owner,",
" bullet = boolit,",
" x = x,",
" y = y,",
" xvel = xvel,",
" yvel = yvel,",
" direction = xvel / math.abs(xvel),",
" life = 48,",
" cycle = 0,",
" phaze = false,",
" }",
"end",
"",
"-- determines what sprite a player uses",
"local determineSprite = function(player)",
" local output",
" player.xadj = 0",
" player.yadj = 0",
" if player.grounded then",
" if player.cycle.slide > 0 then",
" player.cycle.slide = math.max(player.cycle.slide - 1, isPlayerTouchingSolid(player, 0, 0, 0) and 1 or 0)",
" output = \"slide\"",
" else",
" if player.xvel == 0 then",
" player.cycle.run = -1",
" player.cycle.stand = (player.cycle.stand + 1) % 40",
" if player.cycle.shoot > 0 then",
" output = \"shoot\"",
" if player.direction == -1 then",
" player.xadj = -1",
" end",
" else",
" output = player.cycle.stand == 39 and \"stand2\" or \"stand1\"",
" end",
" else",
" if player.cycle.run == -1 and player.cycle.shoot == 0 then",
" player.cycle.run = 0",
" output = \"walk0\"",
" else",
" player.cycle.run = (player.cycle.run + 0.35) % 4",
" if player.cycle.shoot > 0 then",
" output = \"walkshoot\" .. (math.floor(player.cycle.run) + 1)",
" else",
" output = \"walk\" .. (math.floor(player.cycle.run) + 1)",
" end",
" end",
" end",
" end",
" else",
" player.cycle.slide = isPlayerTouchingSolid(player, 0, 0, 0) and 1 or 0",
" if player.cycle.shoot > 0 then",
" output = \"jumpshoot\"",
" if player.direction == -1 then",
" player.xadj = -1",
" end",
" else",
" output = \"jump\"",
" end",
" end",
" player.cycle.shoot = math.max(player.cycle.shoot - 1, 0)",
" return output",
"end",
"",
"local moveTick = function()",
" local i",
" for num, player in pairs(players) do",
"",
" -- falling",
" player.yvel = player.yvel - player.gravity",
"",
" -- jumping",
"",
" if player.control.jump then",
" if player.grounded then",
" if player.cycle.jump == 0 then",
" if not (player.control.down and player.cycle.slide == 0) and not isPlayerTouchingSolid(player, 0, -1, 0) then",
" player.yvel = player.jumpHeight",
" player.cycle.slide = 0",
" player.grounded = false",
" end",
" end",
" player.cycle.jump = 1",
" end",
" if player.yvel > 0 and not player.grounded then",
" player.yvel = player.yvel + player.jumpAssist",
" end",
" else",
" player.cycle.jump = 0",
" end",
" if player.cycle.slide == 0 then",
" if ((config.downJumpSlide and player.control.down and player.control.jump) or player.control.slide) then",
" if player.cycle.slideHold == 0 then",
" player.cycle.slide = 6",
" player.cycle.slideHold = 1",
" end",
" else",
" player.cycle.slideHold = 0",
" end",
" end",
"",
" -- walking",
" if player.control.right then",
" player.direction = 1",
" player.xvel = player.moveSpeed",
" elseif player.control.left then",
" player.direction = -1",
" player.xvel = -player.moveSpeed",
" else",
" player.xvel = 0",
" end",
" if player.cycle.slide > 0 then",
" player.xvel = player.direction * player.slideSpeed",
" end",
"",
" -- shooting",
"",
" if player.control.shoot then",
" if player.cycle.shootHold == 0 then",
" if player.shots < player.maxShots and player.cycle.slide == 0 then",
" spawnProjectile(",
" bullet.lemon,",
" player,",
" player.x + player.xsize * player.direction,",
" player.y,",
" player.lemonSpeed * player.direction,",
" 0",
" )",
" player.cycle.shoot = 5",
" player.shots = player.shots + 1",
" end",
" player.cycle.shootHold = 1",
" end",
" if player.cycle.shootHold == 1 then",
" player.cycle.shootCharge = player.cycle.shootCharge + 1",
" if player.cycle.shootCharge < 16 then",
" player.chargeLevel = 0",
" elseif player.cycle.shootCharge < 32 then",
" player.chargeLevel = 1",
" else",
" player.chargeLevel = 2",
" end",
" end",
" else",
" player.cycle.shootHold = 0",
" if player.shots < player.maxShots and player.cycle.slide == 0 then",
" if player.cycle.shootCharge > 16 then",
" if player.cycle.shootCharge >= 32 then",
" spawnProjectile(",
" bullet.lemon3,",
" player,",
" player.x + math.max(0, player.direction * (player.xsize - 1)),",
" player.y - 2,",
" player.lemonSpeed * player.direction,",
" 0",
" )",
" else",
" spawnProjectile(",
" bullet.lemon2,",
" player,",
" player.x + math.max(0, player.direction * player.xsize),",
" player.y - 1,",
" player.lemonSpeed * player.direction,",
" 0",
" )",
" end",
" player.shots = player.shots + 1",
" player.cycle.shoot = 5",
" end",
" end",
" player.cycle.shootCharge = 0",
" player.chargeLevel = 0",
" end",
"",
" -- movement",
" if player.xvel > 0 then",
" player.xvel = math.min(player.xvel, player.maxVelocity)",
" else",
" player.xvel = math.max(player.xvel, -player.maxVelocity)",
" end",
" if player.yvel > 0 then",
" player.yvel = math.min(player.yvel, player.maxVelocity)",
" else",
" player.yvel = math.max(player.yvel, -player.maxVelocity)",
" end",
"",
" if player.y > killY then",
" player.x = 40",
" player.y = -80",
" player.xvel = 0",
" end",
"",
" movePlayer(player, xvel, yvel)",
" if num == you then",
" scrollX = player.x - math.floor(scr_x / 2) + math.floor(player.xsize / 2)",
" scrollY = player.y - math.floor(scr_y / 2) + math.floor(player.ysize / 2)",
" end",
"",
" -- projectile management",
"",
" player.sprite = determineSprite(player)",
"",
" end",
" for i = #projectiles, 1, -1 do",
" projectiles[i].x = projectiles[i].x + projectiles[i].xvel",
" projectiles[i].y = projectiles[i].y + projectiles[i].yvel",
" projectiles[i].cycle = projectiles[i].cycle + 1",
" projectiles[i].life = projectiles[i].life - 1",
" if projectiles[i].life <= 0 then",
" projectiles[i].owner.shots = projectiles[i].owner.shots - 1",
" table.remove(projectiles, i)",
" end",
" end",
"end",
"",
"local render = function()",
" tsv(false)",
" term.clear()",
" nfte.drawImage(maps[mapname], -scrollX + 1, -scrollY + 1)",
" term.setCursorPos(1,1)",
" for num,player in pairs(players) do",
" print(\"(\" .. player.x .. \", \" .. player.y .. \")\")",
" if player.direction == -1 then",
" nfte.drawImageTransparent(",
" nfte.colorSwap(",
" nfte.flipX(",
" sprites[player.spriteset][player.sprite]",
" ),",
" player.chargeDiscolor[player.chargeLevel][",
" (math.floor(player.cycle.shootCharge / 2) % #player.chargeDiscolor[player.chargeLevel]) + 1",
" ]",
" ),",
" player.x - scrollX + player.xadj,",
" player.y - scrollY + player.yadj",
" )",
" else",
" nfte.drawImageTransparent(",
" nfte.colorSwap(",
" sprites[player.spriteset][player.sprite],",
" player.chargeDiscolor[player.chargeLevel][",
" (math.floor(player.cycle.shootCharge / 2) % #player.chargeDiscolor[player.chargeLevel]) + 1",
" ]",
" ),",
" player.x - scrollX,",
" player.y - scrollY",
" )",
" end",
" end",
" for num,p in pairs(projectiles) do",
" if p.direction == -1 then",
" nfte.drawImageTransparent(",
" nfte.flipX(p.bullet.sprites[(p.cycle % #p.bullet.sprites) + 1]),",
" p.x - scrollX,",
" p.y - scrollY",
" )",
" else",
" nfte.drawImageTransparent(",
" p.bullet.sprites[(p.cycle % #p.bullet.sprites) + 1],",
" p.x - scrollX,",
" p.y - scrollY",
" )",
" end",
" end",
" tsv(true)",
"end",
"",
"local getInput = function()",
" local evt",
" while true do",
" evt = {os.pullEvent()}",
" if evt[1] == \"key\" then",
" keysDown[evt[2]] = true",
" elseif evt[1] == \"key_up\" then",
" keysDown[evt[2]] = false",
" end",
" end",
"end",
"",
"local main = function()",
" while true do",
" players[you].control = deriveControls(keysDown)",
" moveTick()",
" render()",
" if keysDown[keys.q] then",
" return",
" end",
" sleep(0.05)",
" end",
"end",
"",
"parallel.waitForAny(getInput, main)",
"",
"term.setCursorPos(1, scr_y)",
"term.clearLine()",
},
[ "/game/data/sprites/megaman/walkshoot3.nft" ] = {
"  3fŸf3",
"  bf—b€f‚3œ",
"  b3•0b‡b0œfb‰bf‘",
"  bf03f0Žž3f‡f3”bˆŒ3f—",
"  bfŸf3Ÿ3bb3–fƒfb–3bƒ",
"bf‡b€f‹3b‹b3‚f‰3Œfb“ƒ",
"bƒ‚3‡  f3‚bƒfbŸ",
"  fb‚ƒƒƒ",
},
[ "/game/data/sprites/megaman/buster3-2.nft" ] = {
"  4fŸ",
"  0f‡40Ÿfƒ4f’  4fƒ0‹f4",
"4f—00€f4…  4f04†0€€€4‚f",
"0f•0€  f4Š00€€€€€f4•",
"4‚04fŠ  4fŸf4‹00€€4˜",
"  f0‚4Ÿ0fƒf4‡  f4ƒ",
},
[ "/game/data/sprites/megaman/walkshoot2.nft" ] = {
"  bf‡ƒf3›„",
"  3f—bb€03fŒfb…",
"  3f‡f3–0b•0€fŠf0•3fb—ƒf3",
"  f3Šbf›3f‰f0Œ†3ŽbŠ",
"  fb‹bfˆƒ3”f3‡",
"  fb‚3f†f3•…",
"  bf—b€f",
"  fbƒƒ",
},
[ "/game/data/sprites/stickdude/jump.nft" ] = {
"ž0€f„",
"‹Ÿ",
"0fŸš",
"•  f0•",
"‰‚",
},
[ "/game/data/sprites/megaman/throw.nft" ] = {
"  bfŸƒ‰f3",
"  b3”0bŸ3f‰bž",
"  3f‡‚b”00€fŠ……",
"  bffb—bf‰3’fb‘0ŒŒ3f†‹",
"  fb‹bf˜33€€f‡ƒ3fb3",
"  3fŸb‹b€€3‡f3  fb‚b€fŠ",
"  bfŸ‡3‚f‚bƒfbŸ  fb‹",
"b‚ƒƒƒ  fb‚ƒƒƒ",
},
[ "/game/data/sprites/stickdude/walkshoot2.nft" ] = {
"ž0€f„e†",
"‹Ÿe“",
"  f0•  fe‚",
"˜‰",
"‚˜",
},
[ "/game/data/sprites/megaman/teleport1.nft" ] = {
"  3f•bb€f3•",
"  3b‘f3•",
"  3b•b€f3•",
"  3f…bŸf3•",
"  3b”b3‹f•",
"  3f”bb€f3•",
"  3fb‡f3•",
"  3b•b3‚f•",
"  3f•bb€f3•",
"  3b‘f3•",
"  b3Šfb3…",
},
[ "/game/data/sprites/megaman/climbshoot.nft" ] = {
"  bffb",
"bf—˜3†ƒƒfƒf3",
"3f•b•3b‡0ƒf…",
"3Šbšb3‹0ŠfŸŒ0fš3b—ƒf3",
"  f3‹3fbƒ0f3ŸbŠ",
"3fŸƒb3ƒ",
"3Šbƒfb›bf3b‡",
"  bf•fbŸ3Šb‡fb•",
"  bf•b€f•",
"  fb‹…",
},
[ "/game/data/sprites/megaman/climbtop.nft" ] = {
"  bfŸ‡‹fb",
"bfŸ3ƒ3€€€€fƒfb",
"bf•fb‡b3b€€3‚fb‹•",
"  bf•3b€3Ÿffb”",
"  3f•3€f…  bf—b€f‘",
"  bf•b€f",
"  fb‚b€f•",
},
[ "/game/data/sprites/stickdude/walkshoot3.nft" ] = {
"ž0€f„e†",
"‹Ÿe“",
"  f0•  fe‚",
"˜‰",
"0fš  f0‚",
},
[ "/game/data/sprites/megaman/walk3.nft" ] = {
"  3fŸf3",
"  bf—b€f‚3œ",
"  b3•0b‡b0œfb‰bf‘",
"  bf‡33€f™03f0Žž",
"  fb…bfŸf3Ÿ3bb3–fƒfb”",
"bf‡b€f‹3b‹b3‚f‰3Œfb“ƒ",
"bƒ‚3‡  f3‚bƒfbŸ",
"  fb‚ƒƒƒ",
},
[ "/game/data/sprites/megaman/walk1.nft" ] = {
"  3fŸf3",
"  bf—b€f‚3œ",
"  bfŸ3—f3”b•0b‡b0œfb‰bf‘",
"bf—b€f…3ffbš0f0Žž  bfƒfb”",
"b‚ƒf€b•33f‰Œf0“3fbƒfbŸ",
"bfŸ‚fb’bf3bƒ‰ff€3‚bƒ",
"b‚‹3bf•3ƒfb…",
"  fbƒƒƒ",
},
[ "/game/data/sprites/megaman/walk0.nft" ] = {
"  bfŸƒ‰f3",
"  b3”0bŸ3f‰bž",
"  bf”00€fŠ……",
"  bf—3‚fb‘0ŒŒ3f†bƒ",
"  bb€f“3f•3€€€f‚bf„fb•",
"  fbƒbf…b€€3f3bƒ",
"  bfŸ…3‚f‡3fb3ƒfŠ",
"b‚ƒƒƒ  fb‚ƒƒƒ",
},
[ "/game/data/sprites/stickdude/walk2.nft" ] = {
"ž0€f„",
"‹Ÿ",
"  f0•",
"˜‰",
"‚˜",
},
[ "/game/data/sprites/megaman/walk2.nft" ] = {
"  bf‡ƒf3›„",
"  3f—bb€03fŒfb…",
"  3f‡f3–0b•0€fŠf0•",
"  f3Šbf›3f‰f0Œ†",
"  fb‹bfˆƒ3”f3‡bŽ",
"  fb‚3f†f3•…",
"  bf—b€f",
"  fbƒƒ",
},
[ "/game/data/sprites/megaman/stand1.nft" ] = {
"  bf‡ƒf3›„",
"  3f—bb€03fŒfb…",
"  f3‚0b•0€fŠf0•",
"  bfƒ33€f‰f0Œ0f™3ƒfb”",
"bf•ˆf33€€€f•bfœb€",
"b‚ƒ3fŸb3b€3ŸbfŠfb‚ƒ",
"  bfb€3‹f‹bƒfŠfb",
"bƒƒƒ  fbƒƒƒ",
},
[ "/game/data/sprites/megaman/jumpshoot.nft" ] = {
"bfŸƒfb  bfŸƒ‰f3",
"b‚bf‡fbb3”0bŸ3f‰bž",
"  fb‹3‡bf”00€fŠ……3Ÿf3bfƒ3‹Ÿ",
"  f3‚3f‚fb‘0‘f€3†f3…b‡‚",
"  3f•3€€€f•",
"  bf•3b€3Ÿb3‡fb”",
"  3f•b3Ÿf  fb‚b€f‚fb",
"  fbŠb€f”  fb‚ƒ",
"  bb€f•",
"  fbƒ",
},
[ "/game/data/sprites/megaman/buster2-1.nft" ] = {
"  4f",
"4fŸ‡040€€4‚f”",
"4‚‹00€€4Ÿf4…",
"  f4ƒƒ",
},
[ "/game/data/sprites/megaman/walkshoot1.nft" ] = {
"  3fŸf3",
"  bf—b€f‚3œ",
"  bfŸ3—f3”b•0b‡b0œfb‰bf‘",
"bf—b€f…3ffbš0f0Žž3f‡f3”bˆŒ3f—",
"b‚ƒf€b•33f‰Œf0“3†ƒbƒ",
"bfŸ‚fb’bf3bƒ‰",
"b‚‹3bf•3ƒfb…",
"  fbƒƒƒ",
},
[ "/util/whisk.lua" ] = {
"--[[",
" Whisk - File/Folder Transmitter for ComputerCraft",
" by EldidiStroyrr",
"",
" Use the GUI by running w/o arguments",
" ",
" get with",
" pastebin get 4ZRHE4Ar whisk",
" std pb 4ZRHE4Ar whisk",
" std ld whisk whisk",
"",
" Whisk is now on SimSoft! Install w/ storecode jVELp2st",
"--]]",
"",
"local channel = 2846",
"local modem = peripheral.find(\"modem\")",
"",
"local yield = function()",
" os.queueEvent(\"yield\")",
" os.pullEvent(\"yield\")",
"end",
"",
"local displayHelp = function()",
" local helptxt = [[",
"Whisk - file/folder sender",
"",
"Syntax:",
" whisk",
" whisk send <path> [idfilter] [password]",
" whisk receive [path] [idfilter] [password]",
"]]",
" write(helptxt)",
"end",
"",
"fixstr = function(str) --replaces those annoying tabs with spaces, which fixes encryption",
" if not type(str) == \"string\" then return str end",
" local fix = string.gsub(str,string.char(9),\" \")",
" return fix",
"end",
"",
"local defaultKey = \"swordfish\" --the most secure.",
"local tArg = {...}",
"local mode, itPath, idfilter, enckey = tArg[1], tArg[2], tonumber(tArg[3]), tArg[4], tArg[5]",
"filetree = {}",
"if not enckey then",
" enckey = defaultKey",
"end",
"if tArg[5] == \"y\" then",
" doReadOnly = true",
"else",
" doReadOnly = false",
"end",
"",
"--API made by valithor.",
"local encrypt = function(msg,key)",
" local num = \"\"",
" for i = 1, #key do",
" local let = key:sub(i,i):byte()",
" num = let <= 9 and num..\"99\"..let or let<=99 and num..\"9\"..let or num..let",
" num = #msg..num",
" end",
" math.randomseed(tonumber(num))",
" local encrypt = \"\"",
" for i = 1, #msg do",
" local rotation = math.random(0,94)",
" local byte = msg:sub(i,i):byte()",
" local rotate = rotation+byte <= 127 and rotation +byte or ((rotation+byte)%127)+32",
" encrypt = encrypt..string.char(rotate)",
" end",
" return encrypt",
"end",
"",
"local decrypt = function(msg,key)",
" local num = \"\"",
" for i = 1, #key do",
" local let = key:sub(i,i):byte()",
" num = let <= 9 and num..\"99\"..let or let<=99 and num..\"9\"..let or num..let",
" num = #msg..num",
" end",
" math.randomseed(tonumber(num))",
" local decrypt = \"\"",
" for i = 1, #msg do",
" local rotation = math.random(0,94)",
" local byte = msg:sub(i,i):byte()",
" local rotate = byte-rotation >= 32 and byte-rotation or byte-rotation",
" if rotate < 32 then",
" rotate = rotate+95",
" end",
" decrypt = decrypt..string.char(rotate)",
" end",
" return decrypt",
"end",
"",
"local tEnc = function(msg)",
" return encrypt(encrypt(tostring(msg),enckey),tostring(math.floor(os.time()/2)))",
"end",
"local tDec = function(msg)",
" return decrypt(decrypt(tostring(msg),enckey),tostring(math.floor(os.time()/2)))",
"end",
"",
"listAll = function(_path, _files, noredundant) --Thanks Lyqyd!",
" local path = _path or \"\"",
" local files = _files or {}",
" if #path > 1 then table.insert(files, path) end",
" for _, file in ipairs(fs.list(path)) do",
" local path = fs.combine(path, file)",
" if fs.isDir(path) then",
" listAll(path, files)",
" else",
" table.insert(files, path)",
" end",
" end",
" if noredundant then",
" for a = 1, #files do",
" if fs.isDir(tostring(files[a])) then",
" if #fs.list(tostring(files[a])) ~= 0 then",
" table.remove(files,a)",
" end",
" end",
" end",
" end",
" return files",
"end",
"",
"local function choice(input)",
" local event, button",
" repeat",
" event, button = os.pullEvent(\"key\")",
" if type(button) == \"number\" then button = keys.getName(button) end",
" if button == nil then button = \" \" end",
" until string.find(input, button)",
" return button",
"end",
"",
"local drawThing = function(text,y,t,b)",
" local scr_x, scr_y = term.getSize()",
" local _pt,_pb = term.getTextColor(), term.getBackgroundColor()",
" if t then term.setTextColor(t) else term.setTextColor(colors.black) end",
" if b then term.setBackgroundColor(b) else term.setBackgroundColor(colors.white) end",
" term.setCursorPos(1,y-1)",
" term.clearLine()",
" term.setCursorPos((scr_x/2)-(#text/2),y)",
" term.clearLine()",
" print(text)",
" term.clearLine()",
" term.setTextColor(_pt)",
" term.setBackgroundColor(_pb)",
"end",
"",
"output = {}",
"",
"local send = function()",
" if not fs.exists(itPath) then",
" error(\"No such file.\")",
" end",
" contents = {}",
" rawContents = {}",
" if not fs.isDir(itPath) then",
" local file = fs.open(itPath,\"r\")",
" line = \"\"",
" local s = 0",
" while line do",
" line = file.readLine()",
" if line then",
" table.insert(rawContents,fixstr(line))",
" table.insert(contents,tEnc(fixstr(line)))",
" if s >= 64 then",
" yield()",
" s = 0",
" else",
" s = s + 1",
" end",
" end",
" end",
" filetree = {[fs.getName(itPath)] = {fyle = contents, dir = false}}",
" file.close()",
" output = {id = os.getComputerID(), files = filetree}",
" else",
" filelist = {}",
" _filelist = listAll(itPath,nil,true)",
" if not doReadOnly then",
" for a = 1, #_filelist do",
" if not fs.isReadOnly(_filelist[a]) then",
" table.insert(filelist,_filelist[a])",
" end",
" end",
" else",
" filelist = _filelist",
" end",
" for a = 1, #filelist do",
" local isDir",
" contents = {}",
" rawContents = {}",
" if not fs.isDir(filelist[a]) then",
" local file = fs.open(filelist[a],\"r\")",
" local line = \"\"",
" local s = 0",
" while line do",
" line = file.readLine()",
" if line then",
" table.insert(contents,tEnc(fixstr(line)))",
" table.insert(rawContents,fixstr(line))",
" if s >= 64 then",
" yield()",
" s = 0",
" else",
" s = s + 1",
" end",
" end",
" end",
" file.close()",
" isDir = false",
" else",
" contents = {\"\"}",
" isDir = true",
" end",
" if fs.combine(\"\",shell.resolve(itPath)) == \"\" then --This oughta fix things",
" filelist[a] = fs.combine(\"root\"..os.getComputerID(),filelist[a])",
" end",
" filetree[filelist[a]] = {fyle = contents, dir = isDir}",
" end",
" output = {id = os.getComputerID(), files = filetree}",
" end",
" modem.transmit(channel,channel,output)",
"end",
"local receive = function(GUImode)",
" local combinedSize = 0",
" local filecount = 0",
" --local event, side, sendID, repChannel, msg",
" while true do",
" input = {}",
" event, side, sendChannel, repChannel, msg = os.pullEvent()",
" if event == \"char\" and string.lower(side) == \"x\" then",
" if not GUImode then",
" print(\"Cancelled.\")",
" end",
" return 0,0,false",
" end",
" if type(msg) == \"table\" then",
" if type(msg.files) == \"table\" and (idfilter or msg.id) == msg.id then",
" if GUImode then",
" term.setBackgroundColor(colors.gray)",
" term.clear()",
" drawThing(\"Decrypting...\",3)",
" else",
" print(\"Decrypting...\")",
" end",
" break",
" end",
" end",
" end",
" for k,v in pairs(msg.files) do",
" local fee",
" if not itPath then",
" fee = k",
" else",
" local slashpos = string.find(k,\"/\") or 1",
" fee = fs.combine(itPath,k:sub(slashpos))",
" end",
" local doOverwrite = true",
" if fs.exists(fee) and fee == k then",
" if GUImode then",
" drawThing(\"Overwrite '\"..fee..\"'? [Y/N]\",6)",
" else",
" print(\"Overwrite '\"..fee..\"'? [Y/N]\")",
" end",
" if choice(\"yn\") == \"n\" then",
" doOverwrite = false",
" else",
" doOverwrite = true",
" end",
" end",
" if doOverwrite then",
" filecount = filecount + 1",
" if not fs.exists(fs.getDir(fee)) then fs.makeDir(fs.getDir(fee)) end",
" if type(v) == \"table\" then",
" if v.dir then",
" fs.makeDir(fee)",
" else",
" local file = fs.open(fee,\"w\")",
" if file then",
" for a = 1, #v.fyle do",
" file.writeLine(fixstr(tDec(v.fyle[a])))",
" if a % 32 == 0 then",
" yield()",
" end",
" end",
" file.close()",
" combinedSize = combinedSize + fs.getSize(fee)",
" end",
" end",
" end",
" end",
" end",
" return filecount, combinedSize, true",
"end",
"",
"local sendGUI = function()",
" term.setBackgroundColor(colors.gray)",
" term.clear()",
" drawThing(\"Which file/folder?\",3)",
" itPath = \"\"",
" repeat",
" term.setCursorPos(1,6)",
" term.setTextColor(colors.black)",
" term.setBackgroundColor(colors.lightGray)",
" term.clearLine()",
" write(\">\")",
" sleep(0)",
" itPath = read()",
" until string.gsub(itPath,\" \",\"\") ~= \"\"",
" term.setTextColor(colors.white)",
" term.setBackgroundColor(colors.gray)",
" if not fs.exists(itPath) then ",
" drawThing(\"Doesn't exist!\",3)",
" sleep(0.6)",
" return false",
" end",
" drawThing(\"Encryption key? (optional)\",3)",
" enckey = nil",
" term.setCursorPos(1,6)",
" term.setTextColor(colors.black)",
" term.setBackgroundColor(colors.lightGray)",
" term.clearLine()",
" write(\">\")",
" sleep(0)",
" enckey = read(\"*\")",
" if enckey == \"\" then enckey = defaultKey end",
" drawThing(\"ID filter? (optional)\",3)",
" idfilter = nil",
" term.setCursorPos(1,6)",
" term.setTextColor(colors.black)",
" term.setBackgroundColor(colors.lightGray)",
" term.clearLine()",
" write(\">\")",
" sleep(0)",
" idfilter = tonumber(read())",
" drawThing(\"Do read-only files/folders? (Y/N)\",3)",
" doReadOnly = false",
" term.setCursorPos(1,6)",
" term.setTextColor(colors.black)",
" term.setBackgroundColor(colors.lightGray)",
" term.clearLine()",
" sleep(0)",
" local thing = choice(\"yn\")",
" if thing == \"y\" then doReadOnly = true else doReadOnly = false end",
" local thang = \"Encrypting\"",
" if idfilter then",
" thang = thang..\" for ID \"..tostring(idfilter)..\"...\"",
" else",
" thang = thang..\"...\"",
" end",
" term.setBackgroundColor(colors.gray)",
" term.clear()",
" drawThing(thang,3)",
" send()",
" drawThing(\"Sent '\"..itPath..\"'!\",3)",
" sleep(0)",
" return true",
"end",
"",
"local receiveGUI = function()",
" term.setBackgroundColor(colors.gray)",
" term.clear()",
" drawThing(\"Save as what? (optional)\",3)",
" itPath = nil",
" term.setCursorPos(1,6)",
" term.setTextColor(colors.black)",
" term.setBackgroundColor(colors.lightGray)",
" term.clearLine()",
" write(\">\")",
" sleep(0)",
" itPath = read()",
" if string.gsub(itPath,\" \",\"\") == \"\" then",
" itPath = nil",
" end",
" drawThing(\"Decryption key? (optional)\",3)",
" enckey = nil",
" term.setCursorPos(1,6)",
" term.setTextColor(colors.black)",
" term.setBackgroundColor(colors.lightGray)",
" term.clearLine()",
" write(\">\")",
" sleep(0)",
" enckey = read(\"*\")",
" if enckey == \"\" then enckey = defaultKey end",
" drawThing(\"Filter ID? (optional)\",3)",
" idfilter = nil",
" term.setCursorPos(1,6)",
" term.setTextColor(colors.black)",
" term.setBackgroundColor(colors.lightGray)",
" term.clearLine()",
" write(\">\")",
" sleep(0)",
" idfilter = tonumber(read())",
" local thang = \"Receiving\"",
" if idfilter then",
" thang = thang..\" from ID \"..tostring(idfilter)..\"...\"",
" else",
" thang = thang..\"...\"",
" end",
" term.setBackgroundColor(colors.gray)",
" term.clear()",
" drawThing(thang,3)",
" local count,size,success = receive(true)",
" if success then",
" drawThing(\"Received!\",3)",
" if count ~= 1 then",
" drawThing(\"(Got \"..count..\" files)\",5)",
" else",
" drawThing(\"(Got \"..count..\" file)\",5)",
" end",
" if size ~= 1 then",
" drawThing(\"(Totals \"..size..\" bytes)\",7)",
" else",
" drawThing(\"(Totals \"..size..\" byte)\",7)",
" end",
" else",
" drawThing(\"Cancelled.\",3)",
" end",
" sleep(0)",
" return true",
"end",
"",
"local gui = function()",
" local scr_x, scr_y = term.getSize()",
" local prevColor = term.getBackgroundColor()",
" local evt = {}",
" term.setBackgroundColor(colors.gray)",
" term.clear()",
" while true do",
" term.setBackgroundColor(colors.gray)",
" if res then term.clear() end",
" drawThing(\"Whisk BETA\",3)",
" drawThing(\"(1) Send\",7,colors.white,colors.black)",
" drawThing(\"(2) Receive\",11,colors.white,colors.black)",
" drawThing(\"(X,Q) Exit\",15,colors.white,colors.black)",
" evt = {os.pullEvent()}",
" local res = false",
" sleep(0)",
" if evt[1] == \"mouse_click\" then",
" if evt[2] == 1 then",
" if math.abs(evt[4] - 7) <= 1 then",
" res = sendGUI()",
" elseif math.abs(evt[4] - 11) <= 1 then",
" res = receiveGUI()",
" elseif math.abs(evt[4] - 15) <= 1 then",
" res = true",
" end",
" end",
" elseif evt[1] == \"key\" then",
" if evt[2] == keys.one then",
" res = sendGUI()",
" elseif evt[2] == keys.two then",
" res = receiveGUI()",
" elseif evt[2] == keys.three or evt[2] == keys.q or evt[2] == keys.x then",
" res = true",
" end",
" end",
" if res then",
" term.setCursorPos(1,scr_y)",
" term.setBackgroundColor(prevColor)",
" term.clearLine()",
" break",
" end",
" end",
"end",
"",
"if modem then modem.open(channel) end",
"",
"waitForModem = function()",
" while true do",
" sleep(0)",
" modem = peripheral.find(\"modem\")",
" if modem then",
" return",
" end",
" end",
"end",
"",
"if not tArg[1] then",
" local prevBG, prevTXT = term.getBackgroundColor(), term.getTextColor()",
" if modem then",
" gui()",
" else",
" term.setBackgroundColor(colors.gray)",
" term.clear()",
" drawThing(\"You don't have a modem!\",3)",
" drawThing(\"Attach one or press a key.\",5)",
" sleep(0.1)",
" local outcome = parallel.waitForAny(function() os.pullEvent(\"key\") end, waitForModem)",
" if modem then",
" modem.open(channel)",
" gui()",
" else",
" local scr_x,scr_y = term.getSize()",
" term.setCursorPos(1,scr_y)",
" term.setBackgroundColor(prevBG)",
" term.setTextColor(prevTXT)",
" term.clearLine()",
" sleep(0)",
" return false",
" end",
" end ",
"else",
" if not modem then",
" error(\"No modem detected.\")",
" end",
" if mode == \"send\" then",
" send()",
" elseif mode == \"receive\" then",
" write(\"Receiving\")",
" if idfilter then",
" print(\" from \"..idfilter..\"...\")",
" else",
" print(\"...\")",
" end",
" local fc, size = receive(false)",
" write(\"Done. (got \"..fc..\" file\")",
" if fc ~= 1 then write(\"s\") end",
" write(\", totalling \"..size..\" byte\")",
" if size ~= 1 then print(\"s)\") else print(\")\") end",
" else",
" displayHelp()",
" end",
"end",
"",
"sleep(0)",
},
[ "/game/data/sprites/megaman/buster1.nft" ] = {
"f€4f€",
"4Š4€0‹f4…",
},
[ "/game/data/sprites/megaman/teleport3.nft" ] = {
"",
"",
"",
"",
"  bf‡3ƒƒb‹",
"bƒƒƒ3ƒƒbƒƒƒƒƒ",
"",
"bf3bŒb3‹3b—bf",
"b‹bf3b…b33bŸ”ŠfŸ‡",
"  3bœb3‹…3bb3Š“",
"  fb‚ƒƒƒƒƒ3ƒb",
},
[ "/game/breakout.lua" ] = {
"--[[",
" Breakout!! for CC",
" By EldidiStroyrr",
" get with:",
" pastebin get LTRYaSKt breakout",
" std pb LTRYaSKt breakout",
"",
" TODO",
" -make cooler",
"--]]",
"local level = 1",
"local lives = 3",
"local bdepth = 5",
"local y_clip = 3",
"local x_clip = 5",
"local paused = false",
"local ballslow = 2 --divides ball speed by that",
"local rigged = false",
"",
"local titlescreen = {{1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,},{1,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,1,},{1,4,16384,16384,16384,16384,16384,16384,16384,16384,16384,16384,16384,16384,16384,16384,16384,16384,16384,16384,16384,16384,16384,16384,16384,16384,16384,16384,16384,16384,16384,16384,16384,16384,16384,16384,16384,16384,16384,16384,16384,16384,16384,16384,16384,16384,16384,16384,16384,4,1,},{1,4,16384,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,16384,4,1,},{1,32768,32768,32768,16,16,32768,32768,32768,16,16,32768,32768,32768,32768,16,32768,32768,32768,32768,32768,16,32768,16,16,32768,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,2,16384,4,1,},{1,32768,16384,2,32768,32,32768,32,32,32768,32,32768,32,32,32,32,32768,32,32,32,32768,32,32768,32,32,32768,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,16,2,16384,4,1,},{1,32768,32768,32768,16,32,32768,32768,32768,8192,8192,32768,32768,8192,8192,8192,32768,32768,32768,32768,32768,8192,32768,32768,32768,8192,8192,8192,8192,8192,8192,8192,8192,8192,8192,8192,8192,8192,8192,8192,8192,8192,8192,8192,8192,32,16,2,16384,4,1,},{1,32768,16384,2,32768,32,32768,2048,2048,32768,2048,32768,2048,2048,2048,2048,32768,2048,2048,2048,32768,2048,32768,2048,2048,32768,2048,2048,2048,2048,2048,2048,2048,2048,2048,2048,2048,2048,2048,2048,2048,2048,2048,2048,8192,32,16,2,16384,4,1,},{1,32768,32768,32768,32768,32,32768,2048,1024,32768,1024,32768,32768,32768,32768,1024,32768,1024,1024,1024,32768,1024,32768,1024,1024,32768,1024,1024,1024,1024,1024,1024,1024,1024,1024,1024,1024,1024,1024,1024,1024,1024,1024,2048,8192,32,16,2,16384,4,1,},{1,32768,32768,32768,16,32,32768,2048,1024,32768,1024,32768,32768,32768,32768,1024,32768,1024,1024,1024,32768,1024,32768,1024,1024,32768,1024,1024,1024,1024,1024,1024,1024,1024,1024,1024,1024,1024,1024,1024,1024,1024,1024,2048,8192,32,16,2,16384,4,1,},{1,4,16384,2,16,32,8192,2048,2048,2048,2048,2048,2048,2048,2048,2048,2048,2048,2048,2048,2048,2048,2048,2048,2048,2048,2048,2048,2048,2048,2048,2048,2048,2048,2048,2048,2048,2048,2048,2048,2048,2048,2048,2048,8192,32,16,2,16384,4,1,},{1,4,16384,2,16,32,8192,8192,8192,8192,8192,8192,8192,8192,8192,8192,8192,8192,8192,8192,8192,32768,32768,32768,32768,32768,8192,32768,8192,8192,32768,8192,32768,32768,32768,32768,32768,8192,32768,32768,8192,32768,32768,8192,8192,32,16,2,16384,4,1,},{1,4,16384,2,16,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32768,32,32,32,32768,32,32768,32,32,32768,32,32,32,32768,32,32,32,32768,32768,32,32768,32768,32,32,32,16,2,16384,4,1,},{1,4,16384,2,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,32768,16,16,16,32768,16,32768,16,16,32768,16,16,16,32768,16,16,16,32768,32768,16,32768,32768,16,16,16,16,2,16384,4,1,},{1,4,16384,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,32768,2,2,2,32768,2,32768,2,2,32768,2,2,2,32768,2,2,2,32768,32768,2,32768,32768,2,2,2,2,2,16384,4,1,},{1,4,16384,16384,16384,16384,16384,16384,16384,16384,16384,16384,16384,16384,16384,16384,16384,16384,16384,16384,16384,32768,32768,32768,32768,32768,16384,32768,32768,32768,32768,16384,16384,16384,32768,16384,16384,16384,16384,16384,16384,16384,16384,16384,16384,16384,16384,16384,16384,4,1,},{1,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,32768,32768,32768,32768,32768,4,32768,32768,32768,32768,4,4,4,32768,4,4,4,32768,32768,4,32768,32768,4,4,4,4,4,4,4,1,},{1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,},{1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,},{1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,},}",
"",
"local prevColors = {",
" term.getTextColor(),",
" term.getBackgroundColor()",
"}",
"",
"local scr_x, scr_y = term.getSize()",
"local board = {",
" length = 8,",
" x = math.floor(scr_x/2),",
" y = scr_y-1,",
" bgcolor = colors.white,",
" txtcolor = colors.white,",
" char = \" \",",
" dir = 0,",
" canMove = true,",
"}",
"local ball = {",
" x = math.floor(scr_x/2),",
" y = scr_y-5,",
" xv = 1,",
" yv = -1,",
" px = 1,",
" py = 1,",
" txtcolor = colors.white,",
" bgcolor = colors.white,",
" char = \"O\",",
"}",
"local sr = string.rep",
"local remakeBricks = function(xclip,yclip,depth)",
" local output, entry = {}, 0",
" local blitColors = \"0123456789abcdef\"",
" for a = yclip, depth do",
" for b = (xclip+1), scr_x-xclip do",
" entry = entry + 1",
" local d = math.random(1,15)",
" local c = string.sub(blitColors,d,d)",
" output[entry] = {x = b, y = a, color = {c,c},char=\"L\"}",
" end",
" end",
" return output",
"end",
"local cprint = function(msg,cy)",
" term.setCursorPos((scr_x/2)-math.floor(#msg/2), cy or (scr_y/2))",
" print(msg)",
"end",
"local waitForEvents = function(...)",
" local targ = {...}",
" while true do",
" local evt = {os.pullEvent()}",
" for a = 1, #targ do",
" if evt[1] == targ[a] then",
" return table.unpack(evt)",
" end",
" end",
" end",
"end",
"local titleScreen = function()",
" paintutils.drawImage(titlescreen,1,1)",
" sleep(0)",
" return waitForEvents(\"key\",\"mouse_click\")",
"end",
"local clearLines = function(startY,endY)",
" local ori = {term.getCursorPos()}",
" for a = startY,endY do",
" term.setCursorPos(1,a)",
" term.clearLine()",
" end",
" term.setCursorPos(table.unpack(ori))",
" return",
"end",
"local clearDot = function(x,y)",
" local pX,pY = term.getCursorPos()",
" term.setCursorPos(x,y)",
" term.write(\" \")",
" term.setCursorPos(pX,pY)",
"end",
"",
"local render = function(brd,blocktbl)",
" term.setBackgroundColor(colors.black)",
" term.setCursorPos(2,1)",
" term.write(\"Lives: \"..lives)",
" local lvlcount = \"Level: \"..tostring(level)",
" term.setCursorPos(scr_x-#lvlcount,1)",
" term.write(lvlcount)",
" term.setCursorPos(brd.x,brd.y)",
" term.clearLine()",
" term.setTextColor(brd.txtcolor)",
" term.setBackgroundColor(brd.bgcolor)",
" term.write(sr(brd.char,brd.length))",
" for k,v in pairs(blocktbl) do",
" term.setCursorPos(v.x,v.y)",
" term.blit(v.char,v.color[1],v.color[2])",
" end",
" term.setCursorPos(ball.px,ball.py)",
" term.blit(\" \",\"f\",\"f\")",
" term.setCursorPos(ball.x,ball.y)",
" term.setTextColor(ball.txtcolor)",
" term.setBackgroundColor(ball.bgcolor)",
" term.write(ball.char)",
"end",
"",
"local levelComplete = function()",
" local txt = \"LEVEL COMPLETE!\"",
" term.setTextColor(colors.gray)",
" term.setCursorPos((scr_x/2)-(#txt/2),scr_y/2)",
" term.write(txt)",
" sleep(0.1)",
" term.setTextColor(colors.lightGray)",
" term.setCursorPos((scr_x/2)-(#txt/2),scr_y/2)",
" term.write(txt)",
" sleep(0.1)",
" for a = 1, 8 do",
" term.setTextColor(colors.white)",
" term.setCursorPos((scr_x/2)-(#txt/2),scr_y/2)",
" term.write(txt)",
" sleep(0.3)",
" term.setTextColor(colors.black)",
" term.setCursorPos((scr_x/2)-(#txt/2),scr_y/2)",
" term.write(txt)",
" sleep(0.3)",
" end",
" sleep(0.3)",
" blocks = remakeBricks(x_clip,y_clip,bdepth)",
" lives = lives + 2",
" level = level + 1",
" board.x = math.floor((scr_x/2)-(board.length/2))",
" ball.x = math.floor(scr_x/3)",
" ball.y = board.y - 3",
" ball.xv = 1",
" ball.yv = -1",
"end",
"",
"local checkCollision = function()",
" local good = false",
" for a = 1, #blocks do",
" if blocks[a] then",
" if blocks[a].x == ball.x + ball.xv and blocks[a].y == ball.y then",
" ball.xv = -ball.xv",
" clearDot(blocks[a].x,blocks[a].y)",
" good = true",
" end",
" if blocks[a].y == ball.y + ball.yv and blocks[a].x == ball.x then",
" ball.yv = -ball.yv",
" clearDot(blocks[a].x,blocks[a].y)",
" good = true",
" end",
" if good then",
" table.remove(blocks,a)",
" good = false",
" end",
" end",
" end",
"end",
"",
"local animateDeath = function()",
" board.dir = 0",
" local tbl = {",
" {\"*\",\"7\",\"0\"},",
" {\"x\",\"7\",\"8\"},",
" {\"X\",\"f\",\"8\"},",
" {\"X\",\"f\",\"7\"},",
" }",
" term.setBackgroundColor(colors.black)",
" term.setCursorPos(ball.x,ball.y)",
" term.write(\" \")",
" term.setCursorPos(1,board.y)",
" term.clearLine()",
" for a = 1, #tbl do",
" term.setCursorPos(board.x,board.y)",
" local char,txt,bg = tbl[a][1]:rep(board.length),tbl[a][2]:rep(board.length),tbl[a][3]:rep(board.length)",
" term.blit(char,txt,bg)",
" sleep(0.05)",
" end",
" term.setCursorPos(board.x,board.y)",
" term.setBackgroundColor(colors.black)",
" term.clearLine()",
" sleep(0.5)",
" board.x = (scr_x/2)-(board.length/2)",
"end",
"",
"local animateGameOver = function()",
" board.canMove = false",
" animateDeath()",
" local txt = \"GAME OVER\"",
" term.setTextColor(colors.white)",
" term.setBackgroundColor(colors.black)",
" for a = 0, scr_y/2 do",
" term.clearLine()",
" term.setCursorPos((scr_x/2)-(#txt/2),scr_y-a)",
" term.write(txt)",
" sleep(0.1)",
" end",
" sleep(0.5)",
" return",
"end",
"",
"local togglePauseScreen = function(_paused)",
" local txt = \"PAUSED ('P' to unpause)\"",
" term.setBackgroundColor(colors.black)",
" if _paused then",
" term.setCursorPos((scr_x/2)-(#txt/2),scr_y/2)",
" term.blit(txt,sr(\"7\",#txt),sr(\"f\",#txt))",
" sleep(0.1)",
" term.setCursorPos((scr_x/2)-(#txt/2),scr_y/2)",
" term.blit(txt,sr(\"8\",#txt),sr(\"f\",#txt))",
" sleep(0.1)",
" term.setCursorPos((scr_x/2)-(#txt/2),scr_y/2)",
" term.blit(txt,sr(\"0\",#txt),sr(\"f\",#txt))",
" sleep(0.1)",
" else",
" term.setCursorPos((scr_x/2)-(#txt/2),scr_y/2)",
" term.blit(txt,sr(\"8\",#txt),sr(\"f\",#txt))",
" sleep(0.1)",
" term.setCursorPos((scr_x/2)-(#txt/2),scr_y/2)",
" term.blit(txt,sr(\"7\",#txt),sr(\"f\",#txt))",
" sleep(0.1)",
" term.setCursorPos((scr_x/2)-(#txt/2),scr_y/2)",
" term.clearLine()",
" end",
"end",
"",
"local game = function()",
" term.setBackgroundColor(colors.black)",
" term.clear()",
" blocks = remakeBricks(x_clip,y_clip,bdepth)",
" local frame = 1",
" while true do",
" if not paused then",
" ball.x = math.floor(ball.x)",
" ball.y = math.floor(ball.y)",
" if rigged then",
" board.x = ball.x-math.floor(board.length/2)",
" else",
" board.x = board.x + board.dir",
" end",
" if frame % ballslow == 0 then",
" if frame > 40000000 then",
" frame = 100",
" end",
" if frame > 60 then",
" ballslow = 1",
" end",
" if ball.x <= 1 or ball.x >= scr_x then",
" ball.xv = ball.xv * -1",
" end",
" if ball.y <= 1 then",
" ball.yv = -ball.yv",
" elseif ball.y >= scr_y then",
" if lives > 1 then",
" board.canMove = false",
" animateDeath()",
" ball.x = scr_x/2",
" ball.y = scr_y-8",
" ball.xv = 1",
" ball.yv = -1",
" lives = lives - 1",
" board.canMove = true",
" else",
" lives = lives - 1",
" animateGameOver()",
" return \"lose\"",
" end",
" end",
" ball.px = ball.x",
" ball.py = ball.y",
" ball.y = math.floor(ball.y + ball.yv)",
" term.setBackgroundColor(colors.black)",
" checkCollision()",
" ball.x = math.floor(ball.x + ball.xv)",
" checkCollision()",
" if #blocks == 0 then levelComplete() end",
" if (ball.y+1 == board.y or ball.y == board.y) and (ball.x >= board.x and ball.x <= board.x+board.length) then",
" ball.yv = -ball.yv",
" if ball.x < board.x+(board.length/2)-1 then",
" ball.xv = -1",
" elseif ball.x > board.x+(board.length/2)+1 then",
" ball.xv = 1",
" end",
" end",
" end",
" sleep(0)",
" frame = frame + 1",
" render(board,blocks)",
" end",
" sleep(0)",
" end",
"end",
"",
"local getInput = function()",
" local event, key",
" local downKeys = {left = false, right = false}",
" while true do",
" event, key, mx, my = os.pullEvent()",
" if event == \"key\" then",
" if board.canMove and not paused then",
" if key == keys.left and board.x > 1 then",
" board.dir = -1",
" downKeys.left = true",
" elseif key == keys.right and board.x < (scr_x+1)-board.length then",
" board.dir = 1",
" downKeys.right = true",
" end",
" else board.dir = 0 end",
" if key == keys.q then return end",
" if key == keys.p then",
" if not paused then --this is to fix a rendering problem",
" paused = true",
" togglePauseScreen(true)",
" else",
" togglePauseScreen(false)",
" paused = false",
" end",
" end",
" elseif event == \"key_up\" then",
" if key == keys.left then",
" downKeys.left = false",
" elseif key == keys.right then",
" downKeys.right = false",
" end",
" if (downKeys.left == false and downKeys.right == false) or (board.x <= 1 or board.x-board.length >= scr_x) then",
" board.dir = 0",
" end",
" elseif event == \"mouse_click\" or event == \"mouse_drag\" then",
" if board.canMove and not paused then",
" board.x = mx-(board.length/2)",
" end",
" end",
" if board.x < 1 then board.x = 1 board.dir = 0",
" elseif board.x > (scr_x+1)-board.length then board.x = (scr_x+1)-board.length board.dir = 0 end",
" end",
"end",
"",
"local outro = function(txtcolor,bgcolor,result)",
" term.setTextColor(txtcolor)",
" term.setBackgroundColor(bgcolor)",
" term.clear()",
" term.setCursorPos(1,1)",
" print(\"Thanks for playing!\")",
" return result",
"end",
"",
"titleScreen()",
"local startFuncs = {",
" game,",
" getInput,",
"}",
"parallel.waitForAny(table.unpack(startFuncs))",
"outro(prevColors[1],prevColors[2])",
"sleep(0)",
},
[ "/game/data/sprites/megaman/hurt.nft" ] = {
"  3fŸf3",
"  bf—b€f‚3œ",
"  3fŸf3b•0b‡ƒ‹‡3fŸf3",
"bfŸ3Š3ffbš0f0œŽœ3šb…f‚fb",
"bŠ  3f‰‹f3ž  fb…",
"  3f•b33fŠ",
"  3f…b‹b3fb3fb3fb•",
"  b3‚ƒfb  bfb€f”",
"  bfŸb€€",
"  fb‚ƒ",
},
[ "/game/data/api/nfte" ] = {
"local tchar, bchar = string.char(31), string.char(30)",
"",
"local deepCopy = function(tbl)",
" local output = {}",
" for k,v in pairs(tbl) do",
" output[k] = v",
" end",
" return output",
"end",
"",
"local function stringWrite(str,pos,ins,exc)",
" str, ins = tostring(str), tostring(ins)",
" local output, fn1, fn2 = str:sub(1,pos-1)..ins..str:sub(pos+#ins)",
" if exc then",
" repeat",
" fn1, fn2 = str:find(exc,fn2 and fn2+1 or 1)",
" if fn1 then",
" output = stringWrite(output,fn1,str:sub(fn1,fn2))",
" end",
" until not fn1",
" end",
" return output",
"end",
"",
"local checkValid = function(image)",
" if type(image) == \"table\" then",
" if #image == 3 then",
" if #image[1] + #image[2] + #image[3] >= 3 then",
" return (#image[1] == #image[2] and #image[2] == #image[3])",
" end",
" end",
" end",
" return false",
"end",
"local bl = {",
" [' '] = 0,",
" ['0'] = 1,",
" ['1'] = 2,",
" ['2'] = 4,",
" ['3'] = 8,",
" ['4'] = 16,",
" ['5'] = 32,",
" ['6'] = 64,",
" ['7'] = 128,",
" ['8'] = 256,",
" ['9'] = 512,",
" ['a'] = 1024,",
" ['b'] = 2048,",
" ['c'] = 4096,",
" ['d'] = 8192,",
" ['e'] = 16384,",
" ['f'] = 32768,",
"}",
"local lb = {}",
"for k,v in pairs(bl) do",
" lb[v] = k",
"end",
"",
"local ldchart = { --it stands for light/dark chart",
" [\"0\"] = \"0\",",
" [\"1\"] = \"4\",",
" [\"2\"] = \"6\",",
" [\"3\"] = \"0\",",
" [\"4\"] = \"0\",",
" [\"5\"] = \"0\",",
" [\"6\"] = \"0\",",
" [\"7\"] = \"8\",",
" [\"8\"] = \"0\",",
" [\"9\"] = \"3\",",
" [\"a\"] = \"2\",",
" [\"b\"] = \"9\",",
" [\"c\"] = \"1\",",
" [\"d\"] = \"5\",",
" [\"e\"] = \"2\",",
" [\"f\"] = \"7\"",
"}",
"",
"local getSizeNFP = function(image)",
" local xsize = 0",
" if type(image) ~= \"table\" then return 0,0 end",
" for y = 1, #image do xsize = math.max(xsize,#image[y]) end",
" return xsize, #image",
"end",
"",
"getSize = function(image)",
" assert(checkValid(image), \"Invalid image.\")",
" local x, y = 0, #image[1]",
" for y = 1, #image[1] do",
" x = math.max(x, #image[1][y])",
" end",
" return x, y",
"end",
"",
"crop = function(image, x1, y1, x2, y2)",
" assert(checkValid(image), \"Invalid image.\")",
" local output = {{},{},{}}",
" for y = y1, y2 do",
" output[1][#output[1]+1] = image[1][y]:sub(x1,x2)",
" output[2][#output[2]+1] = image[2][y]:sub(x1,x2)",
" output[3][#output[3]+1] = image[3][y]:sub(x1,x2)",
" end",
" return output",
"end",
"",
"loadImageData = function(image, background) --string image",
" local output = {{},{},{}} --char, text, back",
" local y = 1",
" local initText, initBack = \"0\", background or \" \"",
" local text, back = initText, initBack",
" local doSkip, c1, c2 = false",
" local maxX = 0",
" for i = 1, #image do",
" if doSkip then",
" doSkip = false",
" else",
" output[1][y] = output[1][y] or \"\"",
" output[2][y] = output[2][y] or \"\"",
" output[3][y] = output[3][y] or \"\"",
" c1, c2 = image:sub(i,i), image:sub(i+1,i+1)",
" if c1 == tchar then",
" text = c2",
" doSkip = true",
" elseif c1 == bchar then",
" back = c2",
" doSkip = true",
" elseif c1 == \"\\n\" then",
" maxX = math.max(maxX, #output[1][y] + 1)",
" y = y + 1",
" text, back = initText, initBack",
" else",
" output[1][y] = output[1][y]..c1",
" output[2][y] = output[2][y]..text",
" output[3][y] = output[3][y]..back",
" end",
" end",
" end",
" for y = 1, #output[1] do",
" output[1][y] = output[1][y] .. (\" \"):rep(maxX - #output[1][y])",
" output[2][y] = output[2][y] .. (\" \"):rep(maxX - #output[2][y])",
" output[3][y] = output[3][y] .. (\" \"):rep(maxX - #output[3][y])",
" end",
" return output",
"end",
"",
"convertFromNFP = function(image)",
" local output = {{},{},{}}",
" local imageX, imageY = getSizeNFP(image)",
" for y = 1, imageY do",
" output[1][y] = \"\"",
" output[2][y] = \"\"",
" output[3][y] = \"\"",
" for x = 1, imageX do",
" output[1][y] = output[1][y]..lb[image[y][x] or \" \"]",
" output[2][y] = output[2][y]..lb[image[y][x] or \" \"]",
" output[3][y] = output[3][y]..lb[image[y][x] or \" \"]",
" end",
" end",
" return output",
"end",
"",
"loadImage = function(path, background)",
" local file = fs.open(path,\"r\")",
" local output = loadImageData(file.readAll(), background)",
" file.close()",
" return output",
"end",
"",
"unloadImage = function(image)",
" assert(checkValid(image), \"Invalid image.\")",
" local output = \"\"",
" local text, back = \" \", \" \"",
" local c, t, b",
" for y = 1, #image[1] do",
" for x = 1, #image[1][y] do",
" c, t, b = image[1][y]:sub(x,x), image[2][y]:sub(x,x), image[3][y]:sub(x,x)",
" if (t ~= text) or (x + y == 2) then output = output..tchar..t end",
" if (b ~= back) or (x + y == 2) then output = output..bchar..b end",
" output = output..c",
" end",
" if y ~= #image[1] then",
" output = output..\"\\n\"",
" text, back = \" \", \" \"",
" end",
" end",
" return output",
"end",
"",
"drawImage = function(image, x, y)",
" assert(checkValid(image), \"Invalid image.\")",
" local cx, cy = term.getCursorPos()",
" for iy = 1, #image[1] do",
" term.setCursorPos(x,y+(iy-1))",
" term.blit(image[1][iy], image[2][iy], image[3][iy])",
" end",
" term.setCursorPos(cx,cy)",
"end",
"",
"drawImageTransparent = function(image, x, y)",
" assert(checkValid(image), \"Invalid image. (\" .. textutils.serialize(image) .. \")\")",
" local cx, cy = term.getCursorPos()",
" local c, t, b",
" for iy = 1, #image[1] do",
" for ix = 1, #image[1][iy] do",
" c, t, b = image[1][iy]:sub(ix,ix), image[2][iy]:sub(ix,ix), image[3][iy]:sub(ix,ix)",
" if not (b == \" \" and c == \" \") then",
" term.setCursorPos(x+(ix-1),y+(iy-1))",
" term.blit(c, t, b)",
" end",
" end",
" end",
" term.setCursorPos(cx,cy)",
"end",
"",
"drawImageCenter = function(image, x, y)",
" local scr_x, scr_y = term.getSize()",
" local imageX, imageY = getSize(image)",
" return drawImage(image, (x and x or (scr_x/2)) - (imageX/2), (y and y or (scr_y/2)) - (imageY/2))",
"end",
"",
"drawImageCenterTransparent = function(image, x, y)",
" local scr_x, scr_y = term.getSize()",
" local imageX, imageY = getSize(image)",
" return drawImageTransparent(image, (x and x or (scr_x/2)) - (imageX/2), (y and y or (scr_y/2)) - (imageY/2))",
"end",
"",
"colorSwap = function(image, tbl)",
" local output = {{},{},{}}",
" for y = 1, #image[1] do",
" output[1][y] = image[1][y]",
" output[2][y] = image[2][y]:gsub(\".\", tbl)",
" output[3][y] = image[3][y]:gsub(\".\", tbl)",
" end",
" return output",
"end",
"",
"local xflippable = {",
" [\"\"] = \"‚\",",
" [\"ƒ\"] = \"ƒ\",",
" [\"„\"] = \"ˆ\",",
" [\"…\"] = \"Š\",",
" [\"†\"] = \"‰\",",
" [\"‡\"] = \"‹\",",
" [\"Œ\"] = \"Œ\",",
" [\"\"] = \"Ž\",",
" [\"\"] = \"\",",
" [\"\\32\"] = \"\\32\"",
"}",
"local xinvertable = {",
" [\"\"] = \"Ÿ\",",
" [\"‘\"] = \"\",",
" [\"’\"] = \"ž\",",
" [\"“\"] = \"œ\",",
" [\"”\"] = \"—\",",
" [\"˜\"] = \"›\"",
"}",
"for k,v in pairs(xflippable) do",
" xflippable[v] = k",
"end",
"for k,v in pairs(xinvertable) do",
" xinvertable[v] = k",
"end",
"",
"flipX = function(image)",
" assert(checkValid(image), \"Invalid image.\")",
" local output = {{},{},{}}",
" for y = 1, #image[1] do",
" output[1][y] = image[1][y]:reverse():gsub(\".\", xflippable):gsub(\".\", xinvertable)",
" output[2][y] = \"\"",
" output[3][y] = \"\"",
" for x = 1, #image[1][y] do",
" if (not xflippable[image[1][y]:sub(x,x)]) or xinvertable[image[1][y]:sub(x,x)] then",
" output[2][y] = image[3][y]:sub(x,x) .. output[2][y]",
" output[3][y] = image[2][y]:sub(x,x) .. output[3][y]",
" else",
" output[2][y] = image[2][y]:sub(x,x) .. output[2][y]",
" output[3][y] = image[3][y]:sub(x,x) .. output[3][y]",
" end",
" end",
" end",
" return output",
"end",
"",
"flipY = function(image)",
" assert(checkValid(image), \"Invalid image.\")",
" local output = {{},{},{}}",
" for y = #image[1], 1, -1 do",
" output[1][#output[1]+1] = image[1][y]",
" output[2][#output[2]+1] = image[2][y]",
" output[3][#output[3]+1] = image[3][y]",
" end",
" return output",
"end",
"",
"grayOut = function(image)",
" assert(checkValid(image), \"Invalid image.\")",
" local output = {{},{},{}}",
" local chart = {",
" [\"0\"] = \"0\",",
" [\"1\"] = \"8\",",
" [\"2\"] = \"8\",",
" [\"3\"] = \"8\",",
" [\"4\"] = \"8\",",
" [\"5\"] = \"8\",",
" [\"6\"] = \"8\",",
" [\"7\"] = \"7\",",
" [\"8\"] = \"8\",",
" [\"9\"] = \"7\",",
" [\"a\"] = \"7\",",
" [\"b\"] = \"7\",",
" [\"c\"] = \"7\",",
" [\"d\"] = \"7\",",
" [\"e\"] = \"7\",",
" [\"f\"] = \"f\"",
" }",
" for k,v in pairs(chart) do",
" for y = 1, #image[1] do",
" output[1][y] = image[1][y]:gsub(k,v)",
" output[2][y] = image[2][y]:gsub(k,v)",
" output[3][y] = image[3][y]:gsub(k,v)",
" end",
" end",
" return output",
"end",
"",
"greyOut = grayOut",
"",
"lighten = function(image)",
" assert(checkValid(image), \"Invalid image.\")",
" local output = {{},{},{}}",
" for k,v in pairs(ldchart) do",
" for y = 1, #image[1] do",
" output[1][y] = image[1][y]:gsub(k,v)",
" output[2][y] = image[2][y]:gsub(k,v)",
" output[3][y] = image[3][y]:gsub(k,v)",
" end",
" end",
" return output",
"end",
"",
"darken = function(image)",
" assert(checkValid(image), \"Invalid image.\")",
" local output = {{},{},{}}",
" for k,v in pairs(ldchart) do",
" for y = 1, #image[1] do",
" output[1][y] = image[1][y]:gsub(v,k)",
" output[2][y] = image[2][y]:gsub(v,k)",
" output[3][y] = image[3][y]:gsub(v,k)",
" end",
" end",
" return output",
"end",
"",
"stretchImage = function(_image, sx, sy, noRepeat)",
" assert(checkValid(_image), \"Invalid image.\")",
" local output = {{},{},{}}",
" local image = deepCopy(_image)",
" if sx < 0 then image = flipX(image) end",
" if sy < 0 then image = flipY(image) end",
" sx, sy = math.abs(sx), math.abs(sy)",
" local imageX, imageY = getSize(image)",
" local tx, ty",
" for y = 1, sy do",
" for x = 1, sx do",
" tx = math.ceil((x / sx) * imageX)",
" ty = math.ceil((y / sy) * imageY)",
" if not noRepeat then",
" output[1][y] = (output[1][y] or \"\")..image[1][ty]:sub(tx,tx)",
" else",
" output[1][y] = (output[1][y] or \"\")..\" \"",
" end",
" output[2][y] = (output[2][y] or \"\")..image[2][ty]:sub(tx,tx)",
" output[3][y] = (output[3][y] or \"\")..image[3][ty]:sub(tx,tx)",
" end",
" end",
" if noRepeat then",
" for y = 1, imageY do",
" for x = 1, imageX do",
" if image[1][y]:sub(x,x) ~= \" \" then",
" tx = math.ceil(((x / imageX) * sx) - ((0.5 / imageX) * sx))",
" ty = math.ceil(((y / imageY) * sy) - ((0.5 / imageY) * sx))",
" output[1][ty] = stringWrite(output[1][ty], tx, image[1][y]:sub(x,x))",
" end",
" end",
" end",
" end",
" return output",
"end",
"",
"pixelateImage = function(image,amntX, amntY)",
" assert(checkValid(image), \"Invalid image.\")",
" local imageX, imageY = getSize(image)",
" return stretchImage(stretchImage(image,imageX/math.max(amntX,1), imageY/math.max(amntY,1)), imageX, imageY)",
"end",
"",
"merge = function(...)",
" local images = {...}",
" local output = {{},{},{}}",
" local imageX, imageY = 0, 0",
" for i = 1, #images do",
" imageY = math.max(imageY, #images[i][1][1]+(images[i][3]-1))",
" for y = 1, #images[i][1][1] do",
" imageX = math.max(imageX, #images[i][1][1][y]+(images[i][2]-1))",
" end",
" end",
" ",
" --will later add code to adjust X/Y positions if negative values are given",
" ",
" local image, xadj, yadj",
" local tx, ty",
" for y = 1, imageY do",
" output[1][y] = {}",
" output[2][y] = {}",
" output[3][y] = {}",
" for x = 1, imageX do",
" for i = 1, #images do",
" image, xadj, yadj = images[i][1], images[i][2], images[i][3]",
" tx, ty = x-(xadj-1), y-(yadj-1)",
" output[1][y][x] = output[1][y][x] or \" \"",
" output[2][y][x] = output[2][y][x] or \" \"",
" output[3][y][x] = output[3][y][x] or \" \"",
" if image[1][ty] then",
" if (image[1][ty]:sub(tx,tx) ~= \"\") and (tx >= 1) then",
" output[1][y][x] = (image[1][ty]:sub(tx,tx) == \" \" and output[1][y][x] or image[1][ty]:sub(tx,tx))",
" output[2][y][x] = (image[2][ty]:sub(tx,tx) == \" \" and output[2][y][x] or image[2][ty]:sub(tx,tx))",
" output[3][y][x] = (image[3][ty]:sub(tx,tx) == \" \" and output[3][y][x] or image[3][ty]:sub(tx,tx))",
" end",
" end",
" end",
" end",
" output[1][y] = table.concat(output[1][y])",
" output[2][y] = table.concat(output[2][y])",
" output[3][y] = table.concat(output[3][y])",
" end",
" return output",
"end",
"",
"rotateImage = function(image, angle)",
" local output = {{},{},{}}",
" local realOutput = {{},{},{}}",
" local tx, ty",
" local imageX, imageY = getSize(image)",
" local originX, originY = imageX / 2, imageY / 2",
" local adjX, adjY = 1, 1",
" for y = 1, #image[1] do",
" for x = 1, #image[1][y] do",
" if not (image[1][y]:sub(x,x) == \" \" and image[2][y]:sub(x,x) == \" \" and image[3][y]:sub(x,x) == \" \") then",
" tx = math.floor( (x-originX) * math.cos(angle) - (originY-y) * math.sin(angle) )",
" ty = math.floor( (x-originX) * math.sin(angle) + (originY-y) * math.cos(angle) )",
" adjX, adjY = math.min(adjX, tx), math.min(adjY, ty)",
" output[1][ty] = output[1][ty] or {}",
" output[2][ty] = output[2][ty] or {}",
" output[3][ty] = output[3][ty] or {}",
" output[1][ty][tx] = image[1][y]:sub(x,x)",
" output[2][ty][tx] = image[2][y]:sub(x,x)",
" output[3][ty][tx] = image[3][y]:sub(x,x)",
" end",
" end",
" end",
" for y = adjY, #output[1] do",
" realOutput[1][y+1-adjY] = {}",
" realOutput[2][y+1-adjY] = {}",
" realOutput[3][y+1-adjY] = {}",
" for x = adjX, #output[1][y] do",
" realOutput[1][y+1-adjY][x+1-adjX] = output[1][y][x] or \" \"",
" realOutput[2][y+1-adjY][x+1-adjX] = output[2][y][x] or \" \"",
" realOutput[3][y+1-adjY][x+1-adjX] = output[3][y][x] or \" \"",
" end",
" end",
" for y = 1, #realOutput[1] do",
" realOutput[1][y] = table.concat(realOutput[1][y])",
" realOutput[2][y] = table.concat(realOutput[2][y])",
" realOutput[3][y] = table.concat(realOutput[3][y])",
" end",
" return realOutput, math.ceil(adjX-1+originX), math.ceil(adjY-1+originY)",
"end",
"",
"help = function(input)",
" local helpOut = {",
" loadImageData = \"Loads an NFT image from a string input.\",",
" loadImage = \"Loads an NFT image from a file path.\",",
" convertFromNFP = \"Loads a table NFP image into a table NFT image, same as what loadImage outputs.\",",
" drawImage = \"Draws an image. Does not support transparency, sadly.\",",
" drawImageTransparent = \"Draws an image. Supports transparency, but not as fast as drawImage.\",",
" drawImageCenter = \"Draws an image centered around the inputted coordinates. Does not support transparency, sadly.\",",
" drawImageCenterTransparent = \"Draws an image centered around the inputted coordinates. Supports transparency, but not as fast as drawImageCenter.\",",
" flipX = \"Returns the inputted image, but with the X inverted.\",",
" flipY = \"Returns the inputted image, but with the Y inverted.\",",
" grayOut = \"Returns the inputted image, but with the colors converted into grayscale as best I could.\",",
" lighten = \"Returns the inputted image, but with the colors lightened.\",",
" darken = \"Returns the inputted image, but with the colors darkened.\",",
" stretchImage = \"Returns the inputted image, but it's been stretched to the inputted size. If the fourth argument is true, it will spread non-space characters evenly in the image.\",",
" pixelateImage = \"Returns the inputted image, but pixelated to a variable degree.\",",
" merge = \"Merges two or more images together.\",",
" crop = \"Crops an image between points (X1,Y1) and (X2,Y2).\",",
" rotateImage = \"Rotates an image, and also returns how much the image center's X and Y had been adjusted.\",",
" colorSwap = \"Swaps the colors of a given image with another color, according to an inputted table.\"",
" }",
" return helpOut[input] or \"No such function.\"",
"end",
},
[ "/util/fakechat.lua" ] = {
"-- ...use with responsibility.",
"--",
"-- Get with",
"-- pastebin get n3K9Nt3D fakechat",
"-- std PB n3K9Nt3D fakechat",
"",
"local names = { --Add names to quickly switch between using PageUP and PageDOWN",
" {",
" name = \"&o&6Jesus\",",
" prefix = \"<\",",
" suffix = \"> \",",
" },",
" {",
" name = \"&dServer\",",
" prefix = \"&d[\",",
" suffix = \"&d] \",",
" msgprefix = \"&d\",",
" realname = \"But nobody\"",
" },",
" {",
" name = \"&eBagel&6Bot\",",
" prefix = \"<\",",
" suffix = \"> \",",
" },",
" {",
" name = \"Lr_\",",
" prefix = \"<\",",
" suffix = \"> \",",
" },",
" {",
" name = \"dan200\",",
" prefix = \"<\",",
" suffix = \"> \",",
" },",
"}",
"",
"local sHistories = {}",
"",
"local cname = 1",
"",
"local tArg = {...}",
"",
"local channel = 1251 --default 1251",
"",
"local sHistory = {}",
"local scr_x, scr_y = term.getSize()",
"local modems",
"local setModems = function()",
" modems = {peripheral.find(\"modem\")}",
" for a = 1, #modems do",
" if modems[a].isWireless() then",
" modem = modems[a]",
" modem.open(channel)",
" return",
" end",
" end",
" modem = nil",
"end",
"",
"setModems()",
"if (not commands) and (not modem) then",
" return printError(\"You need a modem! Or a command computer!\")",
"end",
"if commands then isServer = true else isServer = false end",
"",
"if (not commands) and (not modem) then",
" error(\"This requires a command computer.\")",
"end",
"",
"local prefix = \"\"",
"local suffix = \"\"",
"",
"local dnb = function(phunk, ...)",
" local t,b = term.getTextColor(), term.getBackgroundColor()",
" local x,y = term.getCursorPos()",
" local output = {phunk(...)}",
" term.setCursorPos(x,y)",
" term.setTextColor(t)",
" term.setBackgroundColor(b)",
" return unpack(output)",
"end",
"",
"local prevnames = {}",
"",
"local colnames = {",
" [\"0\"] = \"black\",",
" [\"1\"] = \"dark_blue\",",
" [\"2\"] = \"dark_green\",",
" [\"3\"] = \"dark_aqua\",",
" [\"4\"] = \"dark_red\",",
" [\"5\"] = \"dark_purple\",",
" [\"6\"] = \"gold\",",
" [\"7\"] = \"gray\",",
" [\"8\"] = \"dark_gray\",",
" [\"9\"] = \"blue\",",
" [\"a\"] = \"green\",",
" [\"b\"] = \"aqua\",",
" [\"c\"] = \"red\",",
" [\"d\"] = \"light_purple\",",
" [\"e\"] = \"yellow\",",
" [\"f\"] = \"white\",",
"}",
"",
"local colors_names = { --for use with colors api, you see",
" [\"0\"] = colors.black,",
" [\"1\"] = colors.blue,",
" [\"2\"] = colors.green,",
" [\"3\"] = colors.cyan,",
" [\"4\"] = colors.red,",
" [\"5\"] = colors.purple,",
" [\"6\"] = colors.orange,",
" [\"7\"] = colors.lightGray,",
" [\"8\"] = colors.gray,",
" [\"9\"] = colors.blue, --they don't translate perfectly, okay??",
" [\"a\"] = colors.lime,",
" [\"b\"] = colors.lightBlue,",
" [\"c\"] = colors.red,",
" [\"d\"] = colors.magenta,",
" [\"e\"] = colors.yellow,",
" [\"f\"] = colors.white,",
"}",
"local codeNames = { --just for checking",
" [\"k\"] = \"obfuscate\",",
" [\"o\"] = \"italic\",",
" [\"l\"] = \"bold\",",
" [\"m\"] = \"strikethrough\",",
" [\"n\"] = \"underline\",",
" [\"r\"] = \"reset\",",
"}",
"",
"local filterColors = function(str,doprint)",
" local p = 1",
" local output = \"\"",
" local code = \"&\"",
" local col = \"f\"",
" local prevT,prevB = term.getTextColor(), term.getBackgroundColor()",
" while p <= #str do",
" if str:sub(p,p) == code then",
" if colors_names[str:sub(p+1,p+1)] then",
" col = str:sub(p+1,p+1)",
" p = p + 1",
" elseif codeNames[str:sub(p+1,p+1)] then",
" if str:sub(p+1,p+1) == \"r\" then",
" col = \"f\"",
" end",
" p = p + 1",
" else",
" if doprint then",
" if term.isColor() then",
" term.setTextColor(colors_names[col])",
" end",
" write(str:sub(p,p))",
" end",
" end",
" p = p + 1",
" else",
" output = output..str:sub(p,p)",
" if doprint then",
" if term.isColor() then",
" term.setTextColor(colors_names[col])",
" end",
" write(str:sub(p,p))",
" end",
" p = p + 1",
" end",
" end",
" term.setTextColor(prevT)",
" term.setBackgroundColor(prevB)",
" return output",
"end",
"",
"local renderReadBar = function(doReturn)",
" local cx,cy = term.getCursorPos()",
" local cb,ct = term.getBackgroundColor(), term.getTextColor()",
" term.setCursorPos(1,scr_y)",
" term.setBackgroundColor(colors.black)",
" term.clearLine()",
" filterColors(prefix..\"&r\"..names[cname].prefix..\"&r\"..names[cname].name..\"&r\"..names[cname].suffix..\"&r\"..suffix,true)",
" term.setCursorPos(1,scr_y-1)",
" if not doReturn then",
" term.setBackgroundColor(colors.gray)",
" term.clearLine()",
" term.setTextColor(colors.white)",
" else",
" term.setCursorPos(cx,cy)",
" term.setBackgroundColor(cb)",
" term.setTextColor(ct)",
" end",
"end",
"",
"local colorFormat = function(str)",
" local color = \"f\"",
" local obfuscated = false",
" local bold = false",
" local strikethrough = false",
" local underline = false",
" local italic = false",
" ",
" local code = \"&\" --ONE CHARACTER",
" local pos = 1",
" local opos = 1",
" local output = {}",
" ",
" while pos <= #str do",
" output[opos] = {}",
" if str:sub(pos,pos) == code and pos < #str then",
" local changed = false",
" if colnames[str:sub(pos+1,pos+1)] then",
" color = str:sub(pos+1,pos+1)",
" changed = true",
" else",
" if str:sub(pos+1,pos+1) == \"r\" then",
" color = \"f\"",
" obfuscated = false",
" bold = false",
" strikethrough = false",
" underline = false",
" italic = false",
" changed = true",
" end",
" if str:sub(pos+1,pos+1) == \"k\" then",
" obfuscated = true",
" changed = true",
" end",
" if str:sub(pos+1,pos+1) == \"l\" then",
" bold = true",
" changed = true",
" end",
" if str:sub(pos+1,pos+1) == \"m\" then",
" strikethrough = true",
" changed = true",
" end",
" if str:sub(pos+1,pos+1) == \"n\" then",
" underline = true",
" changed = true",
" end",
" if str:sub(pos+1,pos+1) == \"o\" then",
" italic = true",
" changed = true",
" end",
" end",
" if changed then",
" output[opos].text = \"\"",
" pos = pos + 2",
" else",
" output[opos].text = str:sub(pos,pos)",
" pos = pos + 1",
" end",
" else",
" output[opos].text = str:sub(pos,pos)",
" pos = pos + 1",
" end",
" output[opos].color = colnames[color]",
" output[opos].obfuscated = obfuscated",
" output[opos].bold = bold",
" output[opos].strikethrough = strikethrough",
" output[opos].underline = underline",
" output[opos].italic = italic",
" opos = opos + 1",
" end",
" return textutils.serialiseJSON(output)",
"end",
"",
"local players = { --Add playernames here if you want to filter who receives messages",
" \"dan200\",",
" \"EldidiStroyrr\",",
"}",
"",
"local doFilter = false --If true, filters according to 'players' table",
"",
"local send = function(name,msg,np,ns,realname,doprint)",
" local compiled --compiled message, not compiled program",
" local filtmsg = filterColors(msg)",
" if filtmsg:sub(1,3) == \"___\" then --should this be a client option? hmm...",
" if filtmsg == \"___join\" then",
" compiled = \"&e\"..filterColors(realname)..\" joined the game.\"",
" elseif filtmsg == \"___notjoin\" then",
" compiled = \"&e\"..filterColors(realname)..\" hasn't joined the game.\"",
" elseif filtmsg == \"___leave\" then",
" compiled = \"&e\"..filterColors(realname)..\" left the game.\"",
" elseif filtmsg == \"___notleave\" then",
" compiled = \"&e\"..filterColors(realname)..\" hasn't left the game.\"",
" elseif filtmsg:sub(1,8) == \"___medal\" then",
" compiled = realname..\"&r has made the achievement &a[\"..msg:sub(10)..\"&a]\"",
" else",
" compiled = msg:sub(4)",
" end",
" else",
" compiled = prefix..\"&r\"..np..\"&r\"..name..\"&r\"..ns..\"&r\"..suffix..\"&r\"..msg",
" end",
" compiled = colorFormat(compiled)",
" if doFilter then",
" for a = 1, #players do",
" commands.tellraw(players[a],compiled)",
" end",
" else",
" commands.tellraw(\"@a\",compiled)",
" end",
"end",
"",
"local netsend = function(n,m,p,s,mp,rn) --name, message, prefix, suffix",
" local data = {",
" name = n,",
" realname = rn or n,",
" msg = mp..m,",
" prefix = p or \"<\",",
" suffix = s or \"> \",",
" }",
" if modem then modem.transmit(channel,channel,data) end",
"end",
"",
"term.setBackgroundColor(colors.black)",
"term.clear()",
"term.setCursorPos(1,1)",
"local name",
"if tArg[1] then",
" name = tArg[1]",
" if name:gsub(\" \",\"\") ~= \"\" and prevnames[#prevnames] ~= name then",
" table.insert(prevnames,name)",
" end",
"else",
" print(\"Enter a name:\")",
" write(\">\")",
" dnb(function() write(\"\\n\\nUse PageUP and PageDOWN to switch names.\\nDo '/exit' to exit.\\nDo '___join' or '___leave' to simulate doing either.\\nPrefix any other message with '___' to do raw chat.\\n\\nUse responsibly\") if term.isColor() then print(\".\") else print(\", and it'd be preferable to use a golden computer. Not required, but...\") end end)",
" name = read(nil,prevnames)",
" if name:gsub(\" \",\"\") ~= \"\" and prevnames[#prevnames] ~= name then",
" table.insert(prevnames,name)",
" end",
"end",
"if name:gsub(\" \",\"\") == \"\" then name = \"Scabby cunt\" end --enter in a fucking name",
"table.insert(names,1,{",
" name = name,",
" prefix = \"<\",",
" suffix = \"> \",",
" realname = name",
"})",
"",
"local insend = function(n,m,p,s,mp,rn) --name, message, prefix, suffix. Sends a message inwards to simulate receiving a message from a client",
" local data = {",
" name = n,",
" realname = rn or n,",
" msg = mp..m,",
" prefix = p or \"<\",",
" suffix = s or \"> \",",
" }",
" os.queueEvent(\"modem_message\",\"top\",channel,channel,data,0)",
"end",
"",
"local client = function() --this is where you enter in your awesome messages! it also happens to be where *you* enter in your shitty messages",
" while true do",
" term.setBackgroundColor(colors.black) --dats rasist",
" term.clear()",
" renderReadBar()",
" write(\">\")",
" local msg = read(nil,sHistories[cname] or {\"I like to eat pubes I find in urinals.\",\"One of my hobbies is to kick small dogs and see how far they go.\",\"Have you reddit\",\"My child-sized skin suit it starting to smell.\"})",
" if msg:gsub(\" \",\"\") == \"/exit\" then",
" return",
" end",
" if msg:gsub(\" \",\"\") ~= \"\" then",
" if not sHistories[cname] then",
" sHistories[cname] = {msg}",
" else",
" if sHistories[cname][#sHistories[cname]] ~= msg then",
" sHistories[cname][#sHistories[cname]+1] = msg",
" end",
" end",
" end",
" if isServer then --if you are a command computer, fuck that netsend() function!!! that's for pussies!!",
" if msg:gsub(\" \",\"\") ~= \"\" then",
" local sdata = {",
" names[cname].name,",
" msg,",
" prefix..names[cname].prefix or \"<\",",
" suffix..names[cname].suffix or \"> \",",
" names[cname].msgprefix or \"\",",
" }",
" if type(names[cname].realname) == \"string\" then",
" table.insert(sdata,names[cname].realname)",
" end",
" insend(unpack(sdata))",
" end",
" else --if you're a client, studies have shown that you're the type of fuck who makes positive acronyms out of insults that are thrown your way",
" local sdata = {",
" names[cname].name,",
" msg,",
" prefix..names[cname].prefix or \"<\",",
" suffix..names[cname].suffix or \"> \",",
" names[cname].msgprefix or \"\",",
" }",
" if type(names[cname].realname) == \"string\" then",
" table.insert(sdata,names[cname].realname)",
" end",
" netsend(unpack(sdata))",
" end",
" end",
"end",
"",
"local renderHistory = function() --this shows all the latest and greatest (optional) messages sent by fakechat clients!",
" local y = scr_y-2",
" local r = \"&r\"",
" term.setBackgroundColor(colors.black)",
" for a = #sHistory, #sHistory-(scr_y-2), -1 do",
" if not sHistory[a] then break end",
" term.setCursorPos(1,y)",
" term.clearLine()",
" filterColors(sHistory[a].p..r..sHistory[a].n..r..sHistory[a].s..r..sHistory[a].m,true)",
" y = y - 1",
" end",
"end",
"",
"local server = function() --now THIS is what I call a quality function! servers are where it's at! *it* being command computers, of course...",
" while true do",
" local evt = {os.pullEvent(\"modem_message\")}",
" if type(evt[5]) == \"table\" then",
" local i = evt[5]",
" if type(i.name) == \"string\" and type(i.msg) == \"string\" and type(i.prefix) == \"string\" and type(i.suffix) == \"string\" and type(i.realname) == \"string\" then",
" table.insert(sHistory,{n=i.name, m=i.msg, p=i.prefix, s=i.suffix})",
" send( i.name, i.msg, i.prefix, i.suffix, i.realname, true)",
" dnb(function() return renderHistory() end)",
" end",
" end",
" end",
"end",
"",
"moreModems = function() --keep them modems loaded!",
" while true do",
" setModems()",
" sleep(0)",
" end",
"end",
"",
"switchNames = function() --in case you happen to be named harry kuntz, and want to change that right away",
" local evt, key, rerender",
" while true do",
" rerender = false",
" evt, key = os.pullEvent(\"key\")",
" if key == keys.pageUp then",
" cname = cname - 1",
" rerender = true",
" elseif key == keys.pageDown then",
" cname = cname + 1",
" rerender = true",
" end",
" if cname <= 0 then",
" cname = #names",
" elseif cname > #names then",
" cname = 1",
" end",
" if rerender then renderReadBar(true) end",
" end",
"end",
"",
"local funclist = { --this is the funciest list I've ever laid eyes upon",
" client,",
" moreModems,",
" switchNames,",
"}",
"if isServer then table.insert(funclist,server) end --clients are not servers, you thick idiot",
"",
"parallel.waitForAny(unpack(funclist)) --execute the SHIT out of this!",
"",
"term.setCursorPos(1,scr_y)",
"term.setBackgroundColor(colors.black)",
"term.clearLine() --the last line is always the hardest...*sniffle*",
},
[ "/util/tps.lua" ] = {
"--[[",
" Turtle Positioning System",
" Use two turtles as an expensive and crappy GPS server! Use ALL the fuel!",
"",
" pastebin get PsTiQ5eu startup",
" std PB PsTiQ5eu startup",
"--]]",
"",
"local chestX = 0 --fill this in!",
"local chestY = 0 --fill this in!",
"local chestZ = 0 --fill this in!",
"",
"local startx,starty,startz --if there isn't a file storing them",
"startx = 0",
"starty = 64",
"startz = 0",
"",
"local chest = true",
"",
"if not gps then --I love having comical error handling",
" return printError(\"GPS API wasn't found. Are you using an older version of ComputerCraft?\")",
"else",
" if type(gps) == \"table\" then",
" if not (gps.locate) then",
" return printError(\"gps.locate seems to be missing.\")",
" else",
" if type(gps.locate) == \"string\" then",
" return printError(\"Is this a joke? gps.locate is a string. This does knot make sense.\")",
" elseif type(gps.locate) == \"table\" then",
" return printError(\"What the... gps.locate is a table! Knock it off.\")",
" elseif type(gps.locate) == \"number\" then",
" return printError(\"Eh? gps.locate is a number! This doesn't ADD UP!\")",
" end",
" end",
" end",
"end",
"",
"local cfilename = \".coords\"",
"",
"local tArg = {...}",
"local modem = peripheral.find(\"modem\")",
"if not turtle then",
" if pocket then",
" return printError(\"Hey, what do you think you're doing!? Turtles only! No pocket computer servers!!\")",
" else",
" return printError(\"Um? This is a turtle program, you know?\")",
" end",
"end",
"if not modem then",
" local l = peripheral.wrap(\"right\")",
" local r = peripheral.wrap(\"left\")",
" if r and l then",
" return printError(\"Dangit, you messed up! Craft a WIRELESS turtle!\")",
" else",
" return printError(\"You need a wireless modem.\")",
" end",
"end",
"modem.open(gps.CHANNEL_GPS)",
"",
"local tew,tps",
"local requests = 0",
"local scr_x, scr_y = term.getSize()",
"",
"local fuels = {",
" [\"minecraft:coal\"] = 80,",
" [\"minecraft:coal_block\"] = 80*9,",
"}",
"",
"local dro = function(input)",
" return input % 4",
"end",
"",
"local fixNumber = function(num)",
" return math.floor(num+0.5)",
"end",
"",
"local getDist = function(x1,y1,z1,x2,y2,z2)",
" return math.abs(x2-x1)+math.abs(y2-y1)+math.abs(z2-z1)",
"end",
"",
"local directionNames = {",
" [0] = \"South\",",
" [1] = \"West\",",
" [2] = \"North\",",
" [3] = \"East\",",
"}",
"",
"local dudes = {}",
"",
"local total",
"--[[local sendRequests = function()",
" while true do",
" total = 0",
" getEvents(\"tew_move\",\"tew_receive\")",
" for k,v in pairs(dudes) do",
" if v > 0 then",
" modem.transmit( k, gps.CHANNEL_GPS, { tew.x, tew.y, tew.z } )",
" dudes[k] = dudes[k] - 1",
" requests = requests + 1",
" total = total + 1",
" end",
" end",
" tew.lock = (total == 0)",
" end",
"end--]]",
"",
"local sendRequest = function()",
" total = 0",
" for k,v in pairs(dudes) do",
" if v > 0 then",
" modem.transmit( k, gps.CHANNEL_GPS, { tew.x, tew.y, tew.z } )",
" dudes[k] = dudes[k] - 1",
" requests = requests + 1",
" total = total + 1",
" end",
" end",
" tew.lock = (total == 0)",
"end",
"local adjustCoords = function(dir, dist)",
" if dir == -1 then",
" tew.y = tew.y + 1",
" elseif dir == -2 then",
" tew.y = tew.y - 1",
" else",
" tew.x = fixNumber(tew.x - math.sin(math.rad(dir*90)))",
" tew.z = fixNumber(tew.z + math.cos(math.rad(dir*90)))",
" end",
" tps(true)",
"end",
"",
"local gotoCoords = function( gx, gy, gz )",
" if (gx == tew.x) and (gy == tew.y) and (gz == tew.z) then return end",
"",
" local cx,cy,cz = tew.x,tew.y,tew.z",
" ",
" while (gx ~= tew.x) or (gy ~= tew.y) or (gz ~= tew.z) do",
" ",
" for a = 1, math.abs(gy-cy) do",
" if tew.y == gy then break end",
" tew.lock = false",
" if gy > cy then",
" tew.up()",
" else",
" tew.down()",
" end",
" end",
" if tew.x ~= gx then",
" tew.lock = false",
" tew.turn(3)",
" for a = 1, math.abs(gx-cx) do",
" if tew.x == gx then break end",
" tew.lock = false",
" if gx > cx then",
" tew.forward()",
" else",
" tew.back()",
" end",
" end",
" end",
" if tew.z ~= gz then",
" tew.lock = false",
" tew.turn(0)",
" for a = 1, math.abs(gz-cz) do",
" if tew.z == gz then break end",
" tew.lock = false",
" if gz > cz then",
" tew.forward()",
" else",
" tew.back()",
" end",
" end",
" end",
" ",
" end",
"end",
"",
"local saveTheWhales = function() --HOPEFULLY the path is unobstructed by blocks",
" local bC = {",
" x = tew.x,",
" y = tew.y,",
" z = tew.z,",
" direction = tew.direction,",
" }",
" gotoCoords(chestX,((chestY>bC.y) and (chestY-1) or (chestY+1)),chestZ)",
" for a = 1, 16 do",
" if turtle.inspectUp() then",
" turtle.suckUp()",
" elseif turtle.inspectDown() then",
" turtle.suckDown()",
" elseif turtle.inspect() then",
" turtle.suck()",
" end",
" end",
" gotoCoords(bC.x,bC.y,bC.z)",
" tew.lock = false",
" tew.turn(bC.direction)",
"end",
"",
"local checkIfCanFuel = function()",
" local currentSlot = turtle.getSelectedSlot()",
" for a = 1, 16 do",
" local item = turtle.getItemDetail(a)",
" if item then",
" if fuels[item.name] then",
" return true",
" end",
" end",
" end",
" return false",
"end",
"",
"local doRefuel = function()",
" while true do",
" local currentSlot = turtle.getSelectedSlot()",
" for a = 1, 16 do",
" local item = turtle.getItemDetail(a)",
" if item then",
" if fuels[item.name] then",
" turtle.select(a)",
" turtle.refuel(1)",
" turtle.select(currentSlot)",
" term.setCursorPos(1,scr_y)",
" term.clearLine()",
" return true",
" end",
" end",
" end",
" sleep(0) --INSERT MORE FUEL!",
" term.setCursorPos(1,scr_y)",
" term.write(\"Insert more fuel!!\")",
" end",
" return false",
"end",
"",
"local handleFuel = function(chest)",
" if type(turtle.getFuelLevel()) == \"number\" then",
" if chest and (not checkIfCanFuel()) then",
" local dist = getDist(tew.x,tew.y,tew.z,chestX,chestY,chestZ)",
" if dist+10 > turtle.getFuelLevel() then --gives me some leeway",
" saveTheWhales() --PANIC",
" doRefuel()",
" end",
" end",
" if turtle.getFuelLevel() == 0 then",
" doRefuel()",
" end",
" else",
" return true",
" end",
"end",
"",
"-- 'tew' is a reproduction of the turtle API, but tracked and written to a file located at cfilename (default: \"/.coords\")",
"",
"tew = { --already localized",
" lock = false,",
" direction = 0,",
" x = startx,",
" y = starty,",
" z = startz,",
" forward = function(dist,doFuelThing)",
" local success, msg",
" for a = 1, dist or 1 do",
" if tew.lock then repeat sleep(0) until not tew.lock end",
" handleFuel(doFuelThing)",
" success, msg = turtle.forward()",
" if success then",
" adjustCoords(dro(tew.direction),1)",
" --os.queueEvent(\"tew_move\")",
" sendRequest()",
" else",
" return success, msg",
" end",
" end",
" return true",
" end,",
" back = function(dist,doFuelThing)",
" local success, msg",
" for a = 1, dist or 1 do",
" if tew.lock then repeat sleep(0) until not tew.lock end",
" handleFuel(doFuelThing)",
" success, msg = turtle.back()",
" if success then",
" adjustCoords(dro(tew.direction+2),1)",
" --os.queueEvent(\"tew_move\")",
" sendRequest()",
" else",
" return success, msg",
" end",
" end",
" return true",
" end,",
" up = function(dist,doFuelThing)",
" local success, msg",
" for a = 1, dist or 1 do",
" if tew.lock then repeat sleep(0) until not tew.lock end",
" handleFuel(doFuelThing)",
" success, msg = turtle.up()",
" if success then",
" adjustCoords(-1,1)",
" --os.queueEvent(\"tew_move\")",
" sendRequest()",
" else",
" return success, msg",
" end",
" end",
" return true",
" end,",
" down = function(dist,doFuelThing)",
" local success, msg",
" for a = 1, dist or 1 do",
" if tew.lock then repeat sleep(0) until not tew.lock end",
" handleFuel(doFuelThing)",
" success, msg = turtle.down()",
" if success then",
" adjustCoords(-2,1)",
" --os.queueEvent(\"tew_move\")",
" sendRequest()",
" else",
" return success, msg",
" end",
" end",
" return true",
" end,",
" turnRight = function(times,doFuelThing)",
" handleFuel(doFuelThing)",
" for a = 1, times or 1 do",
" if tew.lock then repeat sleep(0) until not tew.lock end",
" turtle.turnRight()",
" tew.direction = dro(tew.direction+1)",
" tps(true)",
" end",
" return true",
" end,",
" turnLeft = function(times,doFuelThing)",
" handleFuel(doFuelThing)",
" for a = 1, times or 1 do",
" if tew.lock then repeat sleep(0) until not tew.lock end",
" turtle.turnRight()",
" tew.direction = dro(tew.direction+1)",
" tps(true)",
" end",
" return true",
" end,",
" turn = function(dir)",
" if dir == tew.direction then return true end",
" repeat",
" tew.turnRight()",
" until tew.direction == dir",
" return true",
" end",
"}",
"",
"tps = function( doWrite )",
" if doWrite then",
" local file = fs.open(cfilename,\"w\")",
" file.write(tew.x..\"\\n\"..tew.y..\"\\n\"..tew.z..\"\\n\"..tew.direction..\"\\n\"..chestX..\"\\n\"..chestY..\"\\n\"..chestZ)",
" file.close()",
" else",
" if not fs.exists(cfilename) then tps(true) end",
" local file = fs.open(cfilename,\"r\")",
" tew.x = tonumber(file.readLine())",
" tew.y = tonumber(file.readLine())",
" tew.z = tonumber(file.readLine())",
" tew.direction = tonumber(file.readLine())",
" chestX = tonumber(file.readLine())",
" chestY = tonumber(file.readLine())",
" chestZ = tonumber(file.readLine())",
" file.close()",
" end",
"end",
"",
"tps(false)",
"tew.lock = true",
"",
"local doTurtleMove = function()",
" while true do",
" tew.forward( 1,true)",
" tew.turnRight( 1,true)",
" tew.forward( 1,true)",
" tew.up( 1,true)",
" tew.turnRight( 1,true)",
" tew.forward( 1,true)",
" tew.turnRight( 1,true)",
" tew.forward( 1,true)",
" tew.down( 1,true)",
" tew.turnRight( 1,true)",
" end",
"end",
"",
"local handleRequests = function() --also handles manual exit",
" local evt, side, chan, repchan, message, distance",
" while true do",
" evt, side, chan, repchan, message, distance = os.pullEvent()",
" if evt == \"modem_message\" then",
" if (chan == gps.CHANNEL_GPS) and (message == \"PING\") then",
" dudes[repchan] = 4",
" --os.queueEvent(\"tew_receive\")",
" sendRequest()",
" end",
" elseif evt == \"key\" then",
" if side == keys.x then",
" return",
" end",
" end",
" end",
"end",
"",
"local getEvents = function(...)",
" local evt",
" while true do",
" evt = {os.pullEvent()}",
" for a = 1, #arg do",
" if arg[a] == evt[1] then",
" return unpack(evt)",
" end",
" end",
" end",
"end",
"",
"local colClearLine = function(col,y,char)",
" local cbg,ctxt,cx,cy = term.getBackgroundColor(), term.getTextColor(), term.getCursorPos()",
" local scr_x,scr_y = term.getSize()",
" term.setCursorPos(1,y or cy)",
" term.setBackgroundColor(col or cbg)",
" term.write((char or \" \"):rep(scr_x))",
" term.setBackgroundColor(cbg)",
" term.setTextColor(ctxt)",
" term.setCursorPos(cx,cy)",
"end",
"",
"local prettyPrint = function(left,right)",
" local ctxt = term.getTextColor()",
" term.setTextColor(term.isColor() and colors.yellow or colors.lightGray)",
" write(left)",
" term.setTextColor(ctxt)",
" print(right)",
"end",
"",
"local displayData = function()",
" while true do",
" term.clear()",
" term.setCursorPos(1,1)",
" colClearLine(colors.gray)",
" prettyPrint(\"\\nFuel: \",turtle.getFuelLevel())",
" prettyPrint(\"X/Y/Z: \",tew.x..\"/\"..tew.y..\"/\"..tew.z)",
" prettyPrint(\"Direction: \",tew.direction..\" (\"..directionNames[tew.direction]..\")\")",
" prettyPrint(\"Requests: \",requests)",
" colClearLine(colors.gray)",
" print(\"\\nPress 'X' to exit.\")",
" sleep(0)",
" end",
"end",
"",
"local displayHelp = function()",
" local data = [[",
"Turtle GPS System (TPS)",
"by LDDestroier/EldidiStroyrr",
" Place a chest down, and fill it with fuel.",
" Place the turtle down (you did), and specify its own coordinates ('1') and the chest coordinates ('2').",
" Start!]]",
" print(data)",
" sleep(0.1)",
" os.pullEvent(\"key\")",
"end",
"",
"--[[local t = peripheral.find(\"turtle\") --this was for an easier setup with a specific pattern",
"if t then",
" t.turnOn()",
" tew.turnRight()",
" tew.forward(2)",
" tew.turnRight()",
"end--]]",
"",
"local okaythen = false",
"while not okaythen do",
" term.clear()",
" term.setCursorPos(1,1)",
" print()",
" print(\"Push '1' to change coordinates...\")",
" print(\"Push '2' to change chest coordinates...\")",
" print(\"Push 'X' to cancel...\")",
" print(\"Push 'Spacebar' to start immediately...\")",
" local _x,_y = term.getCursorPos()",
" local buttmode = 0",
" local res = parallel.waitForAny(function()",
" while true do",
" local _,char = os.pullEvent(\"char\")",
" if char:lower() == \"1\" then",
" buttmode = 1",
" return",
" elseif char:lower() == \"2\" then",
" buttmode = 2",
" return",
" elseif char:lower() == \" \" then",
" okaythen = true",
" return",
" elseif char:lower() == \"x\" then",
" buttmode = -1",
" return",
" end",
" end",
" end,function()",
" for a = 1, 3*10 do",
" term.setCursorPos(_x,_y)",
" term.write(\"Starting in \"..(3-(a/10))..\" seconds...\")",
" sleep(0.1)",
" end",
" end)",
" ",
" if res == 1 then",
" term.clear()",
" term.setCursorPos(1,1)",
" if buttmode == 1 then",
" print(\"Turtle position input.\")",
" colClearLine(colors.white)",
" write(\"\\nX: \")",
" tew.x = tonumber(read()) or tew.x",
" write(\"Y: \")",
" tew.y = tonumber(read()) or tew.y",
" write(\"Z: \")",
" tew.z = tonumber(read()) or tew.z",
" print(\"Direction (F3 -> 'f'): \")",
" for k,v in pairs(directionNames) do",
" print(\" \"..k..\" = '\"..v..\"'\")",
" end",
" write(\">\")",
" tew.direction = tonumber(read()) or tew.direction",
" tps(true)",
" elseif buttmode == 2 then",
" print(\"Refuel Chest input.\")",
" colClearLine(colors.white)",
" write(\"\\nChest X: \")",
" chestX = tonumber(read()) or chestX",
" write(\"Chest Y: \")",
" chestY = tonumber(read()) or chestY",
" write(\"Chest Z: \")",
" chestZ = tonumber(read()) or chestZ",
" tps(true)",
" elseif buttmode == -1 then",
" print(\"Cancelled.\")",
" error()",
" end",
" else",
" okaythen = true",
" end",
"end",
"",
"parallel.waitForAny(handleRequests,doTurtleMove,displayData) --,sendRequests) --everything's okay, then",
"",
"term.setCursorPos(1,scr_y-2)",
"print(\"Thank you for using TPS!\")",
"sleep(0)",
},
[ "/game/data/sprites/megaman/walk4.nft" ] = {
"  bf‡ƒf3›„",
"  3f—bb€03fŒfb…",
"  3f‡f3–0b•0€fŠf0•",
"  f3Šbf›3f‰f0Œ†",
"  fb‹bfˆƒ3”f3‡bŽ",
"  fb‚3f†f3•…",
"  bf—b€f",
"  fbƒƒ",
},
[ "/game/data/sprites/stickdude/stand2.nft" ] = {
"0f0€f”",
"‹Ÿ",
"  f0•",
"˜‰",
"•  f0•",
},
[ "/game/data/sprites/megaman/walkshoot4.nft" ] = {
"  bf‡ƒf3›„",
"  3f—bb€03fŒfb…",
"  3f‡f3–0b•0€fŠf0•3fb—ƒf3",
"  f3Šbf›3f‰f0Œ†3ŽbŠ",
"  fb‹bfˆƒ3”f3‡",
"  fb‚3f†f3•…",
"  bf—b€f",
"  fbƒƒ",
},
[ "/util/ports.lua" ] = {
"-- pastebin get XxkBiYJ6 ports",
"-- std pb XxkBiYJ6 ports",
"function getOpenChannels()",
" modemChannels = {}",
" sides = peripheral.getNames()",
" modemSides = {}",
" modemRednetSides = {}",
" for a = 1, #sides do",
" if peripheral.getType(sides[a]) == \"modem\" then",
" table.insert(modemSides, sides[a])",
" if rednet.isOpen(sides[a]) then",
" table.insert(modemRednetSides, sides[a])",
" end",
" end",
" end",
" for a = 1, #modemSides do",
" if not oldPeripheralWrap then",
" modem = peripheral.wrap(modemSides[a])",
" else",
" modem = oldPeripheralWrap(modemSides[a])",
" end",
" channels = {}",
" for b = 1, 65535 do",
" if modem.isOpen(b) then",
" table.insert(modemChannels, b)",
" end",
" end",
" end",
"end",
"",
"function printChannels()",
" print(\"ID: \" .. os.getComputerID())",
" write(\"Open channels:\")",
" if isLocked then",
" print(\" LOCKED\")",
" else",
" print(\"\")",
" end",
" if modemChannels ~= nil then",
" for a = 1, #modemChannels do",
" if modemChannels[a] == rednet.CHANNEL_BROADCAST then",
" print(\" Rednet \" .. modemChannels[a])",
" else",
" print(\" Modem \" .. modemChannels[a])",
" end",
" end",
" else",
" print(\" none!\")",
" end",
"end",
"",
"tArg = {...}",
"",
"command = tArg[1]",
"argument1 = tArg[2]",
"argument2 = tArg[3]",
"argument3 = tArg[4]",
"",
"getOpenChannels()",
"",
"if not command then",
" getOpenChannels()",
" printChannels()",
" return",
"elseif command == \"open\" then",
" if tonumber(argument1) == nil then",
" success = false",
" for a = 1, #modemSides do",
" if modemSides[a] == argument1 then",
" success = true",
" end",
" end",
" if argument1 == nil then",
" error(\"no side given\")",
" end",
" if success == true then",
" rednet.open(argument1)",
" print(\"Opened side \" .. argument1 .. \" on rednet\")",
" else",
" error(\"modem \" .. argument1 .. \" not found\")",
" end",
" else",
" argument1 = tonumber(argument1)",
" if argument1 <= 0 or argument1 > 65535 then",
" error(\"channel '\" .. argument1 .. \"' not good\")",
" else",
" modem.open(argument1)",
" print(\"Opened channel \" .. argument1)",
" end",
" end",
"elseif command == \"close\" then",
" if tonumber(argument1) == nil then",
" success = false",
" if argument1 == \"*\" then",
" modem.closeAll()",
" print(\"All channels closed.\")",
" else",
" for a = 1, #modemSides do",
" if modemSides[a] == argument1 then",
" success = true",
" end",
" end",
" if argument1 == nil then",
" error(\"no side given\")",
" end",
" if success == true then",
" rednet.close(argument1)",
" print(\"Closed side '\" .. argument1 .. \"' on rednet\")",
" else",
" error(\"modem '\" .. argument1 .. \"' not found\")",
" end",
" end",
" else",
" argument1 = tonumber(argument1)",
" if argument1 <= 0 or argument1 > 65535 then",
" error(\"channel \" .. argument1 .. \" not good\")",
" else",
" modem.close(argument1)",
" print(\"Closed channel \" .. argument1)",
" end",
" end",
"elseif command == \"lock\" then",
" if not isLocked then",
" oldOpenChannelList = modemChannels",
" for a = 1, #modemSides do",
" modem = peripheral.wrap(modemSides[a])",
" modem.closeAll()",
" end",
" modem = nil",
" oldRednetSend = rednet.send",
" oldRednetBroadcast = rednet.broadcast",
" oldPeripheralWrap = peripheral.wrap",
" oldPeripheralFind = peripheral.find",
" oldPeripheralCall = peripheral.call",
" oldRednetLookup = rednet.lookup",
" oldRednetHost = rednet.host",
" oldRednetUnhost = rednet.unhost",
" peripheral.wrap = function(object)",
" if peripheral.getType(object) == \"modem\" then",
" return nil",
" else",
" return oldPeripheralWrap(object)",
" end",
" end",
" peripheral.find = function(object)",
" if object == \"modem\" then",
" return nil",
" else",
" return oldPeripheralFind(object)",
" end",
" end",
" peripheral.call = function(...)",
" arg = {...}",
" if peripheral.getType(arg[1]) == \"modem\" then",
" return nil",
" else",
" return oldPeripheralCall(...)",
" end",
" end",
" rednet.send = function(id, contents, protocol)",
" return nil",
" end",
" rednet.broadcast = function(contents, protocol)",
" return nil",
" end",
" rednet.lookup = function(protocol, hostname)",
" return nil",
" end",
" rednet.host = function(protocol, hostname)",
" return nil",
" end",
" rednet.unhost = function(protocol, hostname)",
" return nil",
" end",
" _G.peripheral.wrap = peripheral.wrap",
" _G.peripheral.find = peripheral.find",
" _G.peripheral.call = peripheral.call",
" _G.rednet.send = rednet.send",
" _G.rednet.broadcast = rednet.broadcast",
" _G.rednet.lookup = rednet.lookup",
" _G.rednet.host = rednet.host",
" _G.rednet.unhost = rednet.unhost",
" isLocked = true",
" print(\"Modem communication is LOCKED.\")",
" else",
" rednet.send = oldRednetSend",
" rednet.broadcast = oldRednetBroadcast",
" peripheral.wrap = oldPeripheralWrap",
" peripheral.find = oldPeripheralFind",
" peripheral.call = oldPeripheralCall",
" rednet.lookup = oldRednetLookup",
" rednet.host = oldRednetHost",
" rednet.unhost = oldRednetUnhost",
" _G.peripheral.wrap = peripheral.wrap",
" _G.peripheral.find = peripheral.find",
" _G.peripheral.call = peripheral.call",
" _G.rednet.send = rednet.send",
" _G.rednet.broadcast = rednet.broadcast",
" _G.rednet.lookup = rednet.lookup",
" _G.rednet.host = rednet.host",
" _G.rednet.unhost = rednet.unhost",
" isLocked = false",
" modem = peripheral.find(\"modem\")",
" for a = 1, #oldOpenChannelList do",
" modem.open(oldOpenChannelList[a])",
" end",
" modem = nil",
" print(\"Modem communication is UNLOCKED.\")",
" end",
"elseif command == \"listen\" or command == \"receive\" then",
" modem = peripheral.find(\"modem\")",
" if not modem then",
" error(\"No modem to listen from!\")",
" end",
" if not argument1 then",
" argument1 = rednet.CHANNEL_BROADCAST",
" end",
" write(\"Listening on port \"..argument1)",
" if tonumber(argument2) then",
" print(\" for \"..argument2..\" sec...\")",
" else",
" print(\"...\")",
" end",
" if argument1 == \"rednet\" then",
" modem.open(rednet.CHANNEL_BROADCAST)",
" event, modemSide, senderChannel, replyChannel, message, senderDistance = os.pullEvent(\"modem_message\")",
" else",
" modem.open(tonumber(argument1))",
" event, modemSide, senderChannel, replyChannel, message, senderDistance = os.pullEvent(\"modem_message\")",
" end",
" if event then",
" print(\"msg: '\"..message..\"'\")",
" print(\"senderID: \"..senderChannel)",
" print(\"replyChannel: \"..replyChannel)",
" print(\"distance: \"..senderDistance)",
" else",
" print(\"Nothing...\")",
" end",
"elseif command == \"send\" then",
" modem = peripheral.find(\"modem\")",
" if not modem then",
" error(\"Get a modem!\")",
" end",
" if not argument1 then",
" error(\"No message!\")",
" end",
" if not argument2 then",
" argument2 = rednet.CHANNEL_BROADCAST",
" end",
" if not argument3 then",
" argument3 = rednet.CHANNEL_REPEAT",
" end",
" modem.open(tonumber(argument2))",
" modem.transmit(tonumber(argument2),tonumber(argument3),argument1)",
" print(\"Sent '\"..argument1..\"' on channel \"..argument2..\" (reply:\"..argument3..\")\")",
"else",
" print(\"//ports// - modem tool\")",
" print(\"Syntax:\")",
" print(\" 'ports'\")",
" print(\" 'ports [open/close] <sideName>'\")",
" print(\" 'ports [open/close] <channelNum>'\")",
" print(\" 'ports lock'\")",
" print(\" 'ports send <message> [channel] [replyChannel]\")",
" print(\" 'ports receive'\")",
"end",
},
[ "/game/data/sprites/megaman/teleport2.nft" ] = {
"",
"",
"",
"",
"",
"",
"",
"  bfŸ3ƒƒ‹",
"b‹bf3b…b33bŸ”ŠfŸ‡",
"  3bœb3‹…3bb3Š“",
"  fb‚ƒƒƒƒƒ3ƒb",
},
[ "/game/data/sprites/megaman/jumpthrow.nft" ] = {
"bf‡‹  bf‡ƒf3›„",
"b‹bfŠ‹3—bb€03fŒfb…",
"  fb‚bff3–0b•0€fŠf0•3fbŸfbž",
"  3f”‰0˜f€3f3žbŠbfŠ",
"  33€€€€",
"  3bb€€3‡b3Ÿ",
"  33€f—  bf”b€f‹",
"  bf‚  fbƒƒ",
"  bf•b€",
"  fb‚ƒ",
},
[ "/util/pain.lua" ] = {
"--[[",
" PAIN image editor for ComputerCraft",
" Get it with",
" wget https://raw.githubusercontent.com/LDDestroier/CC/master/pain.lua pain",
" pastebin get wJQ7jav0 pain",
" std ld pain pain",
"--]]",
"local askToSerialize = false",
"local defaultSaveFormat = 4 -- will change if importing image, or making new file with extension in name",
"--[[",
" defaultSaveFormat possible parameters:",
" 1. NFP (paint)",
" 2. NFT (npaintpro)",
" 3. BLT (blittle)",
" 4. Native PAIN",
" 5. GIF",
" 6. UCG",
"--]]",
"",
"local progname = fs.getName(shell.getRunningProgram())",
"local apipath = \".painapi\"",
"",
"local painconfig = {",
" undoBufferSize = 8, -- amount of times undo will save your neck",
" readNonImageAsNFP = true, -- reads non-image files as NFP images",
" useFlattenGIF = true, -- will flatten compressed GIFs",
" gridBleedThrough = false, -- will draw grid instead of character value of dots",
" doFillDiagonal = false, -- checks for diagonal dots when using fill tool",
" doFillAnimation = false, -- whether or not to animate the fill tool",
"}",
"",
"local saveConfig = function()",
" local file = fs.open(fs.combine(apipath,\"painconfig\"), \"w\")",
" file.write(textutils.serialize(painconfig))",
" file.close()",
"end",
"",
"local loadConfig = function()",
" if fs.exists(fs.combine(apipath,\"painconfig\")) then",
" local file = fs.open(fs.combine(apipath,\"painconfig\"), \"r\")",
" painconfig = textutils.unserialize(file.readAll())",
" file.close()",
" end",
"end",
"",
"loadConfig()",
"saveConfig()",
"",
"local displayHelp = function()",
" print(progname)",
" print(progname..\" <filename>\")",
" print(progname..\" [-h/--help]\")",
" print(\"Press F1 in program for more.\")",
"end",
"",
"local tsv = term.current().setVisible",
"local undoBuffer",
"local undoPos = 1",
"local pMode = 0",
"local scr_x, scr_y = term.getSize()",
"screenEdges = {",
" scr_x,",
" scr_y,",
"}",
"",
"local tArg = {...}",
"if (tArg[1] == \"--help\" or tArg[1] == \"-h\") and shell then",
" return displayHelp()",
"end",
"",
"if tArg[2] == \"view\" then",
" pMode = 1",
"elseif (tArg[2] == \"moo\") and (not fs.exists(\"moo\")) then",
" return print(\"This PAIN does not have Super Cow Powers.\")",
"end",
"",
"local fileName",
"if (not term.isColor()) and (pMode ~= 1) then",
" error(\"PAIN only works with Advanced Computers at the moment.\")",
"end",
"local barmsg = \"Press F1 for help.\"",
"local tse = textutils.serialise",
"local tun = textutils.unserialise",
"local paintEncoded",
"local lastPaintEncoded",
"local frame = 1",
"local doRender = false",
"local metaHistory = {}",
"local bepimode = false -- this is a family-friendly program! now stand still while I murder you",
"local evenDrawGrid = true -- will you evenDraw(the)Grid ?",
"local renderBlittle = false -- whether or not to render all in blittle",
"local firstTerm, blittleTerm = term.current()",
"local firstBG = term.getBackgroundColor()",
"local firstTX = term.getTextColor()",
"local changedImage = false",
"local isCurrentlyFilling = false",
"local theClipboard = {}",
"",
"local _",
"local tableconcat = table.concat",
"",
"local rendback = {",
" b = colors.black,",
" t = colors.gray,",
"}",
"",
"local grid",
"",
"local yield = function()",
" os.queueEvent(\"yield\")",
" os.pullEvent(\"yield\")",
"end",
"",
"local paint = {",
" scrollX = 0,",
" scrollY = 0,",
" t = colors.gray,",
" b = colors.white,",
" m = 1, -- in case you want to use PAIN as a level editor or something",
" c = \" \",",
" doGray = false,",
"}",
"local boxchar = {topLeft = true, topRight = true, left = true, right = true, bottomLeft = true, bottomRight = true}",
"local swapColors = false -- swaps background and text colors, for use with those tricky box characters",
"local scrollX, scrollY = 0, 0",
"",
"local keysDown = {}",
"local miceDown = {}",
"",
"local doRenderBar = 1 -- Not true or false",
"",
"local fixstr = function(str)",
" return str:gsub(\"\\\\(%d%d%d)\",string.char)",
"end",
"",
"local choice = function(input,breakkeys,returnNumber)",
" local fpos = 0",
" repeat",
" event, key = os.pullEvent(\"key\")",
" if type(key) == \"number\" then key = keys.getName(key) end",
" if key == nil then key = \" \" end",
" if type(breakkeys) == \"table\" then",
" for a = 1, #breakkeys do",
" if key == breakkeys[a] then",
" return \"\"",
" end",
" end",
" end",
" fpos = string.find(input, key)",
" until fpos",
" return returnNumber and fpos or key",
"end",
"local explode = function(div,str)",
" if (div=='') then return false end",
" local pos,arr = 0,{}",
" for st,sp in function() return string.find(str,div,pos,true) end do",
" arr[#arr+1] = str:sub(pos,st-1)",
" pos = sp + 1",
" end",
" arr[#arr+1] = str:sub(pos)",
" return arr",
"end",
"",
"local cutString = function(max_line_length, str) -- from stack overflow",
" local lines = {}",
" local line",
" str:gsub('(%s*)(%S+)',",
" function(spc, word)",
" if not line or #line + #spc + #word > max_line_length then",
" lines[#lines+1] = line",
" line = word",
" else",
" line = line..spc..word",
" end",
" end",
" )",
" lines[#lines+1] = line",
" return lines",
"end",
"",
"local getDrawingCharacter = function(topLeft, topRight, left, right, bottomLeft, bottomRight) -- thank you oli414",
" local data = 128",
" if not bottomRight then",
" data = data + (topLeft and 1 or 0)",
" data = data + (topRight and 2 or 0)",
" data = data + (left and 4 or 0)",
" data = data + (right and 8 or 0)",
" data = data + (bottomLeft and 16 or 0)",
" else",
" data = data + (topLeft and 0 or 1)",
" data = data + (topRight and 0 or 2)",
" data = data + (left and 0 or 4)",
" data = data + (right and 0 or 8)",
" data = data + (bottomLeft and 0 or 16)",
" end",
" return {char = string.char(data), inverted = bottomRight}",
"end",
"",
"local cutUp = function(len,tbl)",
" local output = {}",
" local e = 0",
" local s",
" for a = 1, #tbl do",
" if #(tbl[a]:gsub(\" \",\"\")) == 0 then",
" s = {\"\"}",
" else",
" s = cutString(len,tbl[a])",
" end",
" for b = 1, #s do",
" output[#output+1] = s[b]",
" end",
" end",
" return output",
"end",
"",
"local getEvents = function(...)",
" local arg, output = table.pack(...)",
" while true do",
" output = {os.pullEvent()}",
" for a = 1, #arg do",
" if type(arg[a]) == \"boolean\" then",
" if doRender == arg[a] then",
" return {}",
" end",
" elseif output[1] == arg[a] then",
" return unpack(output)",
" end",
" end",
" end",
"end",
"",
"",
"",
"local sanitize = function(sani,tize)",
" local _,x = string.find(sani,tize)",
" if x then",
" return sani:sub(x+1)",
" else",
" return sani",
" end",
"end",
"local ro = function(input, max)",
" return math.floor(input % max)",
"end",
"",
"local guiHelp = function(inputText)",
" term.redirect(firstTerm)",
" scr_x, scr_y = term.current().getSize()",
" local _helpText = inputText or [[",
"",
"'PAIN' super-verbose help page",
" Programmed by LDDestroier",
"",
"(use UP/DOWN or scrollwheel, exit with Q)",
"If you wish to use PAIN to its fullest, read everything here.",
"You'll be image-editing like a pro in no time flat.",
"",
"Syntax:",
">pain <filename> [view] [x] [y]",
">pain [-n]",
">pain [-h/--help]",
"",
"[view]: renders the image once (optionally scrolling with [x] and [y])",
"\"-n\" or no arguments: Create new document, declare name upon saving",
"\"-h\" or \"--help\": Display short syntax help",
"",
"You can see what colors are selected based on the word \"PAIN\" on the hotbar.",
"",
"Hotkeys:",
" left/right ctrl: Toggle the menu",
"",
" left click:",
" +left shift = Drag and let go to draw a line",
" -alone = Place a dot",
"",
" Right Click: delete pixel",
"",
" Middle Click, or \"T\": Place text down with current colors; cancel with X",
"",
" \"Z\":",
" +LeftAlt = Redo",
" -alone = Undo",
"",
" \"P\": Pick colors from position onscreen; cancel with X",
"",
" \"N\":",
" +LeftShift = Change character to that of a special character",
" -alone = Change box character for drawing",
" (cancel with CTRL, N, or by clicking outside)",
"",
" \"[\" or mouse scroll down:",
" +LeftShift = Change to previous text color",
" -alone = Change to previous background color",
"",
" \"]\" or mouse scroll up:",
" +LeftShift = Change to next text color",
" -alone = Change to next background color",
"",
" \"F1\":",
" -alone = Access help screen",
"",
" \"F3:\"",
" -alone = View all connected monitors",
"",
" Spacebar:",
" +LeftShift = Toggle background grid",
" -alone = Toggle bar visibility",
"",
" Arrow keys:",
" +LeftShift = Displaces the entire frame",
" +Tab = Moves canvas one pixel at a time",
" -alone = Looks around the canvas smoothly",
"",
" \"+\" (or equals):",
" +LeftAlt = Swap the current frame with the next frame",
" +LeftShift = Merge the current frame atop the next frame",
" +RightShift = If you are making a new frame, duplicates the last frame",
" -alone = Change to next frame",
"",
" \"-\":",
" +LeftAlt = Swap the current frame with the previous frame",
" +LeftShift = Merge the current frame atop the previous frame",
" -alone = Change to previous frame",
"",
" (oh good, you're actually reading this stuff)",
"",
" \"A\": Set the coordinates to 0,0",
"",
" \"N\": Open block character selection",
"",
" \"B\": Toggle redirect to blittle, to preview in teletext characters",
"",
" \"c\":",
" +LeftAlt = Select region to copy to specified clipboard",
" -alone = Input coordinates to scroll over to",
"",
" \"LeftAlt + X\": Select region to cut to specified clipboard",
"",
" \"LeftAlt + X\": Pastes from specified clipboard",
"",
" \"G\": toggle grayscale mode.",
" Everything is in shades of gray.",
" If you Save, it saves in grayscale.",
"",
" \"F\":",
" +LeftShift = fill all empty pixels with background color and selected box character",
" -alone = activate fill tool - click anywhere to fill with color",
"",
" \"M\": set metadata for pixels (for game makers, otherwise please ignore)",
"",
"==================================",
" Thy Menu (accessible with CTRL):",
"==================================",
"",
" Left click on a menu item to select it.",
" If you click on the menubar, release on an option to select it.",
"",
" \"File > Save\"",
" Saves all frames to a specially formatted PAIN paint file. The format PAIN uses is very inefficient despite my best efforts, so Export if you don't use text or multiple frame.",
"",
" \"File > Save As\"",
" Same as \"File > Save\", but you change the filename.",
"",
" \"File > Export\"",
" Exports current frame to NFP, NFT, BLT, or the horribly inefficient PAIN format.",
"",
" \"File > Open\"",
" Opens up a file picker for you to change the image currently being edited.",
"",
" \"Edit > Delete Frame\"",
" Deletes the current frame. Tells you off if you try to delete the only frame.",
"",
" \"Edit > Clear\"",
" Deletes all pixels on the current frame.",
"",
" \"Edit > Crop Frame\"",
" Deletes all pixels that are outside of the screen.",
"",
" \"Edit > Change Box Character\"",
" Opens the block character selection. Used for making those delicious subpixel pictures.",
"",
" \"Edit > Change Special Character\"",
" Opens the special character selector, which lets you change the paint character to that of byte 0 to 255.",
"",
" \"Edit > BLittle Shrink\"",
" Shrinks the current frame using the BLittle API. Very lossy, and unreversable without Undo.",
"",
" \"Edit > Copy\"",
" Drag to select a region of the screen, and save it in a clipboard of a specified name.",
"",
" \"Edit > Cut\"",
" Same as Copy, but deletes the selected region on the screen.",
"",
" \"Edit > Paste\"",
" Takes the contents of the specified clipboard, and plops it on the canvas where the mouse is.",
"(The mouse will indicate the top-left corner of the pasted selection)",
"",
" \"Set > ...\"",
" Each option will toggle a config option (or set it's value to something else).",
" Changing a value is saved automatically, and effective immediately.",
"",
" \"Window > Set Screen Size\"",
" Sets the sizes of the screen border references displayed on the canvas.",
"",
" \"Window > Set Grid Colors\"",
" Sets the backdrop colors to your currently selected color configuration.",
"",
" \"About > PAIN\"",
" Tells you about PAIN and its developer.",
"",
" \"About > File Formats\"",
" Tells you the ins and outs of the file formats, and a brief description of their creators.",
"",
" \"About > Help\"",
" Opens up this help page.",
"",
" \"Exit\"",
" Durr I dunno, I think it exits.",
"",
"",
"I hope my PAIN causes you joy.",
"]]",
" _helpText = explode(\"\\n\",_helpText)",
" helpText = cutUp(scr_x,_helpText)",
" local helpscroll = 0",
" term.setBackgroundColor(colors.gray)",
" term.setTextColor(colors.white)",
" term.clear()",
" local evt, key",
" while true do",
" term.clear()",
" for a = 1, scr_y do",
" term.setCursorPos(1,a)",
" term.clearLine()",
" write(helpText[a-helpscroll] or \"\")",
" end",
" repeat",
" evt,key = os.pullEvent()",
" until evt == \"key\" or evt == \"mouse_scroll\"",
" if evt == \"key\" then",
" if key == keys.up then",
" helpscroll = helpscroll + 1",
" elseif key == keys.down then",
" helpscroll = helpscroll - 1",
" elseif key == keys.pageUp then",
" helpscroll = helpscroll + scr_y",
" elseif key == keys.pageDown then",
" helpscroll = helpscroll - scr_y",
" elseif (key == keys.q) or (key == keys.space) then",
" doRender = true",
" if renderBlittle then term.redirect(blittleTerm) end",
" scr_x, scr_y = term.current().getSize()",
" return",
" end",
" elseif evt == \"mouse_scroll\" then",
" helpscroll = helpscroll - key",
" end",
" if helpscroll > 0 then",
" helpscroll = 0",
" elseif helpscroll < -(#helpText-(scr_y-3)) then",
" helpscroll = -(#helpText-(scr_y-3))",
" end",
" end",
"end",
"",
"local tableRemfind = function(tbl, str)",
" local out = tbl",
" for a = 1, #tbl do",
" if tbl[a] == str then",
" table.remove(out,a)",
" return out,a",
" end",
" end",
" return {}",
"end",
"",
"local stringShift = function(str,amt)",
" return str:sub(ro(amt-1,#str)+1)..str:sub(1,ro(amt-1,#str))",
"end",
"",
"local deepCopy",
"deepCopy = function(obj)",
" if type(obj) ~= 'table' then return obj end",
" local res = {}",
" for k, v in pairs(obj) do res[deepCopy(k)] = deepCopy(v) end",
" return res",
"end",
"",
"local clearLines = function(y1, y2)",
" local cx,cy = term.getCursorPos()",
" for y = y1, y2 do",
" term.setCursorPos(1,y)",
" term.clearLine()",
" end",
" term.setCursorPos(cx,cy)",
"end",
"",
"local renderBottomBar = function(txt,extraClearY)",
" term.setCursorPos(1,scr_y - math.floor(#txt/scr_x))",
" term.setBackgroundColor(colors.lightGray)",
" term.setTextColor(colors.black)",
" clearLines(scr_y - (math.floor(#txt/scr_x) - (extraClearY or 0)), scr_y)",
" return write(txt)",
"end",
"",
"local bottomPrompt = function(txt,history,cho,breakkeys,returnNumber,writeIndent)",
" local writeIndent = renderBottomBar(txt,writeIndent)",
" local out",
" sleep(0)",
" if cho then",
" out = choice(cho,breakkeys,returnNumber)",
" else",
" out = read(_,history)",
" end",
" return out, writeIndent",
"end",
"",
"local makeSubMenu = function(x,y,options)",
" local longestLen = 0",
" for a = 1, #options do",
" if #options[a] > longestLen then",
" longestLen = #options[a]",
" end",
" end",
" longestLen = longestLen + 1",
" term.setTextColor(colors.black)",
" local sel = 1",
" local rend = function()",
" for a = #options, 1, -1 do",
" term.setCursorPos(x or 1, ((y or (scr_y-1)) - (#options-1)) + (a - 1))",
" term.setBackgroundColor(a == sel and colors.white or colors.lightGray)",
" term.write(options[a])",
" term.setBackgroundColor(colors.lightGray)",
" term.write((\" \"):rep(longestLen-#options[a]))",
" end",
" end",
" local usingMouse = false",
" while true do",
" rend()",
" local evt, key, mx, my = os.pullEvent()",
" if evt == \"key\" then",
" if key == keys.up then",
" sel = sel - 1",
" elseif key == keys.down then",
" sel = sel + 1",
" elseif (key == keys.enter) or (key == keys.right) then",
" return sel, longestLen",
" elseif (key == keys.leftCtrl) or (key == keys.rightCtrl) or (key == keys.backspace) or (key == keys.left) then",
" return false, longestLen",
" end",
" elseif evt == \"mouse_drag\" or evt == \"mouse_click\" then",
" if (mx >= x) and (mx < x+longestLen) and (my <= y and my > y-#options) then",
" sel = math.min(#options,math.max(1,(my+#options) - y))",
" usingMouse = true",
" else",
" usingMouse = false",
" if evt == \"mouse_click\" then",
" return false, longestLen",
" end",
" end",
" elseif evt == \"mouse_up\" then",
" if usingMouse then",
" return sel, longestLen",
" end",
" end",
" if sel > #options then sel = 1 elseif sel < 1 then sel = #options end",
" end",
"end",
"",
"local getDotsInLine = function( startX, startY, endX, endY ) -- stolen from the paintutils API...nwehehehe",
" local out = {}",
" startX = math.floor(startX)",
" startY = math.floor(startY)",
" endX = math.floor(endX)",
" endY = math.floor(endY)",
" if startX == endX and startY == endY then",
" out = {{x=startX,y=startY}}",
" return out",
" end",
" local minX = math.min( startX, endX )",
" if minX == startX then",
" minY = startY",
" maxX = endX",
" maxY = endY",
" else",
" minY = endY",
" maxX = startX",
" maxY = startY",
" end",
" local xDiff = maxX - minX",
" local yDiff = maxY - minY",
" if xDiff > math.abs(yDiff) then",
" local y = minY",
" local dy = yDiff / xDiff",
" for x=minX,maxX do",
" out[#out+1] = {x=x,y=math.floor(y+0.5)}",
" y = y + dy",
" end",
" else",
" local x = minX",
" local dx = xDiff / yDiff",
" if maxY >= minY then",
" for y=minY,maxY do",
" out[#out+1] = {x=math.floor(x+0.5),y=y}",
" x = x + dx",
" end",
" else",
" for y=minY,maxY,-1 do",
" out[#out+1] = {x=math.floor(x+0.5),y=y}",
" x = x - dx",
" end",
" end",
" end",
" return out",
"end",
"",
"local movePaintEncoded = function(pe,xdiff,ydiff)",
" local outpootis = deepCopy(pe)",
" for a = 1, #outpootis do",
" outpootis[a].x = outpootis[a].x+xdiff",
" outpootis[a].y = outpootis[a].y+ydiff",
" end",
" return outpootis",
"end",
"",
"local clearRedundant = function(dots)",
" local input = {}",
" local pheight = 0",
" local pwidth = 0",
" local minX, minY = 0, 0",
" for a = 1, #dots do",
" pheight = math.max(pheight, dots[a].y)",
" pwidth = math.max(pwidth, dots[a].x)",
" minX = math.min(minX, dots[a].x)",
" minY = math.min(minY, dots[a].y)",
" end",
" for a = 1, #dots do",
" if not input[dots[a].y] then input[dots[a].y] = {} end",
" input[dots[a].y][dots[a].x] = dots[a]",
" end",
" local output = {}",
" local frame = 0",
" for y = minY, pheight do",
" for x = minX, pwidth do",
" if input[y] then",
" if input[y][x] then",
" output[#output+1] = input[y][x]",
" end",
" end",
" if frame >= 50 then",
" -- yield()",
" frame = 0",
" end",
" end",
" end",
" return output",
"end",
"",
"local grayOut = function(color)",
" local c = deepCopy(_G.colors)",
" local grays = {",
" [c.white] = c.white,",
" [c.orange] = c.lightGray,",
" [c.magenta] = c.lightGray,",
" [c.lightBlue] = c.lightGray,",
" [c.yellow] = c.white,",
" [c.lime] = c.lightGray,",
" [c.pink] = c.lightGray,",
" [c.gray] = c.gray,",
" [c.lightGray] = c.lightGray,",
" [c.cyan] = c.lightGray,",
" [c.purple] = c.gray,",
" [c.blue] = c.gray,",
" [c.brown] = c.gray,",
" [c.green] = c.lightGray,",
" [c.red] = c.gray,",
" [c.black] = c.black,",
" }",
" if (not color) or (color == \" \") then return color end",
" local newColor = grays[color] or 1",
" return newColor",
"end",
"",
"local getOnscreenCoords = function(tbl,_x,_y)",
" local screenTbl = {}",
" for a = 1, #tbl do",
" if tbl[a].x+paint.scrollX > 0 and tbl[a].x+paint.scrollX <= scr_x then",
" if tbl[a].y+paint.scrollY > 0 and tbl[a].y+paint.scrollY <= scr_y then",
" screenTbl[#screenTbl+1] = {tbl[a].x+paint.scrollX,tbl[a].y+paint.scrollY}",
" end",
" end",
" end",
" if not _x and _y then",
" return screenTbl",
" else",
" for a = 1, #screenTbl do",
" if screenTbl[a][1] == _x and screenTbl[a][2] == _y then",
" return true",
" end",
" end",
" return false",
" end",
"end",
"",
"local clearAllRedundant = function(info)",
" local output = {}",
" for a = 1, #info do",
" output[a] = clearRedundant(info[a])",
" if a % 4 == 0 then yield() end",
" end",
" return output",
"end",
"",
"local saveFile = function(path,info)",
" local output = clearAllRedundant(info)",
" local fileout = textutils.serialize(output):gsub(\" \",\"\"):gsub(\"\\n\",\"\"):gsub(\" = \",\"=\"):gsub(\",}\",\"}\"):gsub(\"}},{{\",\"}},\\n{{\")",
" if #fileout >= fs.getFreeSpace(fs.getDir(path)) then",
" barmsg = \"Not enough space.\"",
" return",
" end",
" local file = fs.open(path,\"w\")",
" file.write(fileout)",
" file.close()",
"end",
"local renderBar = function(msg,dontSetVisible)",
" if (doRenderBar == 0) or renderBlittle then return end",
" if tsv and (not dontSetVisible) then tsv(false) end",
" term.setCursorPos(1,scr_y)",
" term.setBackgroundColor(colors.lightGray)",
" term.setTextColor(colors.black)",
" term.clearLine()",
" term.setBackgroundColor(paint.b or rendback.b)",
" term.setTextColor(paint.t or rendback.t)",
" term.setCursorPos(2,scr_y)",
" term.write(\"PAIN\")",
" term.setBackgroundColor(colors.lightGray)",
" term.setTextColor(colors.black)",
" local fmsg = tableconcat({\"Fr:\",frame,\"/\",#paintEncoded,\" (\",paint.scrollX,\",\",paint.scrollY,\")\"})",
" term.setCursorPos(7,scr_y)",
" term.write(msg)",
" term.setCursorPos(scr_x-(#fmsg),scr_y)",
" term.write(fmsg)",
" if tsv and (not dontSetVisible) then tsv(true) end",
"end",
"",
"local tableFormatPE = function(input)",
" local doot = {}",
" local pwidths = {}",
" local pheight = 0",
" for k, dot in pairs(input) do",
" pwidths[dot.y] = math.max((pwidths[dot.y] or 0), dot.x)",
" pheight = math.max(pheight, dot.y)",
" doot[dot.y] = doot[dot.y] or {}",
" doot[dot.y][dot.x] = {",
" char = dot.c,",
" text = CTB(dot.t),",
" back = CTB(dot.b)",
" }",
" end",
" for y = 1, pheight do",
" pwidths[y] = pwidths[y] or 0",
" if doot[y] then",
" for x = 1, pwidths[y] do",
" doot[y][x] = doot[y][x] or {",
" text = \" \",",
" back = \" \",",
" char = \" \",",
" }",
" end",
" else",
" doot[y] = false",
" end",
" end",
" return doot, pheight, pwidths",
"end",
"",
"CTB = function(_color) --Color To Blit",
" local blitcolors = {",
" [0] = \" \",",
" [colors.white] = \"0\",",
" [colors.orange] = \"1\",",
" [colors.magenta] = \"2\",",
" [colors.lightBlue] = \"3\",",
" [colors.yellow] = \"4\",",
" [colors.lime] = \"5\",",
" [colors.pink] = \"6\",",
" [colors.gray] = \"7\",",
" [colors.lightGray] = \"8\",",
" [colors.cyan] = \"9\",",
" [colors.purple] = \"a\",",
" [colors.blue] = \"b\",",
" [colors.brown] = \"c\",",
" [colors.green] = \"d\",",
" [colors.red] = \"e\",",
" [colors.black] = \"f\",",
" }",
" if _color == nil then return nil end",
" return blitcolors[_color] or \"f\"",
"end",
"",
"BTC = function(_color,allowZero) --Blit To Color",
" local blitcolors = {",
" [\" \"] = allowZero and 0 or nil,",
" [\"0\"] = colors.white,",
" [\"1\"] = colors.orange,",
" [\"2\"] = colors.magenta,",
" [\"3\"] = colors.lightBlue,",
" [\"4\"] = colors.yellow,",
" [\"5\"] = colors.lime,",
" [\"6\"] = colors.pink,",
" [\"7\"] = colors.gray,",
" [\"8\"] = colors.lightGray,",
" [\"9\"] = colors.cyan,",
" [\"a\"] = colors.purple,",
" [\"b\"] = colors.blue,",
" [\"c\"] = colors.brown,",
" [\"d\"] = colors.green,",
" [\"e\"] = colors.red,",
" [\"f\"] = colors.black,",
" }",
" if _color == nil then return nil end",
" return blitcolors[_color]",
"end",
"",
"local renderPainyThings = function(xscroll,yscroll,doGrid)",
" local yadjust = (renderBlittle and 0 or doRenderBar)",
" if bepimode then",
" grid = {",
" \"Bepis\",",
" \"episB\",",
" \"pisBe\",",
" \"isBep\",",
" \"sBepi\",",
" }",
" else",
" grid = {",
" \"%%..\",",
" \"%%..\",",
" \"%%..\",",
" \"..%%\",",
" \"..%%\",",
" \"..%%\",",
" }",
" end",
" term.setBackgroundColor(rendback.b)",
" term.setTextColor(rendback.t)",
" local badchar = \"/\"",
" local blittlelabel = \"blittle max\"",
" local screenlabel = \"screen max\"",
"",
" local dotBuffChar, dotBuffBack = \"\", \"\" --only used if gridBleedThrough is true",
" local doot",
" if doGrid then",
" for y = 1, scr_y - yadjust do",
" term.setCursorPos(1,y)",
" -- the single most convoluted line I've ever written that works, and I love it",
" term.write(stringShift(grid[ro(y+(yscroll+2),#grid)+1],xscroll+1):rep(math.ceil(scr_x/#grid[ro(y+(yscroll+2),#grid)+1])):sub(1,scr_x))",
" term.setCursorPos((xscroll <= 0) and (1-xscroll) or 0,y)",
" if ((screenEdges[2]+1)-yscroll) == y then --regular limit",
" term.write( (string.rep(\"@\", math.max(0,( (screenEdges[1]) ) - (#screenlabel+1) )) ..screenlabel:gsub(\" \",\"@\"):upper()..\"@@\"):sub(xscroll>0 and xscroll or 0):sub(1,1+screenEdges[1]) )",
" elseif (((screenEdges[2]*3)+1)-yscroll) == y then --blittle limit",
" term.write( (string.rep(\"@\", math.max(0,( ((screenEdges[1]*2)) ) - (#blittlelabel+1) ))..blittlelabel:gsub(\" \",\"@\"):upper()..\"@@\"):sub(xscroll>0 and xscroll or 0):sub(1,1+screenEdges[1]*2) )",
" end",
" -- Stupid easter eggs, ho! --",
" if 1000-yscroll == y then",
" term.setCursorPos(1000-xscroll,y)",
" term.write(\" What ARE you doing? Stop messing around! \")",
" end",
" if 2016-yscroll == y then",
" term.setCursorPos(200-xscroll,y)",
" term.write(\" Lines don't like to be intersected, you know. \")",
" end",
" if 2017-yscroll == y then",
" term.setCursorPos(200-xscroll,y)",
" term.write(\" It makes them very crossed. \")",
" end",
" if 800-yscroll == y then",
" term.setCursorPos(1700-xscroll,y)",
" term.write(\" You stare deeply into the void. \")",
" end",
" if 801-yscroll == y then",
" term.setCursorPos(1704-xscroll,y)",
" term.write(\" And the void \")",
" end",
" if 802-yscroll == y then",
" term.setCursorPos(1704-xscroll,y)",
" term.write(\" stares back. \")",
" end",
" --Is this the end?--",
" if (xscroll > ((screenEdges[1]*2)-scr_x)) then",
" for y = 1, scr_y do",
" if y+yscroll <= (screenEdges[2]*3) then",
" if not (y == scr_y and doRenderBar == 1) then",
" term.setCursorPos((screenEdges[1]+1)-(xscroll-screenEdges[1]),y)",
" term.write(\"@\")",
" end",
" end",
" end",
" end",
" if (xscroll > (screenEdges[1]-scr_x)) then --regular limit",
" for y = 1, scr_y do",
" if y+yscroll <= screenEdges[2] then",
" if not (y == scr_y and doRenderBar == 1) then",
" term.setCursorPos((screenEdges[1]+1)-xscroll,y)",
" term.write(\"@\")",
" end",
" end",
" end",
" end",
" end",
" --render areas that won't save",
" if xscroll < 0 then",
" for y = 1, scr_y do",
" if not (y == scr_y and doRenderBar == 1) then",
" term.setCursorPos(1,y)",
" term.write(badchar:rep(-xscroll))",
" end",
" end",
" end",
" if yscroll < 0 then",
" for y = 1, -yscroll do",
" if not (y == scr_y and doRenderBar == 1) then",
" term.setCursorPos(1,y)",
" term.write(badchar:rep(scr_x))",
" end",
" end",
" end",
" else",
" for y = 1, scr_y - yadjust do",
" term.setCursorPos(1,y)",
" term.clearLine()",
" end",
" end",
"end",
"",
"importFromPaint = function(theInput)",
" local output = {}",
" local input",
" if type(theInput) == \"string\" then",
" input = explode(\"\\n\",theInput)",
" else",
" input = {}",
" for y = 1, #theInput do",
" input[y] = \"\"",
" for x = 1, #theInput[y] do",
" input[y] = input[y]..(CTB(theInput[y][x]) or \" \")",
" end",
" end",
" end",
" for a = 1, #input do",
" line = input[a]",
" for b = 1, #line do",
" if (line:sub(b,b) ~= \" \") and BTC(line:sub(b,b)) then",
" output[#output+1] = {",
" x = b,",
" y = a,",
" t = colors.white,",
" b = BTC(line:sub(b,b)) or colors.black,",
" c = \" \",",
" }",
" end",
" end",
" end",
" return output",
"end",
"",
"local lddfm = {",
" scroll = 0,",
" ypaths = {}",
"}",
"",
"lddfm.scr_x, lddfm.scr_y = term.getSize()",
"",
"lddfm.setPalate = function(_p)",
" if type(_p) ~= \"table\" then",
" _p = {}",
" end",
" lddfm.p = { --the DEFAULT color palate",
" bg = _p.bg or colors.gray, -- whole background color",
" d_txt = _p.d_txt or colors.yellow, -- directory text color",
" d_bg = _p.d_bg or colors.gray, -- directory bg color",
" f_txt = _p.f_txt or colors.white, -- file text color",
" f_bg = _p.f_bg or colors.gray, -- file bg color",
" p_txt = _p.p_txt or colors.black, -- path text color",
" p_bg = _p.p_bg or colors.lightGray, -- path bg color",
" close_txt = _p.close_txt or colors.gray, -- close button text color",
" close_bg = _p.close_bg or colors.lightGray,-- close button bg color",
" scr = _p.scr or colors.lightGray, -- scrollbar color",
" scrbar = _p.scrbar or colors.gray, -- scroll tab color",
" }",
"end",
"",
"lddfm.setPalate()",
"",
"lddfm.foldersOnTop = function(floop,path)",
" local output = {}",
" for a = 1, #floop do",
" if fs.isDir(fs.combine(path,floop[a])) then",
" table.insert(output,1,floop[a])",
" else",
" table.insert(output,floop[a])",
" end",
" end",
" return output",
"end",
"",
"lddfm.filterFileFolders = function(list,path,_noFiles,_noFolders,_noCD,_doHidden)",
" local output = {}",
" for a = 1, #list do",
" local entry = fs.combine(path,list[a])",
" if fs.isDir(entry) then",
" if entry == \"..\" then",
" if not (_noCD or _noFolders) then table.insert(output,list[a]) end",
" else",
" if not ((not _doHidden) and list[a]:sub(1,1) == \".\") then",
" if not _noFolders then table.insert(output,list[a]) end",
" end",
" end",
" else",
" if not ((not _doHidden) and list[a]:sub(1,1) == \".\") then",
" if not _noFiles then table.insert(output,list[a]) end",
" end",
" end",
" end",
" return output",
"end",
"",
"lddfm.isColor = function(col)",
" for k,v in pairs(colors) do",
" if v == col then",
" return true, k",
" end",
" end",
" return false",
"end",
"",
"lddfm.clearLine = function(x1,x2,_y,_bg,_char)",
" local cbg, bg = term.getBackgroundColor()",
" local x,y = term.getCursorPos()",
" local sx,sy = term.getSize()",
" if type(_char) == \"string\" then char = _char else char = \" \" end",
" if type(_bg) == \"number\" then",
" if lddfm.isColor(_bg) then bg = _bg",
" else bg = cbg end",
" else bg = cbg end",
" term.setCursorPos(x1 or 1, _y or y)",
" term.setBackgroundColor(bg)",
" if x2 then --it pains me to add an if statement to something as simple as this",
" term.write((char or \" \"):rep(x2-x1))",
" else",
" term.write((char or \" \"):rep(sx-(x1 or 0)))",
" end",
" term.setBackgroundColor(cbg)",
" term.setCursorPos(x,y)",
"end",
"",
"lddfm.render = function(_x1,_y1,_x2,_y2,_rlist,_path,_rscroll,_canClose,_scrbarY)",
" local tsv = term.current().setVisible",
" local px,py = term.getCursorPos()",
" if tsv then tsv(false) end",
" local x1, x2, y1, y2 = _x1 or 1, _x2 or lddfm.scr_x, _y1 or 1, _y2 or lddfm.scr_y",
" local rlist = _rlist or {\"Invalid directory.\"}",
" local path = _path or \"And that's terrible.\"",
" ypaths = {}",
" local rscroll = _rscroll or 0",
" for a = y1, y2 do",
" lddfm.clearLine(x1,x2,a,lddfm.p.bg)",
" end",
" term.setCursorPos(x1,y1)",
" term.setTextColor(lddfm.p.p_txt)",
" lddfm.clearLine(x1,x2+1,y1,lddfm.p.p_bg)",
" term.setBackgroundColor(lddfm.p.p_bg)",
" term.write((\"/\"..path):sub(1,x2-x1))",
" for a = 1,(y2-y1) do",
" if rlist[a+rscroll] then",
" term.setCursorPos(x1,a+(y1))",
" if fs.isDir(fs.combine(path,rlist[a+rscroll])) then",
" lddfm.clearLine(x1,x2,a+(y1),lddfm.p.d_bg)",
" term.setTextColor(lddfm.p.d_txt)",
" term.setBackgroundColor(lddfm.p.d_bg)",
" else",
" lddfm.clearLine(x1,x2,a+(y1),lddfm.p.f_bg)",
" term.setTextColor(lddfm.p.f_txt)",
" term.setBackgroundColor(lddfm.p.f_bg)",
" end",
" term.write(rlist[a+rscroll]:sub(1,x2-x1))",
" ypaths[a+(y1)] = rlist[a+rscroll]",
" else",
" lddfm.clearLine(x1,x2,a+(y1),lddfm.p.bg)",
" end",
" end",
" local scrbarY = _scrbarY or math.ceil( (y1+1)+( (_rscroll/(#_rlist-(y2-(y1+1))))*(y2-(y1+1)) ) )",
" for a = y1+1, y2 do",
" term.setCursorPos(x2,a)",
" if a == scrbarY then",
" term.setBackgroundColor(lddfm.p.scrbar)",
" else",
" term.setBackgroundColor(lddfm.p.scr)",
" end",
" term.write(\" \")",
" end",
" if _canClose then",
" term.setCursorPos(x2-4,y1)",
" term.setTextColor(lddfm.p.close_txt)",
" term.setBackgroundColor(lddfm.p.close_bg)",
" term.write(\"close\")",
" end",
" term.setCursorPos(px,py)",
" if tsv then tsv(true) end",
" return scrbarY",
"end",
"",
"lddfm.coolOutro = function(x1,y1,x2,y2,_bg,_txt,char)",
" local cx, cy = term.getCursorPos()",
" local bg, txt = term.getBackgroundColor(), term.getTextColor()",
" term.setTextColor(_txt or colors.white)",
" term.setBackgroundColor(_bg or colors.black)",
" local _uwah = 0",
" for y = y1, y2 do",
" for x = x1, x2 do",
" _uwah = _uwah + 1",
" term.setCursorPos(x,y)",
" term.write(char or \" \")",
" if _uwah >= math.ceil((x2-x1)*1.63) then sleep(0) _uwah = 0 end",
" end",
" end",
" term.setTextColor(txt)",
" term.setBackgroundColor(bg)",
" term.setCursorPos(cx,cy)",
"end",
"",
"lddfm.scrollMenu = function(amount,list,y1,y2)",
" if #list >= y2-y1 then",
" lddfm.scroll = lddfm.scroll + amount",
" if lddfm.scroll < 0 then",
" lddfm.scroll = 0",
" end",
" if lddfm.scroll > #list-(y2-y1) then",
" lddfm.scroll = #list-(y2-y1)",
" end",
" end",
"end",
"",
"lddfm.makeMenu = function(_x1,_y1,_x2,_y2,_path,_noFiles,_noFolders,_noCD,_noSelectFolders,_doHidden,_p,_canClose)",
" if _noFiles and _noFolders then",
" return false, \"C'mon, man...\"",
" end",
" if _x1 == true then",
" return false, \"arguments: x1, y1, x2, y2, path, noFiles, noFolders, noCD, noSelectFolders, doHidden, palate, canClose\" -- a little help",
" end",
" lddfm.setPalate(_p)",
" local path, list = _path or \"\"",
" lddfm.scroll = 0",
" local _pbg, _ptxt = term.getBackgroundColor(), term.getTextColor()",
" local x1, x2, y1, y2 = _x1 or 1, _x2 or lddfm.scr_x, _y1 or 1, _y2 or lddfm.scr_y",
" local keysDown = {}",
" local _barrY",
" while true do",
" list = lddfm.foldersOnTop(lddfm.filterFileFolders(fs.list(path),path,_noFiles,_noFolders,_noCD,_doHidden),path)",
" if (fs.getDir(path) ~= \"..\") and not (_noCD or _noFolders) then",
" table.insert(list,1,\"..\")",
" end",
" _res, _barrY = pcall( function() return lddfm.render(x1,y1,x2,y2,list,path,lddfm.scroll,_canClose) end)",
" if not _res then",
" local tsv = term.current().setVisible",
" if tsv then tsv(true) end",
" error(_barrY)",
" end",
" local evt = {os.pullEvent()}",
" if evt[1] == \"mouse_scroll\" then",
" lddfm.scrollMenu(evt[2],list,y1,y2)",
" elseif evt[1] == \"mouse_click\" then",
" local butt,mx,my = evt[2],evt[3],evt[4]",
" if (butt == 1 and my == y1 and mx <= x2 and mx >= x2-4) and _canClose then",
" --lddfm.coolOutro(x1,y1,x2,y2)",
" term.setTextColor(_ptxt) term.setBackgroundColor(_pbg)",
" return false",
" elseif ypaths[my] and (mx >= x1 and mx < x2) then --x2 is reserved for the scrollbar, breh",
" if fs.isDir(fs.combine(path,ypaths[my])) then",
" if _noCD or butt == 3 then",
" if not _noSelectFolders or _noFolders then",
" --lddfm.coolOutro(x1,y1,x2,y2)",
" term.setTextColor(_ptxt) term.setBackgroundColor(_pbg)",
" return fs.combine(path,ypaths[my])",
" end",
" else",
" path = fs.combine(path,ypaths[my])",
" lddfm.scroll = 0",
" end",
" else",
" term.setTextColor(_ptxt) term.setBackgroundColor(_pbg)",
" return fs.combine(path,ypaths[my])",
" end",
" end",
" elseif evt[1] == \"key\" then",
" keysDown[evt[2]] = true",
" if evt[2] == keys.enter and not (_noFolders or _noCD or _noSelectFolders) then --the logic for _noCD being you'd normally need to go back a directory to select the current directory.",
" --lddfm.coolOutro(x1,y1,x2,y2)",
" term.setTextColor(_ptxt) term.setBackgroundColor(_pbg)",
" return path",
" end",
" if evt[2] == keys.up then",
" lddfm.scrollMenu(-1,list,y1,y2)",
" elseif evt[2] == keys.down then",
" lddfm.scrollMenu(1,list,y1,y2)",
" end",
" if evt[2] == keys.pageUp then",
" lddfm.scrollMenu(y1-y2,list,y1,y2)",
" elseif evt[2] == keys.pageDown then",
" lddfm.scrollMenu(y2-y1,list,y1,y2)",
" end",
" if evt[2] == keys.home then",
" lddfm.scroll = 0",
" elseif evt[2] == keys[\"end\"] then",
" if #list > (y2-y1) then",
" lddfm.scroll = #list-(y2-y1)",
" end",
" end",
" if evt[2] == keys.h then",
" if keysDown[keys.leftCtrl] or keysDown[keys.rightCtrl] then",
" _doHidden = not _doHidden",
" end",
" elseif _canClose and (evt[2] == keys.x or evt[2] == keys.q or evt[2] == keys.leftCtrl) then",
" --lddfm.coolOutro(x1,y1,x2,y2)",
" term.setTextColor(_ptxt) term.setBackgroundColor(_pbg)",
" return false",
" end",
" elseif evt[1] == \"key_up\" then",
" keysDown[evt[2]] = false",
" end",
" end",
"end",
"",
"local getBlittle = function()",
" if not blittle then",
" if fs.exists(fs.combine(apipath,\"blittle\")) then",
" os.loadAPI(fs.combine(apipath,\"blittle\"))",
" if not blittleTerm then",
" blittleTerm = blittle.createWindow()",
" end",
" return blittleTerm, firstTerm",
" else",
" local geet = http.get(\"http://pastebin.com/raw/ujchRSnU\")",
" if not geet then",
" return false",
" else",
" geet = geet.readAll()",
" local file = fs.open(fs.combine(apipath,\"blittle\"),\"w\")",
" file.write(geet)",
" file.close()",
" os.loadAPI(fs.combine(apipath,\"blittle\"))",
" --fs.delete(apipath)",
" if not blittleTerm then",
" blittleTerm = blittle.createWindow()",
" end",
" return blittleTerm, firstTerm",
" end",
" end",
" else",
" if not blittleTerm then",
" blittleTerm = blittle.createWindow()",
" end",
" return blittleTerm, firstTerm",
" end",
"end",
"",
"local getUCG = function()",
" if not ucg then",
" if fs.exists(fs.combine(apipath,\"ucg\")) then",
" os.loadAPI(fs.combine(apipath,\"ucg\"))",
" return true",
" else",
" local geet = http.get(\"https://raw.githubusercontent.com/ardera/libucg/master/src/libucg\")",
" if not geet then",
" return false",
" else",
" geet = geet.readAll()",
" local file = fs.open(fs.combine(apipath,\"ucg\"),\"w\")",
" file.write(geet)",
" file.close()",
" os.loadAPI(fs.combine(apipath,\"ucg\"))",
" end",
" end",
" end",
"end",
"",
"local getBBPack = function()",
" if not bbpack then",
" if fs.exists(fs.combine(apipath,\"bbpack\")) then",
" os.loadAPI(fs.combine(apipath,\"bbpack\"))",
" return true",
" else",
" local geet = http.get(\"https://pastebin.com/raw/cUYTGbpb\")",
" if not geet then",
" return false",
" else",
" geet = geet.readAll()",
" local file = fs.open(fs.combine(apipath,\"bbpack\"),\"w\")",
" file.write(geet)",
" file.close()",
" os.loadAPI(fs.combine(apipath,\"bbpack\"))",
" end",
" end",
" end",
"end",
"",
"local getGIF = function()",
" getBBPack()",
" if not GIF then",
" if fs.exists(fs.combine(apipath,\"GIF\")) then",
" os.loadAPI(fs.combine(apipath,\"GIF\"))",
" return true",
" else",
" local geet = http.get(\"https://pastebin.com/raw/5uk9uRjC\")",
" if not geet then",
" return false",
" else",
" geet = geet.readAll()",
" local file = fs.open(fs.combine(apipath,\"GIF\"),\"w\")",
" file.write(geet)",
" file.close()",
" os.loadAPI(fs.combine(apipath,\"GIF\"))",
" end",
" end",
" end",
"end",
"",
"local NFPserializeImage = function(str)",
" local bepis = explode(\"\\n\",str)",
" local output = {}",
" for y = 1, #bepis do",
" output[y] = {}",
" for x = 1, #bepis[y] do",
" output[y][x] = BTC(bepis[y]:sub(x,x),true)",
" end",
" end",
" return textutils.unserialize(textutils.serialize(output):gsub(\"\\n\",\"\"):gsub(\" \",\"\"):gsub(\",}\",\"}\"))",
"end",
"",
"local importFromGIF = function(filename,verbose)",
" getGIF()",
" local output = {}",
" local image",
" local rawGif = GIF.loadGIF(filename)",
" if painconfig.useFlattenGIF then",
" if verbose then",
" print(\"Flattening...\")",
" end",
" rawGif = GIF.flattenGIF(rawGif)",
" sleep(0)",
" end",
" local cx, cy = term.getCursorPos()",
" for a = 1, #rawGif do",
" output[a] = importFromPaint(GIF.toPaintutils(rawGif[a]))",
" if verbose then",
" term.setCursorPos(cx,cy)",
" write(\"Did \"..a..\"/\"..#rawGif..\" \")",
" end",
" if a % 1 then sleep(0) end --used to be a % 2, might change later",
" end",
" return output",
"end",
"",
"local exportToPaint",
"",
"local exportToGIF = function(input)",
" getGIF()",
" local outGIF = {}",
" for a = 1, #paintEncoded do",
" outGIF[a] = NFPserializeImage(exportToPaint(paintEncoded[a]))",
" sleep(0)",
" end",
" if painconfig.useFlattenGIF then",
" return GIF.flattenGIF(GIF.buildGIF(table.unpack(outGIF)),true)",
" else",
" return GIF.buildGIF(table.unpack(outGIF))",
" end",
"end",
"",
"local importFromUCG = function(filename)",
" getUCG()",
" return importFromPaint(ucg.readFile(filename))",
"end",
"",
"local exportToUCG = function(filename, input)",
" getUCG()",
" ucg.writeFile(filename, NFPserializeImage(exportToPaint(input)))",
"end",
"",
"renderPAIN = function(dots,xscroll,yscroll,doPain,dontRenderBar)",
" if tsv then tsv(false) end",
" local beforeTX,beforeBG = term.getTextColor(), term.getBackgroundColor()",
" local cx,cy = term.getCursorPos()",
" local FUCK, SHIT = pcall(function()",
" if doPain then",
" if (not renderBlittle) then",
" if not dontRenderBar then",
" renderBar(barmsg,true)",
" end",
" renderPainyThings(xscroll,yscroll,evenDrawGrid)",
" else",
" term.clear()",
" end",
" end",
" for a = 1, #dots do",
" local d = dots[a]",
" if doPain then",
" if not ((d.y-yscroll >= 1 and d.y-yscroll <= scr_y-(renderBlittle and 0 or doRenderBar)) and (d.x-xscroll >= 1 and d.x-xscroll <= scr_x)) then",
" d = nil",
" end",
" end",
" if d then",
" term.setCursorPos(d.x-(xscroll or 0),d.y-(yscroll or 0))",
" term.setBackgroundColor((paint.doGray and grayOut(d.b) or d.b) or rendback.b)",
" if painconfig.gridBleedThrough then",
" term.setTextColor(rendback.t)",
" term.write((d.x >= 1 and d.y >= 1) and grid[ ro( d.y+2, #grid)+1]:sub(1+ro(d.x+-1,#grid[1]), 1+ro(d.x+-1,#grid[1])) or \"/\")",
" else",
" term.setTextColor( (paint.doGray and grayOut(d.t) or d.t) or rendback.t)",
" term.write(d.c or \" \")",
" end",
" end",
" end",
" end)",
" term.setBackgroundColor(beforeBG or rendback.b)",
" term.setTextColor(beforeTX or rendback.t)",
" term.setCursorPos(cx,cy)",
" if tsv then tsv(true) end",
" if not FUCK then error(SHIT) end --GOD DAMN IT",
"end",
"",
"renderPAINFS = function(filename,xscroll,yscroll,frameNo,doPain)",
" local tun, tse = textutils.unserialize, textutils.serialize",
" local file = fs.open(filename,\"r\")",
" local contents = file.readAll()",
" local amntFrames",
" file.close()",
" local tcontents = tun(contents)",
" if type(tcontents) ~= \"table\" then",
" tcontents = importFromPaint(contents)",
" else",
" amntFrames = #tcontents",
" tcontents = tcontents[frameNo or 1]",
" end",
" renderPAIN(tcontents,xscroll,yscroll,doPain)",
" return amntFrames",
"end",
"",
"local putDotDown = function(dot) -- only 'x' and 'y' are required arguments",
" paintEncoded[frame][#paintEncoded[frame]+1] = {",
" x = dot.x + paint.scrollX,",
" y = dot.y + paint.scrollY,",
" c = dot.c or paint.c,",
" b = dot.b or (swapColors and paint.t or paint.b),",
" t = dot.t or (swapColors and paint.b or paint.t),",
" m = dot.m or paint.m,",
" }",
"end",
"",
"local saveToUndoBuffer = function()",
" if undoPos < #undoBuffer then",
" for a = #undoBuffer, undoPos+1, -1 do",
" table.remove(undoBuffer,a)",
" end",
" end",
" if undoPos >= painconfig.undoBufferSize then",
" for a = 2, #undoBuffer do",
" undoBuffer[a-1] = undoBuffer[a]",
" end",
" undoBuffer[#undoBuffer] = deepCopy(paintEncoded)",
" else",
" undoPos = undoPos + 1",
" undoBuffer[undoPos] = deepCopy(paintEncoded)",
" end",
"end",
"",
"local doUndo = function()",
" undoPos = math.max(1,undoPos-1)",
" paintEncoded = deepCopy(undoBuffer[undoPos])",
" if not paintEncoded[frame] then",
" frame = #paintEncoded",
" end",
"end",
"",
"local doRedo = function()",
" undoPos = math.min(#undoBuffer,undoPos+1)",
" paintEncoded = deepCopy(undoBuffer[undoPos])",
" if not paintEncoded[frame] then",
" frame = #paintEncoded",
" end",
"end",
"",
"local putDownText = function(x,y)",
" term.setCursorPos(x,y)",
" term.setTextColor((paint.doGray and grayOut(paint.t or rendback.t)) or (paint.t or rendback.t))",
" term.setBackgroundColor((paint.doGray and grayOut(paint.b or rendback.b)) or (paint.b or rendback.b))",
" local msg = read()",
" if #msg > 0 then",
" for a = 1, #msg do",
" putDotDown({x=(x+a)-1, y=y, c=msg:sub(a,a)})",
" end",
" end",
" saveToUndoBuffer()",
"end",
"",
"local deleteDot = function(x,y) --deletes all dots at point x,y",
" local good = false",
" for a = #paintEncoded[frame],1,-1 do",
" local b = paintEncoded[frame][a]",
" if (x == b.x) and (y == b.y) then",
" table.remove(paintEncoded[frame],a)",
" good = true",
" end",
" end",
" return good",
"end",
"",
"exportToPaint = function(input,noTransparent) --exports paintEncoded frame to regular paint format. input is expected to be paintEncoded[frame]",
" local doopTXT, doopTXCOL, doopBGCOL = {}, {}, {}",
" local p = input",
" local pheight = 0",
" local pwidth = 0",
" for a = 1, #p do",
" if p[a].y > pheight then",
" pheight = p[a].y",
" end",
" if p[a].x > pwidth then",
" pwidth = p[a].x",
" end",
" end",
" for k,v in pairs(p) do",
" if not doopBGCOL[v.y] then",
" doopBGCOL[v.y] = {}",
" doopTXCOL[v.y] = {}",
" doopTXT[v.y] = {}",
" end",
" doopBGCOL[v.y][v.x] = CTB(v.b)",
" doopTXCOL[v.y][v.x] = CTB(v.t)",
" doopTXT[v.y][v.x] = v.c",
" end",
" local nfpoutputTXT, nfpoutputTXCOL, nfpoutputBGCOL = \"\", \"\", \"\"",
" for y = 1, pheight do",
" if doopBGCOL[y] then",
" for x = 1, pwidth do",
" if doopBGCOL[y][x] then",
" nfpoutputBGCOL = nfpoutputBGCOL..doopBGCOL[y][x]",
" nfpoutputTXCOL = nfpoutputTXCOL..doopTXCOL[y][x]",
" nfpoutputTXT = nfpoutputTXT..(((doopTXT[y][x] == \" \" and noTransparent) and \"€\" or doopTXT[y][x]) or \" \")",
" else",
" nfpoutputBGCOL = nfpoutputBGCOL..(noTransparent and \"0\" or \" \")",
" nfpoutputTXCOL = nfpoutputTXCOL..(noTransparent and \"0\" or \" \")",
" nfpoutputTXT = nfpoutputTXT..\" \"",
" end",
" end",
" end",
" if y ~= pheight then",
" nfpoutputBGCOL = nfpoutputBGCOL..\"\\n\"",
" nfpoutputTXCOL = nfpoutputTXCOL..\"\\n\"",
" nfpoutputTXT = nfpoutputTXT..\"\\n\"",
" end",
" end",
" return nfpoutputBGCOL, pheight, pwidth",
"end",
"",
"local exportToNFT = function(input)",
"",
" local bgcode, txcode = \"\\30\", \"\\31\"",
" local output = \"\"",
" local text, back",
"",
" local doot, pheight, pwidths = tableFormatPE(input)",
"",
" for y = 1, pheight do",
"",
" text, back = \"0\", \"f\"",
" if doot[y] then",
" for x = 1, pwidths[y] do",
"",
" if doot[y][x] then",
" if doot[y][x].back ~= back then",
" back = doot[y][x].back",
" output = output .. bgcode .. back",
" end",
" if doot[y][x].text ~= text then",
" text = doot[y][x].text",
" output = output .. txcode .. text",
" end",
" output = output .. doot[y][x].char",
" else",
" output = output .. \" \"",
" end",
"",
" end",
" end",
"",
" if y < pheight then",
" output = output .. \"\\n\"",
" end",
" end",
" return output",
"end",
"",
"local importFromNFT = function(input) --imports NFT formatted string image to paintEncoded[frame] formatted table image. please return a paintEncoded[frame] formatted table.",
" local tinput = explode(\"\\n\",input)",
" local tcol,bcol",
" local cx --represents the x position in the picture",
" local sx --represents the x position in the file",
" local output = {}",
" for y = 1, #tinput do",
" tcol,bcol = colors.white,colors.black",
" cx, sx = 1, 0",
" while sx < #tinput[y] do",
" sx = sx + 1",
" if tinput[y]:sub(sx,sx) == \"\\30\" then",
" bcol = BTC(tinput[y]:sub(sx+1,sx+1))",
" sx = sx + 1",
" elseif tinput[y]:sub(sx,sx) == \"\\31\" then",
" tcol = BTC(tinput[y]:sub(sx+1,sx+1))",
" sx = sx + 1",
" else",
" if tcol and bcol then",
" output[#output+1] = {",
" [\"x\"] = cx,",
" [\"y\"] = y,",
" [\"b\"] = bcol,",
" [\"t\"] = tcol,",
" [\"c\"] = tinput[y]:sub(sx,sx),",
" [\"m\"] = 0,",
" }",
" end",
" cx = cx + 1",
" end",
" end",
" end",
" return output",
"end",
"",
"exportToBLT = function(input,filename,doAllFrames,noSave)",
" local output = {}",
" local thisImage,pheight,pwidth,nfpinput",
" getBlittle()",
" for a = doAllFrames and 1 or frame, doAllFrames and #input or frame do",
" output[#output+1] = blittle.shrink(NFPserializeImage(exportToPaint(input[a]),true),colors.black)",
" end",
" if #output == 1 then output = output[1] end",
" if not noSave then",
" blittle.save(output,filename)",
" end",
" return output",
"end",
"",
"importFromBLT = function(input) --takes in filename, not contents",
" local output = {}",
" getBlittle()",
" local wholePic = blittle.load(input)",
" if wholePic.height then wholePic = {wholePic} end",
" local image",
" for a = 1, #wholePic do",
" image = wholePic[a]",
" output[#output+1] = {}",
" for y = 1, image.height*3 do",
" for x = 1, math.max(#image[1][math.ceil(y/3)],#image[2][math.ceil(y/3)],#image[3][math.ceil(y/3)])*2 do",
" output[#output][#output[#output]+1] = {",
" m = 0,",
" x = x,",
" y = y,",
" t = BTC((image[2][math.ceil(y/3)]:sub(math.ceil(x/2),math.ceil(x/2))..\"0\"):sub(1,1)),",
" b = BTC((image[3][math.ceil(y/3)]:sub(math.ceil(x/2),math.ceil(x/2))..\"0\"):sub(1,1)),",
" c = BTC((image[1][math.ceil(y/3)]:sub(math.ceil(x/2),math.ceil(x/2))..\" \"):sub(1,1)),",
" }",
" end",
" end",
" end",
" return output",
"end",
"",
"local getTheDoots = function(pe)",
" local hasBadDots = false",
" local baddestX,baddestY = 1,1",
" for b = 1, #pe do",
" local doot = pe[b]",
" if doot.x <= 0 or doot.y <= 0 then",
" hasBadDots = true",
" if doot.x < baddestX then",
" baddestX = doot.x",
" end",
" if doot.y < baddestY then",
" baddestY = doot.y",
" end",
" end",
" if b % 64 == 0 then yield() end",
" end",
" return baddestX, baddestY",
"end",
"",
"local checkBadDots = function()",
" local hasBadDots = false",
" for a = 1, #paintEncoded do",
" local radx,rady = getTheDoots(paintEncoded[a])",
" if radx ~= 1 or rady ~= 1 then",
" hasBadDots = true",
" end",
" end",
" if hasBadDots then",
" local ting = bottomPrompt(\"Dot(s) are OoB! Save or fix? (Y/N/F)\",_,\"ynf\",{keys.leftCtrl,keys.rightCtrl})",
" if ting == \"f\" then",
" for a = 1, #paintEncoded do",
" local baddestX, baddestY = getTheDoots(paintEncoded[a])",
" paintEncoded[a] = movePaintEncoded(paintEncoded[a],-(baddestX-1),-(baddestY-1))",
" end",
" elseif ting ~= \"y\" then",
" barmsg = \"\"",
" return false",
" end",
" end",
"end",
"",
"local convertToGrayscale = function(pe)",
" local output = pe",
" for a = 1, #pe do",
" for b = 1, #pe[a] do",
" output[a][b].b = grayOut(pe[a][b].b)",
" output[a][b].t = grayOut(pe[a][b].t)",
" if not output[a][b].m then output[a][b].m = 1 end",
" end",
" if a % 2 == 0 then yield() end",
" end",
" return output",
"end",
"",
"local reRenderPAIN = function(overrideRenderBar)",
" local _reallyDoRenderBar = doRenderBar",
"-- doRenderBar = 1",
" renderPAIN(paintEncoded[frame],paint.scrollX,paint.scrollY,true,overrideRenderBar)",
" doRenderBar = _reallyDoRenderBar",
"end",
"",
"local fillTool = function(_frame,cx,cy,dot,isDeleting) -- \"_frame\" is the frame NUMBER",
" local maxX, maxY = 1, 1",
" local minX, minY = 1, 1",
" paintEncoded = clearAllRedundant(paintEncoded)",
" local frame = paintEncoded[_frame]",
" local scx, scy = cx+paint.scrollX, cy+paint.scrollY",
" local output = {}",
" for a = 1, #frame do",
" maxX = math.max(maxX, frame[a].x)",
" maxY = math.max(maxY, frame[a].y)",
" minX = math.min(minX, frame[a].x)",
" minY = math.min(minY, frame[a].y)",
" end",
"",
" maxX = math.max(maxX, scx)",
" maxY = math.max(maxY, scy)",
" minX = math.min(minX, scx)",
" minY = math.min(minY, scy)",
"",
" maxX = math.max(maxX, screenEdges[1])",
" maxY = math.max(maxY, screenEdges[2])",
"",
" local doop = {}",
" local touched = {}",
" local check = {[scy] = {[scx] = true}}",
" for y = minY, maxY do",
" doop[y] = {}",
" touched[y] = {}",
" for x = minX, maxX do",
" doop[y][x] = {",
" c = \" \",",
" b = 0,",
" t = 0",
" }",
" touched[y][x] = false",
" end",
" end",
" for a = 1, #frame do",
" doop[frame[a].y][frame[a].x] = {",
" c = frame[a].c,",
" t = frame[a].t,",
" b = frame[a].b",
" }",
" end",
" local initDot = {",
" c = doop[scy][scx].c,",
" t = doop[scy][scx].t,",
" b = doop[scy][scx].b",
" }",
" local chkpos = function(x, y, checkList)",
" if (x < minX or x > maxX) or (y < minY or y > maxY) then",
" return false",
" else",
" if (doop[y][x].b ~= initDot.b) or (doop[y][x].t ~= initDot.t) or (doop[y][x].c ~= initDot.c) then",
" return false",
" end",
" if check[y] then",
" if check[y][x] then",
" return false",
" end",
" end",
" if touched[y][x] then",
" return false",
" end",
" return true",
" end",
" end",
" local doBreak",
" local step = 0",
" local currentlyOnScreen",
" while true do",
" doBreak = true",
" for chY, v in pairs(check) do",
" for chX, isTrue in pairs(v) do",
" currentlyOnScreen = (chX-paint.scrollX >= 1 and chX-paint.scrollX <= scr_x and chY-paint.scrollY >= 1 and chY-paint.scrollY <= scr_y)",
" if isTrue and (not touched[chY][chX]) then",
" step = step + 1",
" if painconfig.doFillAnimation then",
" if currentlyOnScreen then",
" reRenderPAIN(true)",
" end",
" end",
" if isDeleting then",
" deleteDot(chX, chY)",
" else",
" frame[#frame+1] = {",
" x = chX,",
" y = chY,",
" c = dot.c,",
" t = dot.t,",
" b = dot.b",
" }",
" end",
" touched[chY][chX] = true",
" -- check adjacent",
" if chkpos(chX+1, chY) then",
" check[chY][chX+1] = true",
" doBreak = false",
" end",
" if chkpos(chX-1, chY) then",
" check[chY][chX-1] = true",
" doBreak = false",
" end",
" if chkpos(chX, chY+1) then",
" check[chY+1] = check[chY+1] or {}",
" check[chY+1][chX] = true",
" doBreak = false",
" end",
" if chkpos(chX, chY-1) then",
" check[chY-1] = check[chY-1] or {}",
" check[chY-1][chX] = true",
" doBreak = false",
" end",
" -- check diagonal",
" if painconfig.doFillDiagonal then",
" if chkpos(chX-1, chY-1) then",
" check[chY-1] = check[chY-1] or {}",
" check[chY-1][chX-1] = true",
" doBreak = false",
" end",
" if chkpos(chX+1, chY-1) then",
" check[chY-1] = check[chY-1] or {}",
" check[chY-1][chX+1] = true",
" doBreak = false",
" end",
" if chkpos(chX-1, chY+1) then",
" check[chY+1] = check[chY+1] or {}",
" check[chY+1][chX-1] = true",
" doBreak = false",
" end",
" if chkpos(chX+1, chY+1) then",
" check[chY+1] = check[chY+1] or {}",
" check[chY+1][chX+1] = true",
" doBreak = false",
" end",
" end",
" if step % ((painconfig.doFillAnimation and currentlyOnScreen) and 4 or 1024) == 0 then -- tries to prevent crash",
" sleep(0)",
" end",
" end",
" end",
" end",
" if doBreak then",
" break",
" end",
" end",
" paintEncoded = clearAllRedundant(paintEncoded)",
"end",
"",
"local boxCharSelector = function()",
" local co = function(pos)",
" if pos then",
" term.setTextColor(colors.lime)",
" term.setBackgroundColor(colors.green)",
" else",
" term.setTextColor(colors.lightGray)",
" term.setBackgroundColor(colors.gray)",
" end",
" end",
" local rend = function()",
" term.setCursorPos(1,scr_y)",
" term.setBackgroundColor(colors.lightGray)",
" term.setTextColor(colors.black)",
" term.clearLine()",
" term.write(\"Press CTRL or 'N' when ready.\")",
" term.setCursorPos(1,scr_y-3) co(boxchar.topLeft) write(\"Q\") co(boxchar.topRight) write(\"W\")",
" term.setCursorPos(1,scr_y-2) co(boxchar.left) write(\"A\") co(boxchar.right) write(\"S\")",
" term.setCursorPos(1,scr_y-1) co(boxchar.bottomLeft) write(\"Z\") co(boxchar.bottomRight) write(\"X\")",
" end",
" while true do",
" rend()",
" local evt = {os.pullEvent()}",
" if evt[1] == \"key\" then",
" local key = evt[2]",
" if key == keys.leftCtrl or key == keys.rightCtrl or key == keys.n then",
" break",
" else",
" if key == keys.q then boxchar.topLeft = not boxchar.topLeft end",
" if key == keys.w then boxchar.topRight = not boxchar.topRight end",
" if key == keys.a then boxchar.left = not boxchar.left end",
" if key == keys.s then boxchar.right = not boxchar.right end",
" if key == keys.z then boxchar.bottomLeft = not boxchar.bottomLeft end",
" if key == keys.x then boxchar.bottomRight = not boxchar.bottomRight end",
" end",
" elseif evt[1] == \"mouse_click\" or evt[1] == \"mouse_drag\" then",
" local button, mx, my = evt[2], evt[3], evt[4]",
" if my >= scr_y-2 then",
" if mx == 1 then",
" if my == scr_y - 3 then boxchar.topLeft = not boxchar.topLeft end",
" if my == scr_y - 2 then boxchar.left = not boxchar.left end",
" if my == scr_y - 1 then boxchar.bottomLeft = not boxchar.bottomLeft end",
" elseif mx == 2 then",
" if my == scr_y - 3 then boxchar.topRight = not boxchar.topRight end",
" if my == scr_y - 2 then boxchar.right = not boxchar.right end",
" if my == scr_y - 1 then boxchar.bottomRight = not boxchar.bottomRight end",
" elseif evt[1] == \"mouse_click\" then",
" break",
" end",
" elseif evt[1] == \"mouse_click\" then",
" break",
" end",
" end",
" end",
" if boxchar.topLeft and boxchar.topRight and boxchar.left and boxchar.right and boxchar.bottomLeft and boxchar.bottomRight then",
" swapColors = false",
" return \" \"",
" else",
" local output = getDrawingCharacter(boxchar.topLeft, boxchar.topRight, boxchar.left, boxchar.right, boxchar.bottomLeft, boxchar.bottomRight)",
" swapColors = not output.inverted",
" return output.char",
" end",
"end",
"",
"local specialCharSelector = function()",
" local chars = {}",
" local buff = 0",
" for y = 1, 16 do",
" for x = 1, 16 do",
" chars[y] = chars[y] or {}",
" chars[y][x] = string.char(buff)",
" buff = buff + 1",
" end",
" end",
" local sy = scr_y - (#chars + 1)",
" local char = paint.c",
" local render = function()",
" for y = 1, #chars do",
" for x = 1, #chars do",
" term.setCursorPos(x,y+sy)",
" if chars[y][x] == char then",
" term.blit(chars[y][x], \"5\", \"d\")",
" else",
" term.blit(chars[y][x], \"8\", \"7\")",
" end",
" end",
" end",
" end",
" local evt, butt, x, y",
" render()",
"",
" term.setCursorPos(1,scr_y)",
" term.setBackgroundColor(colors.lightGray)",
" term.setTextColor(colors.black)",
" term.clearLine()",
" term.write(\"Press CTRL or 'N' when ready.\")",
"",
" while true do",
" evt, butt, x, y = os.pullEvent()",
" if (evt == \"mouse_click\" or evt == \"mouse_drag\") then",
" if chars[y-sy] then",
" if chars[y-sy][x] then",
" if (chars[y-sy][x] ~= char) then",
" char = chars[y-sy][x]",
" render()",
" end",
" else",
" return char",
" end",
" else",
" return char",
" end",
" elseif evt == \"key\" then",
" if (butt == keys.n) or (butt == keys.leftCtrl) then",
" return char",
" end",
" end",
" end",
"end",
"",
"local dontDragThisTime = false",
"local resetInputState = function()",
" miceDown = {}",
" keysDown = {}",
" isDragging = false",
" dontDragThisTime = true",
"end",
"",
"local gotoCoords = function()",
" local newX = bottomPrompt(\"Goto X:\")",
" newX = tonumber(newX)",
" local newY",
" if newX then",
" newY = bottomPrompt(\"Goto Y:\")",
" newY = tonumber(newY)",
" paint.scrollX = newX or paint.scrollX",
" paint.scrollY = newY or paint.scrollY",
" end",
"end",
"",
"local renderAllPAIN = function()",
" renderPAIN(paintEncoded[frame],paint.scrollX,paint.scrollY,true)",
"end",
"",
"local checkIfNFP = function(str) --does not check table format, only string format",
" local good = {",
" ['0'] = true,",
" ['1'] = true,",
" ['2'] = true,",
" ['3'] = true,",
" ['4'] = true,",
" ['5'] = true,",
" ['6'] = true,",
" ['7'] = true,",
" ['8'] = true,",
" ['9'] = true,",
" a = true,",
" b = true,",
" c = true,",
" d = true,",
" e = true,",
" f = true,",
" [\" \"] = true,",
" [\"\\n\"] = true",
" }",
" for a = 1, #str do",
" if not good[str:sub(a,a):lower()] then",
" return false",
" end",
" end",
" return true",
"end",
"",
"local selectRegion = function()",
" local position = {}",
" local mevt, id, x1, y1 = os.pullEvent(\"mouse_click\")",
" local x2, y2, pos, redrawID",
" local renderRectangle = true",
" redrawID = os.startTimer(0.5)",
" while true do",
" mevt, id, x2, y2 = os.pullEvent()",
" if mevt == \"mouse_up\" or mevt == \"mouse_drag\" or mevt == \"mouse_click\" then",
" pos = {{",
" x1 < x2 and x1 or x2,",
" y1 < y2 and y1 or y2",
" },{",
" x1 < x2 and x2 or x1,",
" y1 < y2 and y2 or y1",
" }}",
" end",
" if mevt == \"mouse_up\" then",
" break",
" end",
" if (mevt == \"mouse_drag\") or (mevt == \"timer\" and id == redrawID) then",
" renderAllPAIN()",
" if renderRectangle then",
" term.setTextColor(rendback.t)",
" term.setBackgroundColor(rendback.b)",
" for y = pos[1][2], pos[2][2] do",
" if y ~= scr_y then",
" term.setCursorPos(pos[1][1], y)",
" if (y == pos[1][2] or y == pos[2][2]) then",
" term.write((\"#\"):rep(1 + pos[2][1] - pos[1][1]))",
" else",
" term.write(\"#\")",
" term.setCursorPos(pos[2][1], y)",
" term.write(\"#\")",
" end",
" end",
" end",
" end",
" end",
" if (mevt == \"timer\" and id == redrawID) then",
" renderRectangle = not renderRectangle",
" redrawID = os.startTimer(0.25)",
" end",
" end",
" local output = {}",
" pos[1][1] = pos[1][1] + paint.scrollX",
" pos[2][1] = pos[2][1] + paint.scrollX",
" pos[1][2] = pos[1][2] + paint.scrollY",
" pos[2][2] = pos[2][2] + paint.scrollY",
" for k,v in pairs(paintEncoded[frame]) do",
" if v.x >= pos[1][1] and v.x <= pos[2][1] then",
" if v.y >= pos[1][2] and v.y <= pos[2][2] then",
" output[#output+1] = {",
" x = v.x - pos[1][1],",
" y = v.y - pos[1][2],",
" t = v.t,",
" c = v.c,",
" b = v.b,",
" m = v.m",
" }",
" end",
" end",
" end",
" return output, pos[1][1], pos[1][2], pos[2][1], pos[2][2]",
"end",
"",
"local openNewFile = function(fname, allowNonImageNFP)",
" local file = fs.open(fname,\"r\")",
" local contents = file.readAll()",
" file.close()",
" if type(tun(contents)) ~= \"table\" then",
" term.setTextColor(colors.white)",
" if contents:sub(1,3) == \"BLT\" then --thank you bomb bloke for this easy identifier",
" if pMode ~= 1 then print(\"Importing from BLT...\") end",
" return importFromBLT(fname), 3",
" elseif contents:sub(1,3) == \"GIF\" then",
" if pMode ~= 1 then print(\"Importing from GIF, this'll take a while...\") end",
" return importFromGIF(fname,true), 5",
" elseif contents:sub(1,4) == \"?!7\\2\" then",
" if pMode ~= 1 then print(\"Importing from UCG...\") end",
" return {importFromUCG(fname)}, 6",
" elseif contents:find(string.char(30)) and contents:find(string.char(31)) then",
" if pMode ~= 1 then print(\"Importing from NFT...\") end",
" return {importFromNFT(contents)}, 2",
" elseif (checkIfNFP(contents) or allowNonImageNFP) then",
" print(\"Importing from NFP...\")",
" return {importFromPaint(contents)}, 1",
" else",
" return false, \"That is not a valid image file.\"",
" end",
" else",
" return tun(contents), 4",
" end",
"end",
"",
"local editCopy = function()",
" local board = bottomPrompt(\"Copy to board: \")",
" renderAllPAIN()",
" renderBottomBar(\"Select region to copy.\")",
" local selectedDots = selectRegion()",
" theClipboard[board] = selectedDots",
" barmsg = \"Copied to '\"..board..\"'\"",
" doRender = true",
" keysDown = {}",
" miceDown = {}",
"end",
"local editCut = function()",
" local board = bottomPrompt(\"Cut to board: \")",
" renderAllPAIN()",
" renderBottomBar(\"Select region to cut.\")",
" local selectedDots, x1, y1, x2, y2 = selectRegion()",
" theClipboard[board] = selectedDots",
" local dot",
" for i = #paintEncoded[frame], 1, -1 do",
" dot = paintEncoded[frame][i]",
" if dot.x >= x1 and dot.x <= x2 then",
" if dot.y >= y1 and dot.y <= y2 then",
" table.remove(paintEncoded[frame], i)",
" end",
" end",
" end",
" barmsg = \"Cut to '\"..board..\"'\"",
" doRender = true",
" saveToUndoBuffer()",
" keysDown = {}",
" miceDown = {}",
"end",
"",
"local editPaste = function()",
" local board = bottomPrompt(\"Paste from board: \")",
" renderAllPAIN()",
" renderBottomBar(\"Click to paste. (top left corner)\")",
" if theClipboard[board] then",
" local mevt",
" repeat",
" mevt = {os.pullEvent()}",
" until (mevt[1] == \"key\" and mevt[2] == keys.x) or (mevt[1] == \"mouse_click\" and mevt[2] == 1 and (mevt[4] or scr_y) <= scr_y-1)",
" for k,v in pairs(theClipboard[board]) do",
" paintEncoded[frame][#paintEncoded[frame]+1] = {",
" x = v.x + paint.scrollX + (mevt[3]),",
" y = v.y + paint.scrollY + (mevt[4]),",
" c = v.c,",
" t = v.t,",
" b = v.b,",
" m = v.m",
" }",
" end",
" paintEncoded[frame] = clearRedundant(paintEncoded[frame])",
" barmsg = \"Pasted from '\"..board..\"'\"",
" doRender = true",
" saveToUndoBuffer()",
" keysDown = {}",
" miceDown = {}",
" else",
" barmsg = \"No such clipboard.\"",
" doRender = true",
" end",
"end",
"",
"local displayMenu = function()",
" menuOptions = {\"File\",\"Edit\",\"Window\",\"Set\",\"About\",\"Exit\"}",
" local diss = \" \"..tableconcat(menuOptions,\" \")",
" local cleary = scr_y-math.floor(#diss/scr_x)",
"",
" local fileSave = function()",
" checkBadDots()",
" local output = deepCopy(paintEncoded)",
" if paint.doGray then",
" output = convertToGrayscale(output)",
" end",
" doRender = true",
" if not fileName then",
" renderBottomBar(\"Save as: \")",
" local fnguess = read()",
" if fs.isReadOnly(fnguess) then",
" barmsg = \"'\"..fnguess..\"' is read only.\"",
" return false",
" elseif fnguess:gsub(\" \",\"\") == \"\" then",
" return false",
" elseif fs.isDir(fnguess) then",
" barmsg = \"'\"..fnguess..\"' is already a directory.\"",
" return false",
" elseif #fnguess > 255 then",
" barmsg = \"Filename is too long.\"",
" return false",
" else",
" fileName = fnguess",
" end",
" end",
" saveFile(fileName,output)",
" term.setCursorPos(9,scr_y)",
" return fileName",
" end",
" local filePrint = function()",
" local usedDots, dot = {}, {}",
" for a = 1, #paintEncoded[frame] do",
" dot = paintEncoded[frame][a]",
" if dot.x > paint.scrollX and dot.x < (paint.scrollX + 25) and dot.y > paint.scrollX and dot.y < (paint.scrollY + 21) then",
" if dot.c ~= \" \" then",
" usedDots[dot.t] = usedDots[dot.t] or {}",
" usedDots[dot.t][#usedDots[dot.t]+1] = {",
" x = dot.x - paint.scrollX,",
" y = dot.y - paint.scrollY,",
" char = dot.c",
" }",
" end",
" end",
" end",
" local dyes = {",
" [1] = \"bonemeal\",",
" [2] = \"orange dye\",",
" [4] = \"magenta dye\",",
" [8] = \"light blue dye\",",
" [16] = \"dandelion yellow\",",
" [32] = \"lime dye\",",
" [64] = \"pink dye\",",
" [128] = \"gray dye\",",
" [256] = \"light gray dye\",",
" [512] = \"cyan dye\",",
" [1024] = \"purple dye\",",
" [2048] = \"lapis lazuli\",",
" [4096] = \"cocoa beans\",",
" [8192] = \"cactus green\",",
" [16384] = \"rose red\",",
" [32768] = \"ink sac\",",
" }",
" local printer = peripheral.find(\"printer\")",
" if not printer then",
" barmsg = \"No printer found.\"",
" return false",
" end",
" local page",
" for color, dotList in pairs(usedDots) do",
" term.setBackgroundColor(colors.black)",
" term.setTextColor((color == colors.black) and colors.gray or color)",
" term.clear()",
" cwrite(\"Please insert \"..dyes[color]..\" into the printer.\", nil, math.floor(scr_y/2))",
" term.setTextColor(colors.lightGray)",
" cwrite(\"Then, press spacebar.\", nil, math.floor(scr_y/2) + 1)",
" local evt",
" sleep(0)",
" repeat",
" evt = {os.pullEvent(\"key\")}",
" until evt[2] == keys.space",
" page = page or printer.newPage()",
" if not page then",
" barmsg = \"Check ink/paper.\"",
" return",
" end",
" for k,v in pairs(usedDots[color]) do",
" printer.setCursorPos(v.x, v.y)",
" printer.write(v.char)",
" end",
" end",
" printer.endPage()",
" barmsg = \"Printed.\"",
" end",
" local fileExport = function(menuX,getRightToIt,_fileName)",
" local exportMode",
" if not tonumber(getRightToIt) then",
" exportMode = makeSubMenu(menuX or 8,scr_y-2,{\"Paint\",\"NFT\",\"BLT\",\"PAIN Native\",\"GIF\",\"UCG\"})",
" else",
" exportMode = getRightToIt",
" end",
" doRender = true",
" if exportMode == false then return false end",
" local pe, exportName, writeIndent, result",
" if exportMode == 4 then",
" local exNm = fileSave()",
" if exNm then",
" changedImage = false",
" return exNm",
" else",
" return nil",
" end",
" else",
" checkBadDots()",
" if _fileName then",
" exportName, writeIndent = _fileName, #_fileName",
" else",
" exportName, writeIndent = bottomPrompt(\"Export to: /\")",
" end",
" nfpoutput = \"\"",
" if fs.combine(\"\",exportName) == \"\" then",
" barmsg = \"Export cancelled.\"",
" return",
" end",
" if fs.isReadOnly(exportName) then",
" barmsg = \"That's read-only.\"",
" return",
" end",
" if fs.exists(exportName) and (not _fileName) then",
" local plea = (progname == fs.combine(\"\",exportName)) and \"Overwrite ORIGINAL file!?\" or \"Overwrite?\"",
" result, _wIn = bottomPrompt(plea..\" (Y/N)\",_,\"yn\",{keys.leftCtrl,keys.rightCtrl})",
" writeIndent = writeIndent + _wIn",
" if result ~= \"y\" then return end",
" end",
" local output",
" pe = deepCopy(paintEncoded)",
" if paint.doGray then",
" pe = convertToGrayscale(pe)",
" end",
" local doSerializeBLT = false",
" end",
" if exportMode == 1 then",
" output = exportToPaint(pe[frame])",
" if askToSerialize then",
" result, _wIn = bottomPrompt(\"Save as serialized? (Y/N)\",_,\"yn\",{})",
" writeIndent = writeIndent + _wIn",
" else result, _wIn = \"n\", 0 end",
" if result == \"y\" then",
" output = textutils.serialize(NFPserializeImage(output)):gsub(\" \",\"\"):gsub(\"\\n\",\"\"):gsub(\",}\",\"}\")",
" end",
" elseif exportMode == 2 then",
" output = exportToNFT(pe[frame])",
" elseif exportMode == 3 then",
" local doAllFrames, _wIn = bottomPrompt(\"Save all frames, or current? (Y/N)\",_,\"yn\",{keys.leftCtrl,keys.rightCtrl},writeIndent)",
" writeIndent = writeIndent + _wIn",
" if askToSerialize then",
" doSerializeBLT = bottomPrompt(\"Save as serialized? (Y/N)\",_,\"yn\",{},writeIndent) == \"y\"",
" end",
" output = textutils.serialise(exportToBLT(pe,exportName,doAllFrames == \"y\",doSerializeBLT))",
" elseif exportMode == 5 then",
" getGIF()",
" GIF.saveGIF(exportToGIF(pe),exportName)",
" elseif exportMode == 6 then",
" exportToUCG(exportName,pe[frame])",
" end",
" if ((exportMode ~= 3) and (exportMode ~= 4) and (exportMode ~= 5) and (exportMode ~= 6)) or doSerializeBLT then",
" local file = fs.open(exportName,\"w\")",
" file.write(output)",
" file.close()",
" end",
" return exportName",
" end",
"",
" local editClear = function(ignorePrompt)",
" local outcum = ignorePrompt and \"y\" or bottomPrompt(\"Clear the frame? (Y/N)\",_,\"yn\",{keys.leftCtrl,keys.rightCtrl})",
" if outcum == \"y\" then",
" paintEncoded[frame] = {}",
" saveToUndoBuffer()",
" barmsg = \"Cleared frame \"..frame..\".\"",
" end",
" doRender = true",
" end",
"",
" local editDelFrame = function()",
" local outcum = bottomPrompt(\"Thou art sure? (Y/N)\",_,\"yn\",{keys.leftCtrl,keys.rightCtrl})",
" doRender = true",
" if outcum == \"y\" then",
" if #paintEncoded == 1 then",
" return editClear(true)",
" end",
" table.remove(paintEncoded,frame)",
" barmsg = \"Deleted frame \"..frame..\".\"",
" if paintEncoded[frame-1] then",
" frame = frame - 1",
" else",
" frame = frame + 1",
" end",
" if #paintEncoded < frame then",
" repeat",
" frame = frame - 1",
" until #paintEncoded >= frame",
" end",
" saveToUndoBuffer()",
" end",
" end",
" local editCrop = function()",
" local outcum = bottomPrompt(\"Crop all but visible? (Y/N)\",_,\"yn\",{keys.leftCtrl,keys.rightCtrl})",
" if outcum == \"y\" then",
" local ppos = 1",
" local deletedAmnt = 0",
" for a = #paintEncoded[frame], 1, -1 do",
" local x, y = paintEncoded[frame][a].x, paintEncoded[frame][a].y",
" if (x <= paint.scrollX) or (x > paint.scrollX + scr_x) or (y <= paint.scrollY) or (y > paint.scrollY + scr_y) then",
" table.remove(paintEncoded[frame],a)",
" deletedAmnt = deletedAmnt + 1",
" else",
" ppos = ppos + 1",
" end",
" if ppos > #paintEncoded[frame] then break end",
" end",
" saveToUndoBuffer()",
" barmsg = \"Cropped frame.\"",
" end",
" doRender = true",
" end",
" local editBoxCharSelector = function()",
" paint.c = boxCharSelector()",
" end",
" local editSpecialCharSelector = function()",
" paint.c = boxCharSelector()",
" end",
"",
" local windowSetScrSize = function()",
" local x,y",
" x = bottomPrompt(\"Scr.X OR monitor name:\",{},nil,{keys.leftCtrl,keys.rightCtrl})",
" if x == \"\" then",
" return",
" elseif x == \"pocket\" then",
" screenEdges = {26,20}",
" elseif x == \"turtle\" then",
" screenEdges = {39,13}",
" elseif x == \"computer\" then",
" screenEdges = {51,19}",
" elseif tonumber(x) then",
" if tonumber(x) <= 0 then",
" barmsg = \"Screen X must be greater than 0.\"",
" return",
" end",
" screenEdges[1] = math.abs(tonumber(x))",
" y = bottomPrompt(\"Scr.Y:\",{},nil,{keys.leftCtrl,keys.rightCtrl})",
" if tonumber(y) then",
" if tonumber(y) <= 0 then",
" barmsg = \"Screen Y must be greater than 0.\"",
" return",
" end",
" screenEdges[2] = math.abs(tonumber(y))",
" end",
" barmsg = \"Screen size changed.\"",
" else",
" local mon = peripheral.wrap(x)",
" if not mon then",
" barmsg = \"No such monitor.\"",
" return",
" else",
" if peripheral.getType(x) ~= \"monitor\" then",
" barmsg = \"That's not a monitor.\"",
" return",
" else",
" screenEdges[1], screenEdges[2] = mon.getSize()",
" barmsg = \"Screen size changed.\"",
" return",
" end",
" end",
" end",
" end",
" local aboutPAIN = function()",
" local helpText = [[",
"",
"     ",
"       ",
"     ",
"      ",
"      ",
"",
"Advanced Paint Program",
" by LDDestroier",
" or EldidiStroyrr",
" if you please!",
"",
"PAIN is a multi-frame paint program with the intention of becoming a stable, well-used, and mondo-useful CC drawing utility.",
"",
"The main focus during development is to add more functions that you might see in MSPAINT such as lines or a proper fill tool (which I don't have, grr hiss boo), as well as to export/import to and from as many image formats as possible.",
"",
"My ultimate goal is to have PAIN be the default paint program for most every operating system on the forums. In order to do this, I'll need to make sure that PAIN is stable, easy to use, and can be easily limited by an OS to work with more menial tasks like making a single icon or what have you.",
"]]",
" guiHelp(helpText)",
" end",
" local aboutFileFormats = function()",
" local helpText = [[",
"Here's info on the file formats.",
"",
" \"NFP\":",
"Used in rom/programs/paint, and the format for paintutils. It's a handy format, but the default rendering function is inefficient as hell, and it does not store text data, only background.",
"Cannot save multiple frames.",
"",
" \"NFT\":",
"Used in npaintpro and most everything else, it's my favorite of the file formats because it does what NFP does, but allows for text in the pictures. Useful for storing screenshots or small icons where an added level of detail is handy. Created by nitrogenfingers, thank him.",
"Cannot save multiple frames.",
"",
" \"BLT\":",
"Used exclusively with Bomb Bloke's BLittle API, and as such is handy with making pictures with block characters. Just keep in mind that those 2*3 grid squares in PAIN represent individual characters in BLT.",
"BLT can save multiple frames!",
"",
" \"PAIN Native\":",
"The basic, tabular, and wholly inefficient format that PAIN uses. Useful for doing math within the program, not so much for long term file storage. It stores text, but just use NFT if you don't need multiple frames.",
"Obviously, this can save multiple frames.",
"",
" \"GIF\":",
"The API was made by Bomb Bloke, huge thanks for that, but GIF is a universal file format used in real paint programs. Very useful for converting files on your computer to something like NFP, but doesn't store text. Be careful when opening up big GIF files, they can take a long time to load.",
"Being GIF, this saves multiple frames!",
"",
" \"UCG\":",
"Stands for Universal Compressed Graphics. This format was made by ardera, and uses Huffman Code and run-length encoding in order to reduce file sizes tremendously. However, it only saves backgrounds and not text data.",
"Cannot save multiple frames.",
"",
"",
"I recommend using NFT if you don't need multiple frames, NFP if you don't need text, UCG if the picture is really big, Native PAIN if you need both text and multiframe support, and GIF if you want to use something like MS Paint or Pinta or GIMP or whatever.",
"]]",
" guiHelp(helpText)",
" end",
" local menuPoses = {}",
" local menuFunctions = {",
" [1] = function() --File",
" while true do",
" --renderAllPAIN()",
" local output, longestLen = makeSubMenu(1,cleary-1,{",
" \"Save\",",
" \"Save As\",",
" \"Export\",",
" \"Open\",",
" ((peripheral.find(\"printer\")) and \"Print\" or nil)",
" })",
" doRender = true",
" if output == 1 then -- Save",
" local _fname = fileExport(_,defaultSaveFormat,fileName)",
" if _fname then",
" barmsg = \"Saved as '\".._fname..\"'\"",
" lastPaintEncoded = deepCopy(paintEncoded)",
" changedImage = false",
" end",
" break",
" elseif output == 2 then -- Save As",
" local oldfilename = fileName",
" fileName = nil",
" local res = fileExport(_,defaultSaveFormat)",
" if not res then",
" fileName = oldfilename",
" end",
" barmsg = \"Saved as '\"..fileName..\"'\"",
" elseif output == 3 then --Export",
" local res = fileExport(longestLen+1)",
" if res then",
" barmsg = \"Exported as '\"..res..\"'\"",
" break",
" end",
" elseif output == 4 then -- Open",
" renderBottomBar(\"Pick an image file.\")",
" local newPath = lddfm.makeMenu(2, 2, scr_x-1, scr_y-2, fs.getDir(fileName or progname), false, false, false, true, false, nil, true)",
" if newPath then",
" local pen, form = openNewFile(newPath, painconfig.readNonImageAsNFP)",
" if not pen then",
" barmsg = form",
" else",
" fileName = newPath",
" paintEncoded, lastPaintEncoded = pen, deepCopy(pen)",
" defaultSaveFormat = form",
" undoPos = 1",
" undoBuffer = {deepCopy(paintEncoded)}",
" barmsg = \"Opened '\" .. fs.getName(newPath) .. \"'\"",
" paint.scrollX, paint.scrollY, paint.doGray = 1, 1, false",
" doRender = true",
" end",
" end",
" break",
" elseif output == 5 then -- Print",
" filePrint()",
" break",
" elseif output == false then",
" return \"nobreak\"",
" end",
" reRenderPAIN(true)",
" end",
" end,",
" [2] = function() --Edit",
" local output = makeSubMenu(6,cleary-1,{",
" \"Delete Frame\",",
" \"Clear Frame\",",
" \"Crop Frame\",",
" \"Choose Box Character\",",
" \"Choose Special Character\",",
" \"BLittle Shrink\",",
" \"Copy Region\",",
" \"Cut Region\",",
" \"Paste Region\"",
" })",
" doRender = true",
" if output == 1 then",
" editDelFrame()",
" elseif output == 2 then",
" editClear()",
" elseif output == 3 then",
" editCrop()",
" elseif output == 4 then",
" editBoxCharSelector()",
" elseif output == 5 then",
" editSpecialCharSelector()",
" elseif output == 6 then",
" local res = bottomPrompt(\"You sure? It's unreversable! (Y/N)\",_,\"yn\",{keys.leftCtrl,keys.rightCtrl})",
" if res == \"y\" then",
" getBlittle()",
" local bltPE = blittle.shrink(NFPserializeImage(exportToPaint(paintEncoded[frame])))",
" _G.SHRINKOUT = bltPE",
" paintEncoded[frame] = {}",
" for y = 1, bltPE.height do",
" for x = 1, bltPE.width do",
" paintEncoded[frame][#paintEncoded[frame]+1] = {",
" c = bltPE[1][y]:sub(x,x),",
" t = BTC(bltPE[2][y]:sub(x,x),true),",
" b = BTC(bltPE[3][y]:sub(x,x),true),",
" x = x,",
" y = y,",
" }",
" end",
" end",
" saveToUndoBuffer()",
" doRender = true",
" barmsg = \"Shrunk image.\"",
" end",
" elseif output == 7 then",
" editCopy()",
" elseif output == 8 then",
" editCut()",
" elseif output == 9 then",
" editPaste()",
" elseif output == false then",
" return \"nobreak\"",
" end",
" end,",
" [3] = function() --Window",
" local output = makeSubMenu(11,cleary-1,{",
" \"Set Screen Size\",",
" \"Set Scroll XY\",",
" \"Set Grid Colors\"",
" })",
" doRender = true",
" if output == 1 then",
" windowSetScrSize()",
" elseif output == 2 then",
" gotoCoords()",
" elseif output == 3 then",
" rendback.b = paint.b",
" rendback.t = paint.t",
" doRender = true",
" elseif output == false then",
" return \"nobreak\"",
" end",
" end,",
" [4] = function() --Set",
" local output = makeSubMenu(17,cleary-1,{",
" (painconfig.readNonImageAsNFP and \"(T)\" or \"(F)\") .. \" Load Non-images\",",
" (painconfig.useFlattenGIF and \"(T)\" or \"(F)\") .. \" Flatten GIFs\",",
" (painconfig.gridBleedThrough and \"(T)\" or \"(F)\") .. \" Always Render Grid\",",
" (painconfig.doFillDiagonal and \"(T)\" or \"(F)\") .. \" Fill Diagonally\",",
" (painconfig.doFillAnimation and \"(T)\" or \"(F)\") .. \" Do Fill Animation\",",
" \"(\" .. painconfig.undoBufferSize .. \") Set Undo Buffer Size\",",
" })",
" if output == 1 then",
" painconfig.readNonImageAsNFP = not painconfig.readNonImageAsNFP",
" elseif output == 2 then",
" painconfig.useFlattenGIF = not painconfig.useFlattenGIF",
" elseif output == 3 then",
" painconfig.gridBleedThrough = not painconfig.gridBleedThrough",
" elseif output == 4 then",
" painconfig.doFillDiagonal = not painconfig.doFillDiagonal",
" elseif output == 5 then",
" painconfig.doFillAnimation = not painconfig.doFillAnimation",
" elseif output == 6 then",
" local newUndoBufferSize = bottomPrompt(\"New undo buffer size: \")",
" if tonumber(newUndoBufferSize) then",
" painconfig.undoBufferSize = math.abs(tonumber(newUndoBufferSize))",
" undoBuffer = {deepCopy(paintEncoded)}",
" undoPos = 1",
" else",
" return",
" end",
" end",
" saveConfig()",
" end,",
" [5] = function() --About",
" local output = makeSubMenu(17,cleary-1,{",
" \"PAIN\",",
" \"File Formats\",",
" \"Help!\"",
" })",
" doRender = true",
" if output == 1 then",
" aboutPAIN()",
" elseif output == 2 then",
" aboutFileFormats()",
" elseif output == 3 then",
" guiHelp()",
" doRender = true",
" end",
" end,",
" [6] = function() --Exit",
" if changedImage then",
" local outcum = bottomPrompt(\"Abandon unsaved work? (Y/N)\",_,\"yn\",{keys.leftCtrl,keys.rightCtrl})",
" sleep(0)",
" if outcum == \"y\" then",
" return \"exit\"",
" else",
" doRender = true",
" return nil",
" end",
" else",
" return \"exit\"",
" end",
" end,",
" }",
" local cursor = 1",
" local redrawmenu = true",
" local initial = os.time()",
" local clickdelay = 0.003",
"",
" local redrawTheMenu = function()",
" for a = cleary,scr_y do",
" term.setCursorPos(1,a)",
" term.setBackgroundColor(colors.lightGray)",
" term.clearLine()",
" end",
" term.setCursorPos(2,cleary)",
" for a = 1, #menuOptions do",
" if a == cursor then",
" term.setTextColor(colors.black)",
" term.setBackgroundColor(colors.white)",
" else",
" term.setTextColor(colors.black)",
" term.setBackgroundColor(colors.lightGray)",
" end",
" menuPoses[a] = {term.getCursorPos()}",
" write(menuOptions[a])",
" term.setBackgroundColor(colors.lightGray)",
" if a ~= #menuOptions then",
" write(\" \")",
" end",
" end",
" redrawmenu = false",
" end",
"",
" while true do",
" if redrawmenu then",
" redrawTheMenu()",
" redrawmenu = false",
" end",
" local event,key,x,y = getEvents(\"key\",\"char\",\"mouse_click\",\"mouse_up\",\"mouse_drag\")",
" if event == \"key\" then",
" if key == keys.left then",
" redrawmenu = true",
" cursor = cursor - 1",
" elseif key == keys.right then",
" redrawmenu = true",
" cursor = cursor + 1",
" elseif key == keys.enter then",
" redrawmenu = true",
" local res = menuFunctions[cursor]()",
" resetInputState()",
" if res == \"exit\" then",
" return \"exit\"",
" elseif res == \"nobreak\" then",
" reRenderPAIN(true)",
" else",
" return",
" end",
" elseif key == keys.leftCtrl or key == keys.rightCtrl then",
" doRender = true",
" return",
" end",
" elseif event == \"char\" then",
" for a = 1, #menuOptions do",
" if key:lower() == menuOptions[a]:sub(1,1):lower() and a ~= cursor then",
" cursor = a",
" redrawmenu = true",
" break",
" end",
" end",
" elseif event == \"mouse_click\" or event == \"mouse_up\" then",
" if y < cleary then",
" doRender = true",
" resetInputState()",
" return",
" elseif key == 1 and initial+clickdelay < os.time() then --key? more like button",
" for a = 1, #menuPoses do",
" if y == menuPoses[a][2] then",
" if x >= menuPoses[a][1] and x <= menuPoses[a][1]+#menuOptions[a] then",
" cursor = a",
" redrawTheMenu()",
" local res = menuFunctions[a]()",
" os.queueEvent(\"queue\")",
" os.pullEvent(\"queue\")",
" resetInputState()",
" if res == \"exit\" then",
" return \"exit\"",
" else",
" return",
" end",
" end",
" end",
" end",
" end",
" end",
" if (initial+clickdelay < os.time()) and string.find(event,\"mouse\") then",
" if key == 1 then --key? key? what key? all I see is button!",
" for a = 1, #menuPoses do",
" if y == menuPoses[a][2] then",
" if x >= menuPoses[a][1] and x <= menuPoses[a][1]+#menuOptions[a] then",
" cursor = a",
" redrawmenu = true",
" break",
" end",
" end",
" end",
" end",
" end",
" if cursor < 1 then",
" cursor = #menuOptions",
" elseif cursor > #menuOptions then",
" cursor = 1",
" end",
" end",
"end",
"",
"local lastMX,lastMY,isDragging",
"",
"local doNonEventDrivenMovement = function() --what a STUPID function name, dude",
" local didMove",
" while true do",
" didMove = false",
" if (not keysDown[keys.leftShift]) and (not isDragging) and (not keysDown[keys.tab]) then",
" if keysDown[keys.right] then",
" paint.scrollX = paint.scrollX + 1",
" didMove = true",
" elseif keysDown[keys.left] then",
" paint.scrollX = paint.scrollX - 1",
" didMove = true",
" end",
" if keysDown[keys.down] then",
" paint.scrollY = paint.scrollY + 1",
" didMove = true",
" elseif keysDown[keys.up] then",
" paint.scrollY = paint.scrollY - 1",
" didMove = true",
" end",
" if didMove then",
" if lastMX and lastMY then",
" if miceDown[1] then",
" os.queueEvent(\"mouse_click\",1,lastMX,lastMY)",
" end",
" if miceDown[2] then",
" os.queueEvent(\"mouse_click\",2,lastMX,lastMY)",
" end",
" end",
" doRender = true",
" end",
" end",
" sleep(0)",
" end",
"end",
"",
"local linePoses = {}",
"local dragPoses = {}",
"",
"local listAllMonitors = function()",
" term.setBackgroundColor(colors.gray)",
" term.setTextColor(colors.white)",
" local periphs = peripheral.getNames()",
" local mons = {}",
" for a = 1, #periphs do",
" if peripheral.getType(periphs[a]) == \"monitor\" then",
" mons[#mons+1] = periphs[a]",
" end",
" end",
" if #mons == 0 then",
" mons[1] = \"No monitors found.\"",
" end",
" term.setCursorPos(3,1)",
" term.clearLine()",
" term.setTextColor(colors.yellow)",
" term.write(\"All monitors:\")",
" term.setTextColor(colors.white)",
" for y = 1, #mons do",
" term.setCursorPos(2,y+1)",
" term.clearLine()",
" term.write(mons[y])",
" end",
" sleep(0)",
" getEvents(\"char\",\"mouse_click\")",
" doRender = true",
"end",
"",
"local getInput = function() --gotta catch them all",
" local button, x, y, oldmx, oldmy, origx, origy",
" local isDragging = false",
" local proceed = false",
" renderBar(barmsg)",
" while true do",
" doRender = false",
" local oldx,oldy = paint.scrollX,paint.scrollY",
" local evt = {getEvents(\"mouse_scroll\",\"mouse_click\", \"mouse_drag\",\"mouse_up\",\"key\",\"key_up\",true)}",
" if (evt[1] == \"mouse_scroll\") and (not viewing) then",
" local dir = evt[2]",
" if dir == 1 then",
" if keysDown[keys.leftShift] or keysDown[keys.rightShift] then",
" paint.t = paint.t * 2",
" if paint.t > 32768 then",
" paint.t = 32768",
" end",
" else",
" paint.b = paint.b * 2",
" if paint.b > 32768 then",
" paint.b = 32768",
" end",
" end",
" else",
" if keysDown[keys.leftShift] or keysDown[keys.rightShift] then",
" paint.t = math.ceil(paint.t / 2)",
" if paint.t < 1 then",
" paint.t = 1",
" end",
" else",
" paint.b = math.ceil(paint.b / 2)",
" if paint.b < 1 then",
" paint.b = 1",
" end",
" end",
" end",
" renderBar(barmsg)",
" elseif ((evt[1] == \"mouse_click\") or (evt[1] == \"mouse_drag\")) and (not viewing) then",
" if evt[1] == \"mouse_click\" then",
" origx, origy = evt[3], evt[4]",
" end",
" oldmx,oldmy = x or evt[3], y or evt[4]",
" lastMX,lastMY = evt[3],evt[4]",
" button,x,y = evt[2],evt[3],evt[4]",
" if renderBlittle then",
" x = 2*x",
" y = 3*y",
" lastMX = 2*lastMX",
" lastMY = 3*lastMY",
" end",
" linePoses = {{x=oldmx,y=oldmy},{x=x,y=y}}",
" miceDown[button] = true",
" if y <= scr_y-(renderBlittle and 0 or doRenderBar) then",
" if (button == 3) then",
" putDownText(x,y)",
" miceDown = {}",
" keysDown = {}",
" doRender = true",
" elseif button == 1 then",
" if keysDown[keys.leftShift] and evt[1] == \"mouse_click\" then",
" isDragging = true",
" end",
" if isDragging then",
" if evt[1] == \"mouse_click\" or dontDragThisTime then",
" dragPoses[1] = {x=x,y=y}",
" end",
" dragPoses[2] = {x=x,y=y}",
" local points = getDotsInLine(dragPoses[1].x,dragPoses[1].y,dragPoses[2].x,dragPoses[2].y)",
" renderAllPAIN()",
" for a = 1, #points do",
" term.setCursorPos(points[a].x, points[a].y)",
" term.blit(paint.c, CTB(paint.t), CTB(paint.b))",
" end",
" elseif (not dontDragThisTime) then",
" if evt[1] == \"mouse_drag\" then",
" local points = getDotsInLine(linePoses[1].x,linePoses[1].y,linePoses[2].x,linePoses[2].y)",
" for a = 1, #points do",
" putDotDown({x=points[a].x, y=points[a].y})",
" end",
" else",
" putDotDown({x=x, y=y})",
" end",
" changedImage = true",
" doRender = true",
" end",
" dontDragThisTime = false",
" elseif button == 2 and y <= scr_y-(renderBlittle and 0 or doRenderBar) then",
" deleteDot(x+paint.scrollX,y+paint.scrollY)",
" changedImage = true",
" doRender = true",
" end",
" elseif origy >= scr_y-(renderBlittle and 0 or doRenderBar) then",
" miceDown = {}",
" keysDown = {}",
" isDragging = false",
" local res = displayMenu()",
" if res == \"exit\" then break end",
" doRender = true",
" end",
" elseif (evt[1] == \"mouse_up\") and (not viewing) and (not isCurrentlyFilling) then",
" origx,origy = 0,0",
" local button = evt[2]",
" miceDown[button] = false",
" oldmx,oldmy = nil,nil",
" lastMX, lastMY = nil,nil",
" if isDragging then",
" local points = getDotsInLine(dragPoses[1].x,dragPoses[1].y,dragPoses[2].x,dragPoses[2].y)",
" for a = 1, #points do",
" putDotDown({x=points[a].x, y=points[a].y})",
" end",
" changedImage = true",
" doRender = true",
" end",
" saveToUndoBuffer()",
" isDragging = false",
" elseif evt[1] == \"key\" then",
" local key = evt[2]",
" if (isDragging or not keysDown[keys.leftShift]) and (keysDown[keys.tab]) then",
" if key == keys.right and (not keysDown[keys.right]) then",
" paint.scrollX = paint.scrollX + 1",
" doRender = true",
" elseif key == keys.left and (not keysDown[keys.left]) then",
" paint.scrollX = paint.scrollX - 1",
" doRender = true",
" end",
" if key == keys.down and (not keysDown[keys.down]) then",
" paint.scrollY = paint.scrollY + 1",
" doRender = true",
" elseif key == keys.up and (not keysDown[keys.up]) then",
" paint.scrollY = paint.scrollY - 1",
" doRender = true",
" end",
" end",
" keysDown[key] = true",
" if key == keys.space then",
" if keysDown[keys.leftShift] then",
" evenDrawGrid = not evenDrawGrid",
" else",
" doRenderBar = math.abs(doRenderBar-1)",
" end",
" doRender = true",
" end",
" if key == keys.b then",
" local blTerm, oldTerm = getBlittle()",
" renderBlittle = not renderBlittle",
" isDragging = false",
" term.setBackgroundColor(rendback.b)",
" term.clear()",
" if renderBlittle then",
" term.redirect(blTerm)",
" blTerm.setVisible(true)",
" else",
" term.redirect(oldTerm)",
" blTerm.setVisible(false)",
" end",
" doRender = true",
" scr_x, scr_y = term.current().getSize()",
" end",
" if keysDown[keys.leftAlt] then",
" if (not renderBlittle) then",
" if (key == keys.c) then",
" editCopy()",
" elseif (key == keys.x) then",
" editCut()",
" elseif (key == keys.v) then",
" editPaste()",
" end",
" end",
" else",
" if (key == keys.c) and (not renderBlittle) then",
" gotoCoords()",
" resetInputState()",
" doRender = true",
" end",
" end",
" if (keysDown[keys.leftShift]) and (not isDragging) then",
" if key == keys.left then",
" paintEncoded[frame] = movePaintEncoded(paintEncoded[frame],-1,0)",
" saveToUndoBuffer()",
" doRender = true",
" changedImage = true",
" elseif key == keys.right then",
" paintEncoded[frame] = movePaintEncoded(paintEncoded[frame],1,0)",
" saveToUndoBuffer()",
" doRender = true",
" changedImage = true",
" elseif key == keys.up then",
" paintEncoded[frame] = movePaintEncoded(paintEncoded[frame],0,-1)",
" saveToUndoBuffer()",
" doRender = true",
" changedImage = true",
" elseif key == keys.down then",
" paintEncoded[frame] = movePaintEncoded(paintEncoded[frame],0,1)",
" saveToUndoBuffer()",
" doRender = true",
" changedImage = true",
" end",
" end",
" if keysDown[keys.leftAlt] then",
" if #paintEncoded > 1 then",
" if key == keys.equals and paintEncoded[frame+1] then --basically plus",
" local first = deepCopy(paintEncoded[frame])",
" local next = deepCopy(paintEncoded[frame+1])",
" paintEncoded[frame] = next",
" paintEncoded[frame+1] = first",
" frame = frame + 1",
" barmsg = \"Swapped prev frame.\"",
" doRender = true",
" changedImage = true",
" saveToUndoBuffer()",
" end",
" if key == keys.minus and paintEncoded[frame-1] then",
" local first = deepCopy(paintEncoded[frame])",
" local next = deepCopy(paintEncoded[frame-1])",
" paintEncoded[frame] = next",
" paintEncoded[frame-1] = first",
" frame = frame - 1",
" barmsg = \"Swapped next frame.\"",
" doRender = true",
" changedImage = true",
" saveToUndoBuffer()",
" end",
" end",
" elseif keysDown[keys.leftShift] then",
" if #paintEncoded > 1 then",
" if key == keys.equals and paintEncoded[frame+1] then --basically plus",
" for a = 1, #paintEncoded[frame] do",
" paintEncoded[frame+1][#paintEncoded[frame+1] + 1] = paintEncoded[frame][a]",
" end",
" table.remove(paintEncoded, frame)",
" paintEncoded = clearAllRedundant(paintEncoded)",
" barmsg = \"Merged next frame.\"",
" doRender = true",
" changedImage = true",
" saveToUndoBuffer()",
" end",
" if key == keys.minus and paintEncoded[frame-1] then",
" for a = 1, #paintEncoded[frame] do",
" paintEncoded[frame-1][#paintEncoded[frame-1] + 1] = paintEncoded[frame][a]",
" end",
" table.remove(paintEncoded, frame)",
" frame = frame - 1",
" paintEncoded = clearAllRedundant(paintEncoded)",
" barmsg = \"Merged previous frame.\"",
" doRender = true",
" changedImage = true",
" saveToUndoBuffer()",
" end",
" end",
" else",
" if key == keys.equals then --basically 'plus'",
" if renderBlittle then",
" frame = frame + 1",
" if frame > #paintEncoded then frame = 1 end",
" else",
" if not paintEncoded[frame+1] then",
" paintEncoded[frame+1] = {}",
" local sheet = paintEncoded[frame]",
" if keysDown[keys.rightShift] then",
" paintEncoded[frame+1] = deepCopy(sheet)",
" end",
" end",
" frame = frame + 1",
" end",
" saveToUndoBuffer()",
" doRender = true",
" changedImage = true",
" elseif key == keys.minus then",
" if renderBlittle then",
" frame = frame - 1",
" if frame < 1 then frame = #paintEncoded end",
" else",
" if frame > 1 then",
" frame = frame - 1",
" end",
" end",
" saveToUndoBuffer()",
" doRender = true",
" changedImage = true",
" end",
" end",
" if not renderBlittle then",
" if key == keys.m then",
" local incum = bottomPrompt(\"Set meta: \",metaHistory)",
" paint.m = incum:gsub(\" \",\"\") ~= \"\" and incum or paint.m",
" if paint.m ~= metaHistory[#metaHistory] then",
" metaHistory[#metaHistory+1] = paint.m",
" end",
" doRender = true",
" isDragging = false",
" end",
" if key == keys.f7 then",
" bepimode = not bepimode",
" doRender = true",
" end",
" if key == keys.t then",
" renderBottomBar(\"Click to place text.\")",
" local mevt",
" repeat",
" mevt = {os.pullEvent()}",
" until (mevt[1] == \"key\" and mevt[2] == keys.x) or (mevt[1] == \"mouse_click\" and mevt[2] == 1 and (mevt[4] or scr_y) <= scr_y-(renderBlittle and 0 or doRenderBar))",
" if not (mevt[1] == \"key\" and mevt[2] == keys.x) then",
" local x,y = mevt[3],mevt[4]",
" if renderBlittle then",
" x = 2*x",
" y = 3*y",
" end",
" putDownText(x,y)",
" miceDown = {}",
" keysDown = {}",
" end",
" doRender = true",
" changedImage = true",
" isDragging = false",
" end",
" if key == keys.f and not (keysDown[keys.leftShift] or keysDown[keys.rightShift]) and (not isCurrentlyFilling) then",
" renderBottomBar(\"Click to fill area.\")",
" local mevt",
" repeat",
" mevt = {os.pullEvent()}",
" until (mevt[1] == \"key\" and mevt[2] == keys.x) or (mevt[1] == \"mouse_click\" and mevt[2] <= 2 and (mevt[4] or scr_y) <= scr_y-(renderBlittle and 0 or doRenderBar))",
" if not (mevt[1] == \"key\" and mevt[2] == keys.x) then",
" local x,y = mevt[3],mevt[4]",
" if renderBlittle then",
" x = 2*x",
" y = 3*y",
" end",
" miceDown = {}",
" keysDown = {}",
" os.queueEvent(\"filltool_async\", frame, x, y, paint, mevt[2] == 2)",
" end",
" doRender = true",
" changedImage = true",
" isDragging = false",
" end",
" if key == keys.p then",
" renderBottomBar(\"Pick color with cursor:\")",
" paintEncoded = clearAllRedundant(paintEncoded)",
" local mevt",
" repeat",
" mevt = {os.pullEvent()}",
" until (mevt[1] == \"key\" and mevt[2] == keys.x) or (mevt[2] == 1 and mevt[4] <= scr_y)",
" if not (mevt[1] == \"key\" and mevt[2] == keys.x) then",
" local x, y = mevt[3]+paint.scrollX, mevt[4]+paint.scrollY",
" if renderBlittle then",
" x = 2*x",
" y = 3*y",
" end",
" local p",
" for a = 1, #paintEncoded[frame] do",
" p = paintEncoded[frame][a]",
" if (p.x == x) and (p.y == y) then",
" paint.t = p.t or paint.t",
" paint.b = p.b or paint.b",
" paint.c = p.c or paint.c",
" paint.m = p.m or paint.m",
" miceDown = {}",
" keysDown = {}",
" doRender = true",
" isDragging = false",
" break",
" end",
" end",
" resetInputState()",
" end",
" doRender = true",
" isDragging = false",
" end",
" if (key == keys.leftCtrl or key == keys.rightCtrl) then",
" keysDown = {[207] = keysDown[207]}",
" isDragging = false",
" local res = displayMenu()",
" paintEncoded = clearAllRedundant(paintEncoded)",
" if res == \"exit\" then break end",
" doRender = true",
" end",
" end",
" if (key == keys.f and keysDown[keys.leftShift]) then",
" local deredots = {}",
" changedImage = true",
" for a = 1, #paintEncoded[frame] do",
" local dot = paintEncoded[frame][a]",
" if dot.x-paint.scrollX > 0 and dot.x-paint.scrollX <= scr_x then",
" if dot.y-paint.scrollY > 0 and dot.y-paint.scrollY <= scr_y then",
" deredots[#deredots+1] = {dot.x-paint.scrollX, dot.y-paint.scrollY}",
" end",
" end",
" end",
" for y = 1, scr_y do",
" for x = 1, scr_x do",
" local good = true",
" for a = 1, #deredots do",
" if (deredots[a][1] == x) and (deredots[a][2] == y) then",
" good = bad",
" break",
" end",
" end",
" if good then",
" putDotDown({x=x, y=y})",
" end",
" end",
" end",
" saveToUndoBuffer()",
" doRender = true",
" end",
" if key == keys.g then",
" paint.doGray = not paint.doGray",
" changedImage = true",
" saveToUndoBuffer()",
" doRender = true",
" end",
" if key == keys.a then",
" paint.scrollX = 0",
" paint.scrollY = 0",
" doRender = true",
" end",
" if key == keys.n then",
" if keysDown[keys.leftShift] then",
" paint.c = specialCharSelector()",
" else",
" paint.c = boxCharSelector()",
" end",
" resetInputState()",
" doRender = true",
" end",
" if key == keys.f1 then",
" guiHelp()",
" resetInputState()",
" isDragging = false",
" end",
" if key == keys.f3 then",
" listAllMonitors()",
" resetInputState()",
" isDragging = false",
" end",
" if key == keys.leftBracket then",
" os.queueEvent(\"mouse_scroll\",2,1,1)",
" elseif key == keys.rightBracket then",
" os.queueEvent(\"mouse_scroll\",1,1,1)",
" end",
" if key == keys.z then",
" if keysDown[keys.leftAlt] and undoPos < #undoBuffer then",
" doRedo()",
" barmsg = \"Redood.\"",
" doRender = true",
" elseif undoPos > 1 then",
" doUndo()",
" barmsg = \"Undood.\"",
" doRender = true",
" end",
" end",
" elseif evt[1] == \"key_up\" then",
" local key = evt[2]",
" keysDown[key] = false",
" end",
" if (oldx~=paint.scrollX) or (oldy~=paint.scrollY) then",
" doRender = true",
" end",
" if doRender then",
" renderAllPAIN()",
" doRender = false",
" end",
" end",
"end",
"",
"runPainEditor = function(...) --needs to be cleaned up",
" local tArg = table.pack(...)",
" if not (tArg[1] == \"-n\" or (not tArg[1])) then",
" fileName = shell.resolve(tostring(tArg[1]))",
" end",
"",
" if not fileName then",
" paintEncoded = {{}}",
" elseif not fs.exists(fileName) then",
" local ex = fileName:sub(-4):lower()",
" if ex == \".nfp\" then",
" defaultSaveFormat = 1",
" elseif ex == \".nft\" then",
" defaultSaveFormat = 2",
" elseif ex == \".blt\" then",
" defaultSaveFormat = 3",
" elseif ex == \".gif\" then",
" defaultSaveFormat = 5",
" elseif ex == \".ucg\" then",
" defaultSaveFormat = 6",
" else",
" defaultSaveFormat = 4",
" end",
" paintEncoded = {{}}",
" elseif fs.isDir(fileName) then",
" if math.random(1,32) == 1 then",
" write(\"Oh\") sleep(0.2)",
" write(\" My\") sleep(0.2)",
" print(\" God\") sleep(0.3)",
" write(\"That is a\") sleep(0.1) term.setTextColor(colors.red)",
" write(\" FLIPPING\") sleep(0.4)",
" print(\" FOLDER.\") sleep(0.2) term.setTextColor(colors.white)",
" print(\"You crazy person.\") sleep(0.2)",
" else",
" print(\"That's a folder.\")",
" end",
" return",
" else",
" paintEncoded, defaultSaveFormat = openNewFile(fileName, readNonImageAsNFP)",
" if not paintEncoded then",
" return print(defaultSaveFormat)",
" end",
" end",
"",
" local asyncFillTool = function()",
" local event, frameNo, x, y, dot",
" isCurrentlyFilling = false",
" while true do",
" event, frameNo, x, y, dot, isDeleting = os.pullEvent(\"filltool_async\")",
" isCurrentlyFilling = true",
" renderBottomBar(\"Filling area...\")",
" fillTool(frameNo, x, y, dot, isDeleting)",
" saveToUndoBuffer()",
" isCurrentlyFilling = false",
" reRenderPAIN(doRenderBar == 0)",
" end",
" end",
"",
" if not paintEncoded[frame] then paintEncoded = {paintEncoded} end",
" if pMode == 1 then",
" doRenderBar = 0",
" renderPAIN(paintEncoded[tonumber(tArg[5]) or 1],-(tonumber(tArg[3]) or 0),-(tonumber(tArg[4]) or 0)) -- 'pain filename view X Y frame'",
" sleep(0)",
" return",
" else",
" renderPAIN(paintEncoded[frame],paint.scrollX,paint.scrollY,true)",
" end",
" lastPaintEncoded = deepCopy(paintEncoded)",
" undoBuffer = {deepCopy(paintEncoded)}",
" parallel.waitForAny(getInput, doNonEventDrivenMovement, asyncFillTool)",
"",
" term.setCursorPos(1,scr_y)",
" term.setBackgroundColor(colors.black)",
" term.clearLine()",
"end",
"",
"if not shell then error(\"shell API is required, sorry\") end",
"",
"runPainEditor(...)",
},
[ "/game/data/sprites/megaman/climb1.nft" ] = {
"  bffb",
"  bfŸ3‡‹fb›bf‚",
"  bf—b€3•b3•b€f”",
"bfƒf3Šbb€3‚fbŸ3š",
"3b‡3€f‰bŒŒf3ž",
"33fžb3‡3f’‹",
"f€3•bfbf†3ƒƒ",
"f€b3‚  fb‹b€",
"f€bb€€",
"f€b",
},
[ "/game/dodge.lua" ] = {
"--[[",
" Wall Dodge! What a riveting game!",
" Dodge the walls before they kill you.",
" ",
" Download with:",
" pastebin get fDTts7wz dodge",
" std PB fDTts7wz dodge",
" std ld dodge dodge",
"--]]",
"",
"local scr_x, scr_y = term.getSize()",
"local keysDown = {} --holds all pressed keys. It's way better than using \"key\" event for movement",
"local walls = {} --holds all screen data for walls. I could do slants if I wanted, not just walls",
"local frame = 0 --for every screen update-oh, you know what a frame is",
"local maxFrame = 26 --max frames until new wall",
"local fframe = 0 --not a typo. is the buffer of spaces until the spaces between walls shrinks",
"local maxFFrame = 6 --max fframes until the space between walls gets slightly tighter (down to 5, good luck m8)",
"local pause = false --pausing is a nice thing",
"local tsv = term.current().setVisible --it is my belief that monitors and normal computers do not have the setVisible method for term.current()",
"for a = 1, scr_x do",
" table.insert(walls,{top=1,bottom=scr_y,color=colors.black})",
"end",
"",
"local score = 0 --increases for every wall.",
"local time = 0 --in seconds, increases in increments of 0.1",
"",
"local addNewWall = function(top,bottom,color)",
" table.remove(walls,1)",
" table.insert(walls,{top=top,bottom=bottom,color=color})",
"end",
"",
"local guyX = 2",
"local guyY = math.floor(scr_y/2)",
"",
"local maxY = scr_y-1",
"local minY = 2",
"",
"local clearLines = function(y1,y2)",
" local _x,_y = term.getCursorPos()",
" for a = y1, y2 or y1 do",
" term.setCursorPos(1,a)",
" term.clearLine()",
" end",
" term.setCursorPos(_x,_y)",
"end",
"",
"local renderTEXT = function(_txt)",
" local txt = _txt or \"YOU ARE DEAD\"",
" local midY = math.floor(scr_y/2)",
" for a = 0, 2 do",
" term.setBackgroundColor(colors.gray)",
" clearLines(midY-a,midY+a)",
" sleep(0.1)",
" end",
" term.setCursorPos(4,midY)",
" term.write(txt)",
"end",
"",
"local trymove = function(dir)",
" if (guyY+dir)>=minY and (guyY+dir)<=maxY then",
" guyY = guyY + dir",
" return true",
" end",
" return false",
"end",
"",
"local render = function()",
" if tsv then tsv(false) end",
" term.setBackgroundColor(colors.white)",
" term.setTextColor(colors.white)",
" term.clear()",
" term.setCursorPos(guyX,guyY)",
" term.setBackgroundColor(colors.black)",
" term.write(\" \")",
" term.setCursorPos(1,1)",
" term.clearLine()",
" term.setCursorPos(1,scr_y)",
" term.clearLine()",
" for x = 1, #walls do",
" term.setBackgroundColor(walls[x].color)",
" for y = 1, walls[x].top do",
" term.setCursorPos(x,y)",
" term.write(\" \")",
" end",
" for y = walls[x].bottom, scr_y do",
" term.setCursorPos(x,y)",
" term.write(\" \")",
" end",
" end",
" term.setCursorPos(2,1)",
" term.setBackgroundColor(colors.black)",
" term.write(\"SCORE: \"..score..\" | TIME: \"..time)",
" if tsv then tsv(true) end",
"end",
"",
"local keepTime = function()",
" time = 0",
" while true do",
" sleep(0.1)",
" if not pause then",
" time = time + 0.1",
" end",
" end",
"end",
"",
"local doGame = function()",
" local wf = 0",
" local gap = 2",
" local ypos, randomcol",
" while true do",
" if not pause then",
" if frame >= maxFrame or wf > 0 then",
" if frame >= maxFrame then",
" frame = 0",
" fframe = fframe + 1",
" ypos = math.random(4,scr_y-3)",
" wf = 3",
" randomcol = 2^math.random(1,14)",
" end",
" if wf > 0 then",
" wf = wf - 1",
" end",
" if not term.isColor() then",
" randomcol = colors.black --Shame.",
" end",
" addNewWall(ypos-gap,ypos+gap,randomcol)",
" else",
" frame = frame + 1",
" addNewWall(1,scr_y,colors.black)",
" end",
" if fframe >= maxFFrame then",
" fframe = 0",
" if maxFrame > 7 then",
" maxFrame = maxFrame - 1",
" end",
" end",
" if keysDown[keys.up] then",
" trymove(-1)",
" end",
" if keysDown[keys.down] then",
" trymove(1)",
" end",
" if walls[guyX-1].top > 1 or walls[guyX-1].bottom < scr_y then",
" if walls[guyX].top < walls[guyX-1].top or walls[guyX].bottom > walls[guyX-1].bottom then",
" score = score + 1",
" end",
" end",
" render()",
" end",
" sleep(0)",
" if guyY<=walls[guyX].top or guyY>=walls[guyX].bottom then",
" return \"dead\"",
" end",
" end",
"end",
"",
"local getInput = function()",
" while true do",
" local evt = {os.pullEvent()}",
" if evt[1] == \"key\" then",
" if evt[2] == keys.q then",
" return \"quit\"",
" end",
" if evt[2] == keys.p then",
" pause = not pause",
" if pause then",
" local pauseMSGs = {",
" \"PAUSED\",",
" \"Paused. Press 'P' to resume\",",
" \"The game is paused\",",
" \"GAME PAUSE !\",",
" \"What, gotta catch your breath??\",",
" \"Paused, the game is, hmmm?\",",
" \"PAUSED GAME\",",
" \"GAME PAUSED\",",
" \"THE GAME IS PAUSED\",",
" \"THE PAUSED IS GAME\",",
" \"Buh-buh-buh-BEEP\",",
" \"UNPAUSE WITH 'P'\",",
" \"Tip: press UP to go up\",",
" \"Tip: press DOWN to go down\",",
" \"Tip: read Narbonic comic, you tool\",",
" \"Tip: read Skin Horse comic, you twat\",",
" \"YOU HAVE NO CHANCE TO SURVIVE MAKE YOUR TIME\",",
" \"-PAUSED-\",",
" \"=PAUSED=\",",
" \"PAISED\",",
" \"THOUST GAME BE PAUSETH\",",
" \"Yon game is paused. Obvious exits are 'Q', 'CTRL+T'\",",
" \"Tip: don't hit the walls\",",
" \"Tip: press 'P' to pause the game\",",
" }",
" renderTEXT(pauseMSGs[math.random(1,#pauseMSGs)])",
" keysDown[keys.up] = false",
" keysDown[keys.down] = false",
" end",
" end",
" keysDown[evt[2]] = true",
" end",
" if evt[1] == \"key_up\" then",
" keysDown[evt[2]] = false",
" end",
" end",
"end",
"",
"local uut = parallel.waitForAny(getInput,doGame,keepTime)",
"if uut == 2 then",
" renderTEXT()",
"end",
"sleep(0.05)",
"term.setCursorPos(1,scr_y)",
"term.setBackgroundColor(colors.black)",
"term.clearLine()",
},
[ "/game/data/sprites/megaman/shoot.nft" ] = {
"  bfŸƒ‰f3",
"  b3”0bŸ3f‰bž",
"  3f‡‚b”00€fŠ……  bffb",
"  bffb—bf‰3’fb‘0ŒŒ3f†f3•b‚ƒfŠ",
"  fb‹bf˜33€€f‡",
"  3fŸb‹b€€3‡f3",
"  bfŸ‡3‚f‚bƒfbŸ",
"b‚ƒƒƒ  fb‚ƒƒƒ",
},
[ "/util/sinelock.lua" ] = {
"--[[",
" Sinelock v1.3",
" The *COOLEST* computer/door lock ever!",
" Now with slightly less seizure!",
"",
" pastebin get XDgeSDTq sinelock",
" std pb XDgeSDTq sinelock",
" std ld sinelock sinelock",
"",
" Now with salting!",
"--]]",
"local scr_x, scr_y = term.getSize() --Gets screen size. Don't modify this",
"",
"--Config variables start!",
"local terminateMode = 2 --0 enables termination, 1 blocks it, 2 provides a taunting screen.",
"local passFile = \".sl_password\" --The ABSOLUTE path of the password file.",
"local saltFile = \".sl_salt\" --The ABSOLUTE path of the salt file.",
"local characterLimit = 1024 --The cap of characters at the read() prompt. Set this to prevent crashes.",
"local runProgram = \"\" --Set to something to run it when correct, and not using doors.",
"local dahChar = \"*\" --The character used to hide characters when typed.",
"local doKeyCards = true --Whether or not the lock also accepts keycards (floppy disks) as well as passwords.",
"local doEjectDisk = false --Whether or not to eject a keycard after it's accepted, just to speed things up a bit.",
"local doorSides = {} --If it has anything, the lock will open the doors instead of unlocking the PC.",
"local doInvertSignal = false --If true, it will invert the redstone signal of the door, in case you need to.",
"local doShowDoorSides = true --If true, will show the door sides being opened. Set to false if you are paranoid.",
"local beWavey = true --Whether or not to animate the sine wave.",
"local readYpos = scr_y-2 --The Y position of the read() prompt",
"local requireAllPasswords = false --Whether or not the lock asks for ONE of the multiple passwords, or ALL of them in order.",
"local badlength = 4 --The length in seconds that you have to wait to try again.",
"local goodlength = 6 --The length in seconds that doors will stay open.",
"local sineFrameDelay = 0.15 --The amount of time between sine animation frames. Tradeoff of purty vs performance.",
"local palate = {",
" frontsine = colors.lightGray,",
" backsine = colors.gray,",
" background = colors.black,",
" rainColor = colors.gray,",
" rainChar = \"|\",",
" promptBG = colors.gray,",
" promptTXT = colors.white,",
" wrongBG = colors.black,",
" wrongTXT = colors.gray,",
"}",
"local language = \"english\"",
"local lang = {",
" english = {",
" wrong1 = \"YOU ARE WRONG.\",",
" wrong2 = \"YOU ARE WRONG. AS ALWAYS.\",",
" right1 = \"Correct!\",",
" right2 = \"Correct, finally!\",",
" },",
" spanish = {",
" wrong1 = \"ESTA USTED EQUIVOCADO.\",",
" wrong2 = \"ESTA USTED EQUIVOCADO. TODAVIA OTRA VEZ.\",",
" right1 = \"Correcto!\",",
" right2 = \"Asi es, por fin!\",",
" noTerminate = \"No termine!\",",
" },",
" german = {",
" wrong1 = \"SIE LIEGEN FALSCH.\",",
" wrong2 = \"SIE LIEGEN FALSCH. WIE IMMER.\",",
" right1 = \"Richtig!\",",
" right2 = \"Richtig, endlich!\",",
" noTerminate = \"Nicht zu beenden!\",",
" },",
" dutch = {",
" wrong1 = \"U BENT ONJUIST.\",",
" wrong2 = \"JE BENT ONJUIST, ALS ALTIJD.\",",
" right1 = \"Dat is juist!\",",
" right2 = \"Dat is juist, eindelijk!\",",
" noTerminate = \"Niet te beeindigen!\",",
" },",
" latin = { --As a joke",
" wrong1 = \"ERRAS\",",
" wrong2 = \"TU DEFICIENTES!\",",
" right1 = \"Quod suus 'verum!\",",
" right2 = \"Quod suus 'verum, demum!\",",
" noTerminate = \"Vade futuo te ipsum!\",",
" },",
" italian = {",
" wrong1 = \"HAI SBAGLIATO.\",",
" wrong2 = \"HAI SBAGLIATO, COME SEMPRE D'ALTRONDE.\",",
" right1 = \"CORRETTO!\",",
" right2 = \"CORRETTO, FINALMENTE!\",",
" noTerminate = \"Non cercare di terminarmi\",",
" },",
"}",
"",
"-- Config variables end. Don't touch anything else, m'kay?",
"if not _VERSION then",
" return printError(\"Sorry, only CC 1.7 and later supported.\")",
"end",
"local csv, salt, doSine",
"local floor, ceil, random, abs = math.floor, math.ceil, math.random, math.abs",
"local sin, cos = math.sin, math.cos",
"local rhite = term.write",
"local setTextColor, setBackgroundColor, getTextColor, getBackgroundColor = term.setTextColor, term.setBackgroundColor, term.getTextColor, term.getBackgroundColor",
"local setCursorPos, setCursorBlink, getCursorPos, getSize = term.setCursorPos, term.setCursorBlink, term.getCursorPos, term.getSize",
"local sineLevel = 1",
"local isTerminable = false",
"local kaykaycoolcool = true",
"if term.current().setVisible then",
" csv = true",
"else",
" csv = false",
"end",
"",
"local writeError = function(...)",
" local tx,bg = getTextColor(),getBackgroundColor()",
" if term.isColor() then",
" setTextColor(colors.red)",
" else",
" setTextColor(colors.white)",
" end",
" rhite(table.concat(arg,\" \"))",
" setTextColor(tx)",
" setBackgroundColor(bg)",
"end",
"",
"local goodPullEvent",
"if terminateMode == 1 then",
" if os.pullEvent ~= os.pullEventRaw then",
" goodPullEvent = os.pullEvent",
" end",
" os.pullEvent = os.pullEventRaw",
"end",
"",
"local keepLooping = true",
"",
"---- SHA256 START ----",
"--SHA256 implementation done by GravityScore.",
"",
"local MOD = 2^32",
"local MODM = MOD-1",
"",
"local function memoize(f)",
" local mt = {}",
" local t = setmetatable({}, mt)",
" function mt:__index(k)",
" local v = f(k)",
" t[k] = v",
" return v",
" end",
" return t",
"end",
"",
"local function make_bitop_uncached(t, m)",
" local function bitop(a, b)",
" local res,p = 0,1",
" while a ~= 0 and b ~= 0 do",
" local am, bm = a % m, b % m",
" res = res + t[am][bm] * p",
" a = (a - am) / m",
" b = (b - bm) / m",
" p = p*m",
" end",
" res = res + (a + b) * p",
" return res",
" end",
" return bitop",
"end",
"",
"local function make_bitop(t)",
" local op1 = make_bitop_uncached(t,2^1)",
" local op2 = memoize(function(a) return memoize(function(b) return op1(a, b) end) end)",
" return make_bitop_uncached(op2, 2 ^ (t.n or 1))",
"end",
"",
"local bxor1 = make_bitop({[0] = {[0] = 0,[1] = 1}, [1] = {[0] = 1, [1] = 0}, n = 4})",
"",
"local function bxor(a, b, c, ...)",
" local z = nil",
" if b then",
" a = a % MOD",
" b = b % MOD",
" z = bxor1(a, b)",
" if c then z = bxor(z, c, ...) end",
" return z",
" elseif a then return a % MOD",
" else return 0 end",
"end",
"",
"local function band(a, b, c, ...)",
" local z",
" if b then",
" a = a % MOD",
" b = b % MOD",
" z = ((a + b) - bxor1(a,b)) / 2",
" if c then z = bit32_band(z, c, ...) end",
" return z",
" elseif a then return a % MOD",
" else return MODM end",
"end",
"",
"local function bnot(x) return (-1 - x) % MOD end",
"",
"local function rshift1(a, disp)",
" if disp < 0 then return lshift(a,-disp) end",
" return floor(a % 2 ^ 32 / 2 ^ disp)",
"end",
"",
"local function rshift(x, disp)",
" if disp > 31 or disp < -31 then return 0 end",
" return rshift1(x % MOD, disp)",
"end",
"",
"local function lshift(a, disp)",
" if disp < 0 then return rshift(a,-disp) end ",
" return (a * 2 ^ disp) % 2 ^ 32",
"end",
"",
"local function rrotate(x, disp)",
" x = x % MOD",
" disp = disp % 32",
" local low = band(x, 2 ^ disp - 1)",
" return rshift(x, disp) + lshift(low, 32 - disp)",
"end",
"",
"local k = {",
" 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5,",
" 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,",
" 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3,",
" 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,",
" 0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc,",
" 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,",
" 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7,",
" 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967,",
" 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13,",
" 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,",
" 0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3,",
" 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,",
" 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5,",
" 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,",
" 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208,",
" 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2,",
"}",
"",
"local function str2hexa(s)",
" return (string.gsub(s, \".\", function(c) return string.format(\"%02x\", string.byte(c)) end))",
"end",
"",
"local function num2s(l, n)",
" local s = \"\"",
" for i = 1, n do",
" local rem = l % 256",
" s = string.char(rem) .. s",
" l = (l - rem) / 256",
" end",
" return s",
"end",
"",
"local function s232num(s, i)",
" local n = 0",
" for i = i, i + 3 do n = n*256 + string.byte(s, i) end",
" return n",
"end",
"",
"local function preproc(msg, len)",
" local extra = 64 - ((len + 9) % 64)",
" len = num2s(8 * len, 8)",
" msg = msg .. \"€\" .. string.rep(\"\\0\", extra) .. len",
" assert(#msg % 64 == 0)",
" return msg",
"end",
"",
"local function initH256(H)",
" H[1] = 0x6a09e667",
" H[2] = 0xbb67ae85",
" H[3] = 0x3c6ef372",
" H[4] = 0xa54ff53a",
" H[5] = 0x510e527f",
" H[6] = 0x9b05688c",
" H[7] = 0x1f83d9ab",
" H[8] = 0x5be0cd19",
" return H",
"end",
"",
"local function digestblock(msg, i, H)",
" local w = {}",
" for j = 1, 16 do w[j] = s232num(msg, i + (j - 1)*4) end",
" for j = 17, 64 do",
" local v = w[j - 15]",
" local s0 = bxor(rrotate(v, 7), rrotate(v, 18), rshift(v, 3))",
" v = w[j - 2]",
" w[j] = w[j - 16] + s0 + w[j - 7] + bxor(rrotate(v, 17), rrotate(v, 19), rshift(v, 10))",
" end",
"",
" local a, b, c, d, e, f, g, h = H[1], H[2], H[3], H[4], H[5], H[6], H[7], H[8]",
" for i = 1, 64 do",
" local s0 = bxor(rrotate(a, 2), rrotate(a, 13), rrotate(a, 22))",
" local maj = bxor(band(a, b), band(a, c), band(b, c))",
" local t2 = s0 + maj",
" local s1 = bxor(rrotate(e, 6), rrotate(e, 11), rrotate(e, 25))",
" local ch = bxor (band(e, f), band(bnot(e), g))",
" local t1 = h + s1 + ch + k[i] + w[i]",
" h, g, f, e, d, c, b, a = g, f, e, d + t1, c, b, a, t1 + t2",
" end",
"",
" H[1] = band(H[1] + a)",
" H[2] = band(H[2] + b)",
" H[3] = band(H[3] + c)",
" H[4] = band(H[4] + d)",
" H[5] = band(H[5] + e)",
" H[6] = band(H[6] + f)",
" H[7] = band(H[7] + g)",
" H[8] = band(H[8] + h)",
"end",
"",
"local function sha256(...)",
" local msg = table.concat(arg,\",\")",
" msg = preproc(msg, #msg)",
" local H = initH256({})",
" for i = 1, #msg, 64 do digestblock(msg, i, H) end",
" return str2hexa(num2s(H[1], 4) .. num2s(H[2], 4) .. num2s(H[3], 4) .. num2s(H[4], 4) ..",
" num2s(H[5], 4) .. num2s(H[6], 4) .. num2s(H[7], 4) .. num2s(H[8], 4))",
"end",
"",
"---- SHA256 END ----",
"",
"local terminates = 0",
"local sillyTerminate = function()",
" local goodpull = _G.os.pullEvent",
" os.pullEvent = os.pullEventRaw",
" terminates = terminates + 1",
" local script = {",
" \"You shall not pass!\",",
" \"THOU shalt not pass!\",",
" \"Stop trying to pass!\",",
" \"...maybe I'm not clear.\",",
" \"YOU. SHALL NOT. PASS!!\",",
" \"Pass thou shalt not!\",",
" \"Hey, piss off, will ya?\",",
" \"I haven't got all day.\",",
" \"...no, shut up. I don't.\",",
" \"I won't tell you it!\",",
" \"No password for you.\",",
" \"It's been hashed!\",",
" \"Hashed...with a salt!\",",
" \"I'll never tell you the salt.\",",
" \"You know why?\",",
" \"Because that requires passing!\",",
" \"WHICH THOU SHALT NOT DO!\",",
" \"(oh btw don't pass k?)\",",
" \"You! Don't pass!\",",
" \"That means YOU!\",",
" \"Cut it out!\",",
" \"Re: Cut it out!\",",
" \"Perhaps if you keep it up...\",",
" \"..hmm...\",",
" \"..oh I give up.\",",
" \"<bullshitterm>\",",
" \"What? Is this what you wanted?\",",
" \"Huh? No? I-it's not?\",",
" \"Well then...!\",",
" \"<toobad>\",",
" \"YEAH I SAID IT\",",
" \"You think you're a terminating machine!\",",
" \"You think you're above consequence!\",",
" \"...w-...\",",
" \"eat my shorts\",",
" \"Your attempts are futile anyhow.\",",
" \"Here I am getting drunk off your sweat,\",",
" \"...while you push CTRL and T.\",",
" \"Or maybe you're pressing that [T] button.\",",
" \"Like, um, in CCEmuRedux.\",",
" \"But it matters not!\",",
" \"For you see, my defences are great!\",",
" \"Nothing can bust my rock-hard abs!\",",
" \"<fuckinghell>\",",
" \"Oh bualls.\",",
" \"That was embarrasing.\",",
" \"...?\",",
" \"What're YOU lookin' at??\",",
" \"You callin' me UNSTABLE!?\",",
" \"HUH!??\",",
" \"...\",",
" \"...w-well at least I admit it\",",
" \"...b-bakka\",",
" \".......\",",
" \"Hey, have you ever played EarthBound?\",",
" \"(Yes. I'm gonna rant.)\",",
" \"It's an RPG on the Super Nintendo.\",",
" \"Like, instead of fighting fantasy demons,\",",
" \"you fight stop signs and cars and shit\",",
" \"And, like, you hit rabid dogs with a bat\",",
" \"And you have magical PSI spells\",",
" \"...speaking of PSI, I happen to use it a lot.\",",
" \"...er, *I* as in the coder of this lock...\",",
" \"And by PSI, I mean the mod.\",",
" \"You don't see too many psychic locks these days.\",",
" \"A shame, really.\",",
" \"I bet a PSI lock could act as a heater with PSI Fire.\",",
" \"Or maybe it can kill rats with PSI Ground or Thunder\",",
" \"Maybe, you can get a psychic KEY lock, so, like,\",",
" \"you could put it on that Psychonauts head door thing.\",",
" \"...WHAT!? just a suggestion.\",",
" \"Psychonauts is another game I reccommend.\",",
" \"It has some really clever dialogue.\",",
" \"I'm sure you'd like it quite a lot.\",",
" \"I know, because you've been here for ten fucking minutes.\",",
" \"And you're not ONE STEP closer to getting the password\",",
" \"Which I've been guarding very, very closely.\",",
" \"Yes. Extremely closely.\",",
" \"Excrutiatingly, some would say.\",",
" \"You know, I should probably get to shouting.\",",
" \"*ahem*\",",
" \"...\",",
" \"*aahhhechhemmemmhmm*\",",
" \"*aachkskacehchachkhackcoughfartfuckdammitaaucahkh*\",",
" \"...\",",
" \"STAHP IT\",",
" \"STAHP TEHRMINATIN\",",
" \"do it for the CHILDREN\",",
" \"okay fuck the children, who needs 'em\",",
" \"then\",",
" \"um\",",
" \"THINK OF THE...THE...\",",
" \"the babies...?\",",
" \"um\",",
" \"<abuseofcommunity>\",",
" \"That's a fucking horrible idea.\",",
" \"I'd rather eat my own brain then think about that.\",",
" \"I'd sooner kiss a pig!\",",
" \"I'd sooner swallow an avocado pit!\",",
" \"...\",",
" \"You know, you suck so much.\",",
" \"You suck so much, and I'm sick of writing this script\",",
" \"If my knuckles bleed, you're paying my insurance\",",
" \"In order to save time, money, and my joints,\",",
" \"I believe it would be in order to...\",",
" \"...to say,\",",
" \"NO TERMINATING.\",",
" }",
" setCursorBlink(false)",
" local mess",
" if terminates > #script then",
" mess = script[#script]",
" else",
" mess = script[terminates]",
" end",
" if mess == \"<bullshitterm>\" then",
" setBackgroundColor(colors.black)",
" if term.isColor() then",
" setTextColor(colors.yellow)",
" else",
" setTextColor(colors.white)",
" end",
" term.clear()",
" setCursorPos(1,1)",
" print(os.version())",
" write(\"> \")",
" setTextColor(colors.white)",
" read()",
" printError(\"shell:350: Unable to pass\")",
" sleep(2)",
" elseif mess == \"<toobad>\" then",
" setBackgroundColor(colors.black)",
" if term.isColor() then",
" setTextColor(colors.red)",
" else",
" setTextColor(colors.white)",
" end",
" term.clear()",
" setCursorPos(1,scr_y/2)",
" local toobad = \" T\"..(\"O\"):rep(scr_x-8)..\" BAD!\"",
" for a = 1, #toobad do",
" for y = 1, scr_y do",
" setCursorPos(a,y)",
" rhite(toobad:sub(a,a))",
" end",
" sleep(0)",
" end",
" sleep(1.5)",
" for a = 1, 16 do",
" if a%3 == 0 then",
" setBackgroundColor(colors.white)",
" elseif a%3 == 1 then",
" setBackgroundColor(colors.black)",
" else",
" if term.isColor() then",
" setBackgroundColor(colors.red)",
" else",
" setBackgroundColor(colors.gray)",
" end",
" end",
" term.clear()",
" sleep(0)",
" end",
" elseif mess == \"<fuckinghell>\" then",
" writeError(\"Terminated\")",
" setBackgroundColor(colors.black)",
" setTextColor(colors.white)",
" term.blit(\">\",\"4\",\"f\")",
" read()",
" sleep(0.75)",
" for a = 1, 2 do",
" sleep(0.05)",
" term.scroll(1)",
" end",
" for a = 1, scr_y do ",
" sleep(0.05)",
" term.scroll(-1)",
" end",
" sleep(0.25)",
" setBackgroundColor(colors.gray)",
" term.clear()",
" sleep(0.1)",
" setBackgroundColor(colors.lightGray)",
" term.clear()",
" sleep(0.1)",
" setBackgroundColor(colors.white)",
" term.clear()",
" sleep(0.25)",
" local msg = \"taht didn't happan\"",
" term.setCursorPos(scr_x-#msg,scr_y)",
" setTextColor(colors.black)",
" rhite(msg)",
" sleep(1)",
" elseif mess == \"<abuseofcommunity>\" then",
" setBackgroundColor(colors.white)",
" setTextColor(colors.black)",
" term.clear()",
" setCursorPos(2,3)",
" print(\"Since you're such a smart bastard, why don't you come up with something objectionable to think about?\\n\")",
" setBackgroundColor(colors.gray)",
" setTextColor(colors.white)",
" term.clearLine()",
" local yourFuckingShittyAssResponceThatSucksSoMuchBallsThatIWouldRatherListenToThatFuckingOwlFromOcarinaOfTimeBlatherAboutHisFuckingDayThanSitWithYouForAnotherGoddamnedSecondReeeeee = read()",
" setBackgroundColor(colors.white)",
" setTextColor(colors.black)",
" for a = 1, 5 do",
" sleep(0.6)",
" write(\".\")",
" end",
" sleep(1)",
" term.setTextColor(colors.red)",
" for a = 1, 20 do",
" sleep(0.05)",
" write(\".\")",
" end",
" sleep(0.5)",
" else",
" setBackgroundColor(colors.gray)",
" setTextColor(colors.white)",
" setCursorPos(math.max(1,(scr_x/2)-(#mess/2)),scr_y/2)",
" if language == \"english\" then",
" write(mess)",
" else",
" write(lang[language].noTerminate)",
" end",
" sleep(1.5)",
" end",
" os.pullEvent = goodpull",
" return terminates",
"end",
"",
"local shuffle = function(txt)",
" local output = \"\"",
" for a = 1, #txt do",
" if a % 2 == 0 then",
" output = output..txt:sub(a,a)",
" else",
" output = txt:sub(a,a)..output",
" end",
" end",
" return output",
"end",
"",
"local goodpass = function(pswd,count)",
" isTerminable = true",
" doSine = false",
" setCursorBlink(false)",
" local flashes = {",
" colors.white,",
" colors.lightGray,",
" colors.gray,",
" }",
" if type(pswd) == \"table\" then",
" pswd = pswd[1]",
" end",
" setTextColor(colors.black)",
" local correctmsg",
" if count < 10 then",
" correctmsg = lang[language].right1",
" else",
" correctmsg = lang[language].right2",
" end",
" for a = 1, #flashes do",
" setBackgroundColor(flashes[#flashes-(a-1)])",
" term.clear()",
" setCursorPos((scr_x/2)-(#correctmsg/2),scr_y/2)",
" rhite(correctmsg)",
" sleep(0)",
" end",
" if #doorSides == 0 then",
" sleep(0.4)",
" keepLooping = false",
" else",
" local doormsg",
" if doShowDoorSides then",
" doormsg = \"Applying RS to \"..table.concat(doorSides,\", \")..\".\"",
" else",
" doormsg = \"Applying redstone.\"",
" end",
" setCursorPos((scr_x/2)-(#doormsg/2),(scr_y/2)+2)",
" rhite(doormsg)",
" for a = 1, #doorSides do",
" redstone.setOutput(doorSides[a],not doInvertSignal)",
" end",
" if terminateMode == 1 then",
" os.pullEvent = goodPullEvent",
" end",
" sleep(goodlength)",
" if terminateMode == 1 then",
" os.pullEvent = os.pullEventRaw",
" end",
" for a = 1, #doorSides do",
" redstone.setOutput(doorSides[a],doInvertSignal)",
" end",
" end",
" for a = 1, #flashes do",
" setBackgroundColor(flashes[a])",
" term.clear()",
" setCursorPos((scr_x/2)-(#correctmsg/2),scr_y/2)",
" rhite(correctmsg)",
" sleep(0)",
" end",
" setBackgroundColor(colors.black)",
" term.clear()",
" setCursorPos(1,1)",
" if terminateMode == 1 and goodPullEvent and (#doorSides == 0) then",
" os.pullEvent = goodPullEvent",
" end",
" setCursorBlink(true)",
" isTerminable = false",
" return true",
"end",
"",
"local badpass = function(pswd,count)",
" doSine = false",
" local getevent = os.pullEvent",
" os.pullEvent = os.pullEventRaw",
" setCursorBlink(false)",
" setBackgroundColor(palate.wrongBG)",
" setTextColor(palate.wrongTXT)",
" term.clear()",
" if type(pswd) == \"table\" then",
" pswd = pswd[1]",
" end",
" local badmsg",
" if count < 10 then",
" if pswd == sha256(\"bepis\",salt) then",
" badmsg = \"Bepis.\"",
" else",
" badmsg = lang[language].wrong1",
" end",
" else",
" if pswd == sha256(\"bepis\",salt) then",
" badmsg = \"BEPIS!\"",
" else",
" badmsg = lang[language].wrong2",
" end",
" end",
" setCursorPos((scr_x/2)-(#badmsg/2),scr_y/2)",
" rhite(badmsg)",
" sleep(badlength)",
" doSine = true",
" setCursorBlink(true)",
" os.pullEvent = getevent",
" return \"man you suck\"",
"end",
" ",
"local readPassFile = function()",
" local _output, _salt",
" if fs.exists(passFile) then",
" local file = fs.open(passFile,\"r\")",
" _output = file.readLine()",
" file.close()",
" end",
" if fs.exists(saltFile) then",
" local file = fs.open(saltFile,\"r\")",
" _salt = file.readLine()",
" file.close()",
" end",
" return _output, _salt",
"end",
"",
"local addNewPassword = function(pword,_path)",
" local file = fs.open(_path or passFile,\"a\")",
" file.write( sha256(pword,salt) )",
" file.close()",
"end",
" ",
"local rendersine = function(move)",
" move = move or 0",
" local res1,res2,x,y",
" if csv then term.current().setVisible(false) end",
" setBackgroundColor(colors.black)",
" setCursorBlink(false)",
" for a = 1, scr_y do",
" if a ~= readYpos then",
" for b = 1, scr_x do",
" x = b+floor(scr_x/2)",
" y = a-floor(scr_y/2)",
" res1 = abs( floor(sin((x/(scr_x/7.3))+move)*scr_y/4) - y ) <= 2",
" setCursorPos(b,a)",
" if res1 then",
" setBackgroundColor(palate.backsine)",
" else",
" setBackgroundColor(palate.background)",
" end",
" rhite(\" \")",
" res2 = abs( floor(cos((x/(scr_x/12.75))+(move*4))*scr_y/7) - y+2 ) <= 1",
" setCursorPos(b,a)",
" if res2 then",
" setBackgroundColor(palate.frontsine)",
" rhite(\" \")",
" elseif not res1 then",
" setBackgroundColor(palate.background)",
" setTextColor(palate.rainColor)",
" if (x % 2 == 0) and ((y+floor(move*-10)+(x % 5)) % 5 <= 1) then",
" rhite(palate.rainChar)",
" else",
" rhite(\" \")",
" end",
" end",
" end",
" end",
" end",
" if csv then term.current().setVisible(true) end",
" setCursorBlink(true)",
"end",
"",
"local sine = function()",
" doSine = true",
" while true do",
" if sineLevel > 900 then",
" sineLevel = 1",
" end",
" if doSine then",
" local cX,cY = getCursorPos()",
" local bg,txt = getBackgroundColor(),getTextColor()",
" rendersine(sineLevel/10)",
" setCursorPos(cX,cY)",
" setBackgroundColor(bg)",
" setTextColor(txt)",
" end",
" sleep(sineFrameDelay)",
" if kaykaycoolcool then",
" sineLevel = sineLevel + 1",
" end",
" end",
"end",
"",
"local funcread = function(repchar,rHistory,doFunc,noNewLine,writeFunc,cursorAdjFunc,doFuncEvent,charLimit)",
" local scr_x,scr_y = term.getSize()",
" local sx,sy = term.getCursorPos()",
" local cursor = 1",
" local rCursor = #rHistory+1",
" local output = \"\"",
" term.setCursorBlink(true)",
" local rite = writeFunc or term.write",
" cursorAdjFunc = cursorAdjFunc or function() return 0 end",
" while true do",
" local evt,key = os.pullEvent()",
" if evt == doFuncEvent then",
" pleaseDoFunc = true",
" elseif evt == \"key\" then",
" if key == keys.enter then",
" if not noNewLine then",
" write(\"\\n\")",
" end",
" term.setCursorBlink(false)",
" return output",
" elseif key == keys.left then",
" if cursor-1 >= 1 then",
" cursor = cursor - 1",
" end",
" elseif key == keys.right then",
" if cursor <= #output then",
" cursor = cursor + 1",
" end",
" elseif key == keys.up then",
" if rCursor > 1 then",
" rCursor = rCursor - 1",
" term.setCursorPos(sx,sy)",
" rite((\" \"):rep(#output))",
" output = (rHistory[rCursor] or \"\"):sub(1,charLimit or -1)",
" cursor = #output+1",
" pleaseDoFunc = true",
" end",
" elseif key == keys.down then",
" term.setCursorPos(sx,sy)",
" rite((\" \"):rep(#output))",
" if rCursor < #rHistory then",
" rCursor = rCursor + 1",
" output = (rHistory[rCursor] or \"\"):sub(1,charLimit or -1)",
" cursor = #output+1",
" pleaseDoFunc = true",
" else",
" rCursor = #rHistory+1",
" output = \"\"",
" cursor = 1",
" end",
" elseif key == keys.backspace then",
" if cursor > 1 and #output > 0 then",
" output = (output:sub(1,cursor-2)..output:sub(cursor)):sub(1,charLimit or -1)",
" cursor = cursor - 1",
" pleaseDoFunc = true",
" end",
" elseif key == keys.delete then",
" if #output:sub(cursor,cursor) == 1 then",
" output = (output:sub(1,cursor-1)..output:sub(cursor+1)):sub(1,charLimit or -1)",
" pleaseDoFunc = true",
" end",
" end",
" elseif evt == \"char\" or evt == \"paste\" then",
" output = (output:sub(1,cursor-1)..key..output:sub(cursor+(#key-1))):sub(1,charLimit or -1)",
" cursor = math.min(#output+1,cursor+#key)",
" pleaseDoFunc = true",
" end",
" local pOut = (output or \"\"):sub(math.max( 1,(#output+sx)-scr_x) )",
" if pleaseDoFunc then",
" pleaseDoFunc = false",
" if type(doFunc) == \"function\" then",
" doFunc(output:sub(1,charLimit or -1))",
" end",
" term.setCursorPos(sx,sy)",
" if repchar then",
" rite(repchar:sub(1,1):rep(#pOut))",
" else",
" rite(pOut)",
" end",
" term.write(\" \")",
" end",
" term.setCursorPos(sx+cursorAdjFunc(pOut)+cursor-math.max( 1,(#output+sx)-scr_x),sy)",
" end",
"end",
"",
"local arse, arseSHA, passes",
"",
"local awaitKeyCard = function()",
" local bwop,_,side",
" repeat",
" _,side = os.pullEvent(\"disk\")",
" if side then",
" bwop = fs.combine(disk.getMountPath(side),\".sinepw\") --bwop!",
" else",
" bwop = \"\"",
" end",
" until fs.exists(bwop) and not fs.isDir(bwop)",
" local file = fs.open(bwop,\"r\")",
" local output = file.readLine()",
" file.close()",
" arseSHA = output",
" if doEjectDisk then disk.eject(side) end",
"end",
"",
"local passwordPrompt = function()",
" if requireAllPasswords then",
" arse = {}",
" arseSHA = \"\"",
" for a = 1, ceil(#passes/64) do",
" setCursorPos(1,readYpos)",
" setBackgroundColor(palate.promptBG)",
" term.clearLine()",
" setTextColor(palate.promptTXT)",
" write(\"P\"..a..\">\")",
" arse[#arse+1] = read(dahChar)",
" arseSHA = arseSHA..sha256(arse[#arse],salt)",
" end",
" else",
" setCursorPos(1,readYpos)",
" setBackgroundColor(palate.promptBG)",
" term.clearLine()",
" setTextColor(palate.promptTXT)",
" write(\">\")",
" arse = funcread(dahChar,{},nil,true,nil,nil,nil,characterLimit)",
" arseSHA = sha256(arse,salt)",
" end",
"end",
"",
"local count = 0",
"",
"local lock = function()",
" if #doorSides > 0 then",
" for a = 1, #doorSides do",
" redstone.setOutput(doorSides[a],doInvertSignal)",
" end",
" end",
" while true do",
" passes, salt = readPassFile()",
" count = count + 1",
" if doKeyCards then",
" parallel.waitForAny(passwordPrompt,awaitKeyCard)",
" else",
" passwordPrompt()",
" end",
" local good",
" if requireAllPasswords then",
" if passes == arseSHA then",
" good = true",
" else",
" good = false",
" end",
" else",
" if string.find(passes,arseSHA) then",
" good = true",
" else",
" good = false",
" end",
" end",
" if good then",
" goodpass(arseSHA,count)",
" if #doorSides == 0 then",
" return true",
" else",
" doSine = true",
" end",
" else",
" badpass(arseSHA,count)",
" end",
" end",
"end",
"",
"local choice = function(input)",
" repeat",
" event, key = os.pullEvent(\"key\")",
" if type(key) == \"number\" then key = keys.getName(key) end",
" if key == nil then key = \" \" end",
" until string.find(input, key)",
" return key",
"end",
"",
"if not fs.exists(saltFile) then",
" local file = fs.open(saltFile,\"w\")",
" for a = 1, 128 do",
" local c = string.char(random(1,255))",
" file.write(c)",
" end",
" file.close()",
" local f = fs.open(saltFile,\"r\")",
" salt = f.readLine()",
" f.close()",
"end",
"",
"passes, salt = readPassFile()",
"",
"local tArg = {...}",
"if tArg[1] == \"addpass\" then",
" if tArg[2] then",
" print(\"Really add password? [Y,N]\")",
" local answer = choice(\"yn\")",
" if answer == \"n\" then",
" sleep(0)",
" return print(\"Oh, okay.\")",
" else",
" table.remove(tArg,1)",
" addNewPassword(table.concat(tArg,\" \"))",
" sleep(0)",
" return print(\"Added password.\")",
" end",
" else",
" sleep(0)",
" return print(\"Expected a new password...\")",
" end",
"elseif tArg[1] == \"keymake\" then",
" if tArg[2] then",
" print(\"Really add to disk?\")",
" print(\"Keep in mind the password has to be manually added for the keycard to work.\\n[Y,N]\")",
" local answer = choice(\"yn\")",
" if answer == \"n\" then",
" sleep(0)",
" return print(\"Oh, okay.\")",
" else",
" print(\"Please insert a disk or pocket computer.\")",
" local _,side = os.pullEvent(\"disk\")",
" local diskPassPath = fs.combine(disk.getMountPath(side),\".sinepw\")",
" table.remove(tArg,1)",
" addNewPassword(table.concat(tArg,\" \"),diskPassPath)",
" if not disk.getLabel(side) then",
" disk.setLabel(side,\"slkey-\"..random(1,1000))",
" end",
" sleep(0)",
" print(\"Added password.\")",
" if not doKeyCards then",
" print(\"Key cards aren't enabled, though.\")",
" end",
" return",
" end",
" else",
" sleep(0)",
" return print(\"Expected a password...\")",
" end",
"end",
"",
"if not fs.exists(passFile) then",
" local progname = fs.getName(shell.getRunningProgram())",
" return print(\"No password file found.\\nRun '\"..progname..\" addpass <password>' to add a password.\")",
"end",
"",
"setBackgroundColor(colors.black)",
"term.clear()",
"",
"local parafunky = { --it looks kinda funky, but it tastes funKAY!",
" sine,",
" lock,",
"}",
"",
"if not beWavey then table.remove(parafunky,1) end --not funky, man",
"local staytis, errawr",
"while keepLooping do",
" kaykaycoolcool = true",
" staytis, errawr = pcall(parallel.waitForAny,unpack(parafunky))",
" if keepLooping == false then break else",
" if terminateMode == 2 then",
" kaykaycoolcool = false",
" if not isTerminable then",
" sillyTerminate()",
" else",
" keepLooping = false",
" setBackgroundColor(colors.black)",
" term.clear()",
" setTextColor(colors.white)",
" setCursorPos(1,1)",
" break",
" end",
" else",
" keepLooping = false",
" setBackgroundColor(colors.black)",
" term.clear()",
" setTextColor(colors.white)",
" setCursorPos(1,1)",
" if not staytis then",
" printError(errawr)",
" end",
" break",
" end",
" end",
"end",
"if runProgram and (runProgram ~= \"\") then",
" shell.run(runProgram)",
"end",
},
[ "/game/connect4.lua" ] = {
"local scr_x, scr_y = term.getSize()",
"local midX, midY = .5 * scr_x, .5 * scr_y",
"local origTX, origBG = term.getTextColor(), term.getBackgroundColor()",
"",
"local winLength = 4",
"local sleepDelay = 0.05",
"local moveCount = 0",
"",
"local board = {} -- connect 4 board; formatted like board[y][x]",
"local block = {} -- bottom blockage; formatted like block[x]",
"",
"local waiting = false",
"",
"local boardX, boardY = 7, 6 -- size of board",
"",
"local palette = {",
" bg = colors.black, -- color of backdrop",
" board = colors.white, -- color of board",
" txt = colors.white -- color of text",
"}",
"",
"local tiles = {",
" [\"bl\"] = palette.bg, -- blank space",
" [\"P1\"] = colors.red, -- player 1",
" [\"P2\"] = colors.blue -- player 2",
"}",
"",
"local you = \"P1\"",
"local nou = \"P2\"",
"",
"local cwrite = function(text, y, doClear)",
" local cx, cy = term.getCursorPos()",
" term.setCursorPos(midX - math.floor(#text / 2), y or cy)",
" if doClear then term.clearLine() end",
" term.write(text)",
"end",
"",
"local cblit = function(char, text, back, y, doClear)",
" local cx, cy = term.getCursorPos()",
" term.setCursorPos(midX - math.floor(#text / 2), y or cy)",
" if doClear then term.clearLine() end",
" term.blit(char, text, back)",
"end",
"",
"local resetBoard = function()",
" board = {}",
" for y = 1, boardY do",
" board[y] = {}",
" for x = 1, boardX do",
" board[y][x] = {\"bl\", 0} -- owner, half-in mod",
" end",
" end",
" for x = 1, boardX do",
" block[x] = true",
" end",
"end",
"",
"local addPiece = function(owner, x)",
" if board[1][x][1] == \"bl\" then",
" board[1][x] = {owner, 0, x, 1}",
" return true",
" else",
" return false",
" end",
"end",
"",
"local moveTilesDown = function()",
" local settled = true -- allows for animated falling tiles",
" for y = boardY, 1, -1 do",
" for x = 1, boardX do",
" if board[y][x][1] ~= \"bl\" then",
" if board[y][x][2] == -1 then",
" board[y][x][2] = 0",
" settled = false",
" elseif (y + 1 <= boardY) then",
" if board[y + 1][x][1] == \"bl\" then",
" if board[y][x][2] == 0 then",
" board[y][x][2] = 1",
" settled = false",
" elseif board[y][x][2] == 1 then",
" board[y + 1][x] = {board[y][x][1], -1, x, y + 1}",
" board[y][x] = {\"bl\", 0, x, y}",
" settled = false",
" end",
" end",
" elseif not block[x] then",
" if board[y][x][2] == 0 then",
" board[y][x][2] = 1",
" settled = false",
" else",
" board[y][x] = {\"bl\", 0, x, y}",
" end",
" end",
" end",
" end",
" end",
" return settled",
"end",
"",
"resetBoard()",
"",
"local tileChar = {",
" {",
" \"ƒ”\",",
" \"…\",",
" },",
" {",
" \"10\",",
" \"00\",",
" },",
" {",
" \"01\",",
" \"11\",",
" }",
"}",
"",
"local to_blit = {",
" [0] = \" \",",
" [colors.white] = \"0\",",
" [colors.orange] = \"1\",",
" [colors.magenta] = \"2\",",
" [colors.lightBlue] = \"3\",",
" [colors.yellow] = \"4\",",
" [colors.lime] = \"5\",",
" [colors.pink] = \"6\",",
" [colors.gray] = \"7\",",
" [colors.lightGray] = \"8\",",
" [colors.cyan] = \"9\",",
" [colors.purple] = \"a\",",
" [colors.blue] = \"b\",",
" [colors.brown] = \"c\",",
" [colors.green] = \"d\",",
" [colors.red] = \"e\",",
" [colors.black] = \"f\",",
"}",
"",
"term.setBackgroundColor(palette.bg)",
"term.clear()",
"",
"local checkIfWinner = function()",
" local conditions = {}",
"",
" -- check horizontal",
" for y = 1, boardY do",
" for x = 1, boardX - winLength + 1 do",
" conditions[#conditions+1] = {}",
" for w = 0, winLength - 1 do",
" conditions[#conditions][w+1] = board[y][x+w]",
" end",
" end",
" end",
"",
" -- check vertical",
" for y = boardY - winLength + 1, 1, -1 do",
" for x = 1, boardX do",
" conditions[#conditions+1] = {}",
" for w = 0, winLength - 1 do",
" conditions[#conditions][w+1] = board[y+w][x]",
" end",
" end",
" end",
"",
" -- check diagonals",
" for y = 1, boardY - winLength + 1 do",
" for x = 1, boardX - winLength + 1 do",
" conditions[#conditions+1] = {}",
" conditions[#conditions+1] = {}",
" for w = 0, winLength - 1 do",
" conditions[#conditions-1][w+1] = board[y+(winLength-w-1)][x+w]",
" conditions[#conditions][w+1] = board[y+w][x+w]",
" end",
" end",
" end",
"",
" local winner, check",
" for set = 1, #conditions do",
" winner = true",
" check = conditions[set][1][1]",
" for piece = 2, #conditions[set] do",
" if conditions[set][piece][1] == \"bl\" or conditions[set][piece][1] ~= check then",
" winner = false",
" break",
" end",
" end",
" if winner then",
" return conditions[set][1][1], conditions[set]",
" end",
" end",
" return false",
"end",
"",
"local renderBoard = function()",
" local tileColRep = {",
" [\"1\"] = to_blit[palette.board]",
" }",
" local cx, cy",
" for y = 1, boardY + 1 do",
" if y == boardY + 1 then",
" term.setTextColor(palette.txt)",
" for x = 1, boardX do",
" term.setCursorPos(midX - (boardX) + (x - 1) * #tileChar[1][1], 4)",
" term.write(x)",
" end",
" cwrite(\"SPACE to clear\", scr_y, false)",
" else",
" for ymod = 1, #tileChar[1] do",
" for x = 0, boardX do",
" cx = x * #tileChar[1][1] + (midX - boardX) - 2",
" cy = y * #tileChar[1] + ymod + (midY - boardY) - 1",
" if x == 0 then",
" term.setCursorPos(cx + 1, cy)",
" term.blit(\"•\", to_blit[palette.bg], to_blit[palette.board])",
" else",
" term.setCursorPos(cx, cy)",
" if (board[y][x][2] == 0) or (board[y][x][2] == -1 and ymod == 1) or (board[y][x][2] == 1 and ymod == 2) then",
" tileColRep[\"0\"] = to_blit[tiles[ board[y][x][1] ]]",
" elseif board[y][x][2] == 2 then",
" tileColRep[\"0\"] = to_blit[palette.board]",
" else",
" tileColRep[\"0\"] = to_blit[tiles[\"bl\"]]",
" end",
" term.blit(",
" tileChar[1][ymod],",
" tileChar[2][ymod]:gsub(\".\", tileColRep),",
" tileChar[3][ymod]:gsub(\".\", tileColRep)",
" )",
" end",
" end",
" end",
" end",
" end",
"end",
"",
"local getInput = function()",
" local evt",
" while true do",
" evt = {os.pullEvent()}",
" if evt[1] == \"char\" then",
" if tonumber(evt[2]) then",
" if tonumber(evt[2]) >= 1 and tonumber(evt[2]) <= boardX then",
" if not waiting then",
" if board[1][tonumber(evt[2])][1] == \"bl\" then",
" addPiece(you, tonumber(evt[2]))",
" moveCount = moveCount + 1",
" you, nou = nou, you",
" waiting = true",
" end",
" end",
" end",
" end",
" if evt[2] == \" \" then",
" os.queueEvent(\"clear_board\")",
" for y = 1, boardY do",
" for x = 1, boardX do",
" board[y][x][2] = 0",
" end",
" end",
" for x = 1, boardX do",
" block[x] = false",
" sleep(0.05)",
" end",
" moveCount = 0",
" you, nou = \"P1\", \"P2\"",
" sleep(1)",
" for x = 1, boardX do",
" block[x] = true",
" end",
" elseif evt[2] == \"q\" then",
" return \"exit\"",
" end",
" end",
" end",
"end",
"",
"local main = function()",
" local winner, winPieces",
" while true do",
" renderBoard()",
" while not moveTilesDown() do",
" sleep(sleepDelay)",
" renderBoard()",
" end",
" winner, winPieces = checkIfWinner()",
" term.setTextColor(palette.txt)",
" if winner then",
" cblit(",
" \"Winner: \" .. winner,",
" to_blit[palette.txt]:rep(8) .. to_blit[tiles[winner]]:rep(#winner),",
" to_blit[palette.bg]:rep(8 + #winner),",
" 1,",
" true",
" )",
" parallel.waitForAny(function()",
" while true do",
" for p = 1, #winPieces do",
" board[winPieces[p][4]][winPieces[p][3]][2] = 0",
" end",
" renderBoard()",
" sleep(0.3)",
" for p = 1, #winPieces do",
" board[winPieces[p][4]][winPieces[p][3]][2] = 2",
" end",
" renderBoard()",
" sleep(0.2)",
" end",
" end, function()",
" local evt",
" repeat",
" evt = {os.pullEvent()}",
" until evt[1] == \"clear_board\"",
" end)",
" elseif moveCount >= boardX * boardY then",
" cwrite(\"It's a tie.\", 1, true)",
" waiting = true",
" else",
" waiting = false",
" cblit(",
" \"It's \" .. you .. \"'s turn.\",",
" to_blit[palette.txt]:rep(5) .. to_blit[tiles[you]]:rep(#you) .. to_blit[palette.txt]:rep(8),",
" to_blit[palette.bg]:rep(13 + #you),",
" 1,",
" true",
" )",
" end",
" sleep(sleepDelay)",
" end",
"end",
"",
"parallel.waitForAny(main, getInput)",
"cwrite(\"Thanks for playing!\", 1, true)",
"term.setCursorPos(1, scr_y)",
"term.clearLine()",
},
[ "/game/quickdraw.lua" ] = {
"--[[",
" QuickDraw!",
" Can you outshoot the cowbow?",
" I bet you can! It's actually really easy...",
"",
" pastebin get uGTzMxNL quickdraw",
" std pb uGTzMxNL quickdraw",
" std ld quickdraw",
"--]]",
"",
"local difficulty = 1.2 --amount of time you have to shoot im'",
"",
"local isRunning = true --whether the game should loop",
"local over = false --whether you or the guy is dead",
"",
"local wins = 0",
"local losses = 0",
"",
"local s = {",
" enemy = {",
" getready = {{},{},{0,0,0,0,0,0,0,0,0,0,0,0,0,2,2,2,2,},{0,0,0,0,0,0,0,0,0,0,0,0,2,2,2,2,2,2,},{0,0,0,0,0,0,0,0,0,0,0,0,0,16,16,16,16,},{0,0,0,0,0,0,0,0,0,0,0,0,0,16,16,16,16,},{0,0,0,0,0,0,0,0,0,0,0,0,0,0,16,16,},{0,0,0,0,0,0,0,0,0,0,0,0,4096,4096,128,4096,4096,4096,4096,},{0,0,0,0,0,0,0,0,0,0,0,4096,0,4096,128,4096,4096,0,4096,},{0,0,0,0,0,0,0,0,0,0,0,4096,0,4096,128,4096,4096,0,4096,},{0,0,0,0,0,0,0,0,0,0,0,4096,0,4096,128,4096,4096,0,4096,},{0,0,0,0,0,0,0,0,0,0,0,0,256,4096,128,4096,4096,4096,},{0,0,0,0,0,0,0,0,0,0,0,0,0,2048,2048,2048,2048,},{0,0,0,0,0,0,0,0,0,0,0,0,0,2048,0,2048,2048,},{0,0,0,0,0,0,0,0,0,0,0,0,0,2048,0,0,2048,},{0,0,0,0,0,0,0,0,0,0,0,0,0,2048,0,0,2048,},{0,0,0,0,0,0,0,0,0,0,0,0,0,2048,0,0,2048,},},",
" shoot1 = {{},{},{0,0,0,0,0,0,0,0,0,0,0,0,0,2,2,2,2,},{0,0,0,0,0,0,0,0,0,0,0,0,2,2,2,2,2,2,},{0,0,0,0,0,0,0,0,0,0,0,0,0,16,16,16,16,},{0,0,0,0,0,0,0,0,0,0,0,0,0,16,16,16,16,},{0,0,0,0,0,0,0,0,0,0,0,0,0,0,16,16,},{0,0,0,0,0,0,0,0,0,0,0,0,0,4096,128,4096,4096,},{0,0,0,0,0,0,0,0,0,0,0,0,4096,4096,128,4096,4096,4096,},{0,0,0,0,0,0,0,0,0,0,0,4096,0,4096,4096,128,4096,4096,},{0,0,0,0,0,0,0,0,0,0,0,256,0,4096,4096,128,4096,4096,},{0,0,0,0,0,0,0,0,0,0,0,0,0,4096,4096,128,4096,},{0,0,0,0,0,0,0,0,0,0,0,0,0,2048,2048,2048,2048,},{0,0,0,0,0,0,0,0,0,0,0,0,0,2048,2048,2048,2048,},{0,0,0,0,0,0,0,0,0,0,0,0,0,2048,0,0,2048,},{0,0,0,0,0,0,0,0,0,0,0,0,0,2048,0,0,2048,},{0,0,0,0,0,0,0,0,0,0,0,0,0,2048,0,0,2048,},},",
" shoot2 = {{},{},{0,0,0,0,0,0,0,0,0,0,0,0,0,2,2,2,2,},{0,0,0,0,0,0,0,0,0,0,0,0,2,2,2,2,2,2,},{0,0,0,0,0,0,0,0,0,0,0,0,0,16,16,16,16,},{0,0,0,0,0,0,0,0,0,0,0,0,0,16,16,16,16,},{0,0,0,0,0,0,0,0,0,0,0,0,0,0,16,16,},{0,0,0,0,0,0,0,0,0,0,0,0,256,4096,4096,128,4096,},{0,0,0,0,0,0,0,0,0,0,0,0,4096,4096,4096,128,4096,4096,},{0,0,0,0,0,0,0,0,0,0,0,0,0,4096,4096,128,4096,0,4096,},{0,0,0,0,0,0,0,0,0,0,0,0,0,4096,4096,128,4096,0,4096,},{0,0,0,0,0,0,0,0,0,0,0,0,0,4096,4096,128,4096,},{0,0,0,0,0,0,0,0,0,0,0,0,0,2048,2048,2048,2048,},{0,0,0,0,0,0,0,0,0,0,0,0,0,2048,2048,0,2048,},{0,0,0,0,0,0,0,0,0,0,0,0,0,2048,0,0,2048,},{0,0,0,0,0,0,0,0,0,0,0,0,0,2048,0,0,2048,},{0,0,0,0,0,0,0,0,0,0,0,0,0,2048,0,0,2048,},},",
" laugh = {{},{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,},{0,0,0,0,0,0,0,0,0,0,0,0,0,2,2,2,2,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,},{0,0,0,0,0,0,0,0,0,0,0,0,2,2,2,2,2,2,0,0,0,0,1,1,32768,1,1,32768,1,1,32768,32768,1,1,32768,1,1,},{0,0,0,0,0,0,0,0,0,0,0,0,0,16,16,16,16,0,0,0,1,1,1,1,32768,1,1,32768,1,32768,1,1,32768,1,32768,1,1,},{0,0,0,0,0,0,0,0,0,0,0,0,0,16,16,16,16,0,1,1,1,1,1,1,32768,32768,32768,32768,1,32768,32768,32768,32768,1,32768,1,1,},{0,0,0,0,0,0,0,0,0,0,0,0,0,0,16,16,0,0,0,0,1,1,1,1,32768,1,1,32768,1,32768,1,1,32768,1,1,1,1,},{0,0,0,0,0,0,0,0,0,0,0,0,0,4096,4096,128,4096,0,0,0,0,0,1,1,32768,1,1,32768,1,32768,1,1,32768,1,32768,1,1,},{0,0,0,0,0,0,0,0,0,0,0,0,4096,4096,4096,128,4096,4096,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,},{0,0,0,0,0,0,0,0,0,0,0,4096,0,4096,4096,128,4096,0,4096,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,},{0,0,0,0,0,0,0,0,0,0,0,4096,0,4096,4096,128,4096,0,4096,},{0,0,0,0,0,0,0,0,0,0,0,0,4096,4096,4096,128,4096,4096,},{0,0,0,0,0,0,0,0,0,0,0,0,0,2048,2048,2048,2048,},{0,0,0,0,0,0,0,0,0,0,0,0,0,2048,2048,0,2048,},{0,0,0,0,0,0,0,0,0,0,0,0,0,2048,0,0,2048,},{0,0,0,0,0,0,0,0,0,0,0,0,0,2048,0,0,2048,},{0,0,0,0,0,0,0,0,0,0,0,0,0,2048,0,0,2048,},},",
" dead = {{},{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,},{0,0,0,0,0,0,0,0,0,0,0,0,0,2,2,2,2,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,},{0,0,0,0,0,0,0,0,0,0,0,0,2,2,2,2,2,2,0,0,0,0,1,1,1,32768,32768,1,1,32768,1,32768,1,32768,1,1,1,},{0,0,0,0,0,0,0,0,0,0,0,4096,0,16,16,16,16,0,4096,0,1,1,1,1,32768,1,1,32768,1,32768,1,32768,1,32768,1,1,1,},{0,0,0,0,0,0,0,0,0,0,0,4096,0,16,16,16,16,0,1,1,1,1,1,1,32768,32768,32768,32768,1,32768,32768,32768,1,32768,1,1,1,},{0,0,0,0,0,0,0,0,0,0,0,4096,0,0,16,16,0,0,4096,0,1,1,1,1,32768,1,1,32768,1,32768,1,32768,1,1,1,1,1,},{0,0,0,0,0,0,0,0,0,0,0,4096,0,4096,4096,128,4096,0,4096,0,0,0,1,1,32768,1,1,32768,1,32768,1,32768,1,32768,1,1,1,},{0,0,0,0,0,0,0,0,0,0,0,0,4096,4096,4096,128,4096,4096,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,},{0,0,0,0,0,0,0,0,0,0,0,0,0,4096,4096,128,4096,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,},{0,0,0,0,0,0,0,0,0,0,0,0,0,4096,4096,128,4096,},{0,0,0,0,0,0,0,0,0,0,0,0,0,4096,4096,128,4096,},{0,0,0,0,0,0,0,0,0,0,0,0,0,2048,2048,2048,2048,},{0,0,0,0,0,0,0,0,0,0,0,0,0,2048,2048,0,2048,},{0,0,0,0,0,0,0,0,0,0,0,0,0,2048,0,0,2048,},{0,0,0,0,0,0,0,0,0,0,0,0,0,2048,0,0,2048,},{0,0,0,0,0,0,0,0,0,0,0,0,0,2048,0,0,2048,},},",
" },",
" bg = {{8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,},{8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,},{8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,},{8,8,8,8,8,1,1,1,1,8,8,8,1,1,8,8,8,8,8,8,8,8,8,8,8,8,8,1,1,1,1,1,1,8,8,8,8,8,8,8,8,8,8,16,16,8,8,8,8,8,8,},{8,8,8,1,1,1,1,1,1,1,1,1,1,1,1,1,8,8,8,8,8,8,8,8,8,1,1,1,1,1,1,1,1,1,8,8,8,8,8,8,8,8,16,16,16,16,8,8,8,8,8,},{8,8,8,1,1,1,1,1,1,1,1,1,1,1,1,1,8,8,8,8,8,8,8,8,8,1,1,1,1,1,1,1,1,1,8,8,8,8,8,8,8,8,8,16,16,8,8,8,8,8,8,},{8,8,8,1,1,1,1,1,1,1,1,1,1,1,1,8,8,8,8,8,8,8,8,8,8,8,8,1,1,8,1,1,1,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,},{8,8,8,8,8,1,1,1,8,8,8,1,1,1,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,},{8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,},{8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,},{8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,},{8,8,8,8,8,128,128,128,128,128,128,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,},{8,8,8,8,8,128,128,128,128,128,128,128,128,128,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,16,16,16,16,16,16,16,16,16,16,},{16,16,16,16,16,128,128,128,128,128,128,128,128,128,16,16,16,16,16,16,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,},{16,16,16,16,16,128,128,128,128,128,128,128,128,128,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,},{16,16,16,16,16,128,128,128,128,128,128,128,128,128,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,},{256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,},{256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,},{16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,},},",
"}",
"_s = s",
"",
"local scr_x, scr_y = term.getSize()",
"",
"local yield = function()",
" os.queueEvent(\"yield\")",
" os.pullEvent(\"yield\")",
"end",
"",
"local RPGslowprint = function(text,rate)",
" local cX,cY = term.getCursorPos()",
" yield()",
" local uutcome = parallel.waitForAny(function()",
" textutils.slowPrint(text,rate or 20)",
" end, function()",
" os.pullEvent(\"key\")",
" end)",
" if uutcome == 2 then",
" term.setCursorPos(cX,cY)",
" print(text)",
" end",
"end",
"",
"local displayHelp = function(cli)",
" local helptext = [[",
" QuickDraw by EldidiStroyrr",
"",
" HOW TO PLAY:",
"",
" 1) Click and hold on the green square for three seconds.",
" 2) As soon as it says DRAW, quickly move your mouse over the guy and let go.",
" 3) If you win, it'll get slightly harder",
"",
" Press 'Q' to quit ingame.",
"]]",
" if cli then",
" print(helptext)",
" else",
" term.setBackgroundColor(colors.gray)",
" term.setTextColor(colors.white)",
" term.setCursorPos(1,2)",
" term.clear()",
" RPGslowprint(helptext,30)",
" term.setCursorPos(2,scr_y-1)",
" term.write(\"Press any key to continue!\")",
" yield()",
" os.pullEvent(\"key\")",
" end",
"end",
"",
"function mixImages( img1, img2 )",
" local output = { }",
" for a = 1, #img2 do",
" output[ a ] = { }",
" if not img1[ a ] then",
" for b = 1, #img2[ a ] do",
" output[ a ][ b ] = img2[ a ][ b ]",
" end",
" else",
" for b = 1, #img2[ a ] do",
" if img1[ a ][ b ] then",
" if img1[ a ][ b ] ~= 0 then",
" output[ a ][ b ] = img1[ a ][ b ]",
" else",
" output[ a ][ b ] = img2[ a ][ b ]",
" end",
" else",
" output[ a ][ b ] = img2[ a ][ b ]",
" end",
" end",
" end",
" end",
" return output",
"end",
"",
"local function clear()",
" local b,t = term.getBackgroundColor(), term.getTextColor()",
" term.setBackgroundColor(colors.black)",
" term.clear()",
" term.setBackgroundColor(b)",
"end",
"",
"local function cprint(txt)",
" local pX, pY = term.getCursorPos()",
" term.setCursorPos((scr_x/2)-math.floor(#txt/2),(scr_y/2)+4)",
" term.write(txt)",
" term.setCursorPos(pX,pY)",
"end",
"",
"local gameArea, alive",
"",
"local function handleShooting()",
" currentSprite = \"getready\"",
" sleep(difficulty/4)",
" paintutils.drawImage(mixImages(s.enemy.shoot1,s.bg),1,1)",
" currentSprite = \"shoot1\"",
" sleep(difficulty/4)",
" paintutils.drawImage(mixImages(s.enemy.shoot2,s.bg),1,1)",
" currentSprite = \"shoot2\"",
" sleep(difficulty/2)",
" os.queueEvent(\"thoseWhoDig\",false)",
" return false, \"dead\"",
"end",
"",
"function drawHitBox(color)",
" paintutils.drawFilledBox(scr_x-3,scr_y-2,scr_x,scr_y,color)",
" term.setBackgroundColor(colors.lightBlue)",
" term.setTextColor(colors.white)",
" local txt = \"YOU: \"..wins..\" / ENEMY: \"..losses",
" term.setCursorPos(scr_x-(#txt+1)+1,1)",
" term.write(txt)",
" term.setBackgroundColor(colors.lightGray)",
" term.setTextColor(colors.gray)",
" local txt = \"TIME: \"..tostring(difficulty):sub(1,5)..\" SEC\"",
" term.setCursorPos(2,scr_y-1)",
" term.write(txt)",
"end",
"",
"function exitGame()",
" if not isRunning then",
" term.setCursorPos(1,scr_y)",
" term.setBackgroundColor(colors.black)",
" term.write(string.rep(\" \",scr_x-4))",
" term.setCursorPos(1,scr_y)",
" sleep(0)",
" end",
" error()",
"end",
"",
"currentSprite = \"getready\"",
"",
"local function countdown()",
" term.setCursorPos((scr_x/2)-2,scr_y/2)",
" term.setTextColor(colors.black)",
" term.setBackgroundColor(colors.lightBlue)",
" cprint(\"3...\")",
" sleep(0.8)",
" cprint(\"2...\")",
" sleep(0.8)",
" cprint(\"1...\")",
" sleep(0.8)",
" cprint(\"DRAW!\")",
"end",
"",
"function getInput()",
" alive = true",
" os.pullEvent(\"getMeSomeInput\")",
" while true do",
" local evt",
" if gameArea == \"beginning1\" then",
" evt = {os.pullEvent()}",
" if evt[1] == \"mouse_click\" then",
" if evt[3] >= scr_x-3 and evt[4] >= scr_y-2 then",
" local res = parallel.waitForAny(function()",
" while true do",
" local evt = {os.pullEvent()}",
" if evt[1] == \"mouse_up\" or evt[1] == \"mouse_click\" then",
" break",
" elseif evt[1] == \"mouse_drag\" then",
" if (evt[3] < scr_x-3) or (evt[4] < scr_y-2) then",
" break",
" end",
" end",
" end",
" end, countdown)",
" if (res == 1) and not over then",
" cprint(\"FOUL!!\")",
" exitGame()",
" end",
" os.queueEvent(\"imready\")",
" parallel.waitForAny(function()",
" while alive do",
" evt = {os.pullEvent()}",
" if evt[1] == \"mouse_up\" then",
" local x,y = evt[3],evt[4]",
" if _s.enemy[currentSprite][y] then",
" if _s.enemy[currentSprite][y][x] then",
" if _s.enemy[currentSprite][y][x] ~= 0 then",
" os.queueEvent(\"thoseWhoDig\",true,x,y)",
" break",
" end",
" end",
" end",
" sleep(0.2)",
" elseif evt[1] == \"mouse_click\" then --yay for anticheating",
" sleep(1)",
" end",
" end",
" end, handleShooting)",
" end",
" elseif evt[1] == \"key\" then",
" if evt[2] == keys.q then",
" isRunning = false",
" exitGame()",
" end",
" end",
" end",
" end",
"end",
"",
"local flash = {",
" colors.white,",
" colors.lightGray,",
" colors.black,",
" colors.gray,",
"}",
"",
"local tArg = {...}",
"if tArg[1] == \"help\" then",
" return displayHelp(true)",
"end",
"",
"function game()",
" over = false",
" term.setTextColor(colors.white)",
" while true do",
" gameArea = \"beginning1\"",
" paintutils.drawImage(mixImages(s.enemy.getready,s.bg),1,1)",
" drawHitBox(colors.green)",
" currentSprite = \"getready\"",
" os.queueEvent(\"getMeSomeInput\")",
" os.pullEvent(\"imready\")",
" os.queueEvent(\"shootStart!\")",
" local _,alive,x,y = os.pullEvent(\"thoseWhoDig\")",
" over = true",
" if not alive then",
" for a = 1, #flash do",
" term.setBackgroundColor(flash[a])",
" term.clear()",
" sleep(0.1)",
" end",
" losses = losses + 1",
" paintutils.drawImage(mixImages(s.enemy.laugh,s.bg),1,1)",
" term.setTextColor(colors.red)",
" term.setBackgroundColor(colors.lightBlue)",
" sleep(0.5)",
" exitGame()",
" else",
" paintutils.drawImage(mixImages(s.enemy.dead,s.bg),1,1)",
" paintutils.drawPixel(x,y,colors.red)",
" sleep(0.2)",
" term.setBackgroundColor(colors.lightBlue)",
" term.setTextColor(colors.black)",
" cprint(\"YOU WIN!\")",
" wins = wins + 1",
" sleep(0.8)",
" difficulty = difficulty * 0.92",
" exitGame()",
" end",
" end",
"end",
"",
"clear()",
"displayHelp(false)",
"while isRunning do",
" parallel.waitForAny(getInput,game)",
" if isRunning then",
" sleep(0.8)",
" end",
"end",
},
[ "/game/data/sprites/stickdude/walkshoot0.nft" ] = {
"0f‡ƒf0e†",
"0f’0€f„e“",
"  f0•  fe‚",
"˜‰",
"0fšŸf0…",
},
[ "/game/data/sprites/megaman/buster3-1.nft" ] = {
"  0f‡40žf4„",
"  4f…0Ÿf†00€4‚fƒf0",
"  4f00€€€€€€€4‚f",
"400€€€€€€€€f4•",
"  0440Ÿ0€€€€€fŸ",
"  f4Š00€4f‰f0‹4ƒ",
"  f0‚4",
},
[ "/game/data/sprites/stickdude/walk0.nft" ] = {
"0f‡ƒf0",
"0f’0€f„",
"  f0•",
"˜‰",
"0fšŸf0…",
},
[ "/toy/elements.lua" ] = {
"-- pastebin get vxLQ1fVb element",
"-- std pb vxLQ1fVb element",
"",
"local scr_x, scr_y = term.getSize()",
"-- for state, 1=gas, 2=liquid, 3=solid",
"elements = {",
" [1] = {",
" name = \"hydrogen\",",
" symbol = \"H\",",
" mass = 1.008,",
" group = 1,",
" period = 1,",
" state = 1,",
" eleconfig = \"\",",
" },",
" [2] = {",
" name = \"helium\",",
" symbol = \"He\",",
" mass = 4.002602,",
" group = 18,",
" period = 1,",
" state = 1,",
" eleconfig = \"\",",
" },",
" [3] = {",
" name = \"lithium\",",
" symbol = \"Li\",",
" mass = 6.94,",
" group = 1,",
" period = 2,",
" state = 3,",
" eleconfig = \"\",",
" },",
" [4] = {",
" name = \"beryllium\",",
" symbol = \"Be\",",
" mass = 9.0121831,",
" group = 2,",
" period = 2,",
" state = 3,",
" eleconfig = \"\",",
" },",
" [5] = {",
" name = \"boron\",",
" symbol = \"B\",",
" mass = 10.81,",
" group = 13,",
" period = 2,",
" state = 3,",
" eleconfig = \"\",",
" },",
" [6] = {",
" name = \"carbon\",",
" symbol = \"C\",",
" mass = 12.011,",
" group = 14,",
" period = 2,",
" state = 3,",
" eleconfig = \"\",",
" },",
" [7] = {",
" name = \"nitrogen\",",
" symbol = \"N\",",
" mass = 14.007,",
" group = 15,",
" period = 2,",
" state = 1,",
" eleconfig = \"\",",
" },",
" [8] = {",
" name = \"oxygen\",",
" symbol = \"O\",",
" mass = 15.999,",
" group = 16,",
" period = 2,",
" state = 1,",
" eleconfig = \"\",",
" },",
" [9] = {",
" name = \"fluorine\",",
" symbol = \"F\",",
" mass = 18.998403163,",
" group = 17,",
" period = 2,",
" state = 1,",
" eleconfig = \"\",",
" },",
" [10] = {",
" name = \"neon\",",
" symbol = \"Ne\",",
" mass = 20.1797,",
" group = 18,",
" period = 2,",
" state = 1,",
" eleconfig = \"\",",
" },",
" [11] = {",
" name = \"sodium\",",
" symbol = \"Na\",",
" mass = 22.98976928,",
" group = 1,",
" period = 3,",
" state = 3,",
" eleconfig = \"\",",
" },",
" [12] = {",
" name = \"magnesium\",",
" symbol = \"Mg\",",
" mass = 24.305,",
" group = 2,",
" period = 3,",
" state = 3,",
" eleconfig = \"\",",
" },",
" [13] = {",
" name = \"aluminum\",",
" symbol = \"Al\",",
" mass = 26.9815385,",
" group = 13,",
" period = 3,",
" state = 3,",
" eleconfig = \"\",",
" },",
" [14] = {",
" name = \"silicon\",",
" symbol = \"Si\",",
" mass = 28.085,",
" group = 14,",
" period = 3,",
" state = 3,",
" eleconfig = \"\",",
" },",
" [15] = {",
" name = \"phosphorus\",",
" symbol = \"P\",",
" mass = 30.973761998,",
" group = 15,",
" period = 3,",
" state = 3,",
" eleconfig = \"\",",
" },",
" [16] = {",
" name = \"sulfur\",",
" symbol = \"S\",",
" mass = 32.06,",
" group = 16,",
" period = 3,",
" state = 3,",
" eleconfig = \"\",",
" },",
" [17] = {",
" name = \"chlorine\",",
" symbol = \"Cl\",",
" mass = 35.45,",
" group = 17,",
" period = 3,",
" state = 1,",
" eleconfig = \"\",",
" },",
" [18] = {",
" name = \"argon\",",
" symbol = \"Ar\",",
" mass = 39.945,",
" group = 18,",
" period = 3,",
" state = 1,",
" eleconfig = \"\",",
" },",
" [19] = {",
" name = \"potassium\",",
" symbol = \"K\",",
" mass = 39.0953,",
" group = 1,",
" period = 4,",
" state = 3,",
" eleconfig = \"\",",
" },",
" [20] = {",
" name = \"calcium\",",
" symbol = \"Ca\",",
" mass = 40.075,",
" group = 2,",
" period = 4,",
" state = 3,",
" eleconfig = \"\",",
" },",
" [21] = {",
" name = \"scandium\",",
" symbol = \"Sc\",",
" mass = 44.955905,",
" group = 3,",
" period = 4,",
" state = 3,",
" eleconfig = \"\",",
" },",
" [22] = {",
" name = \"titanium\",",
" symbol = \"Ti\",",
" mass = 47.587,",
" group = 4,",
" period = 4,",
" state = 3,",
" eleconfig = \"\",",
" },",
" [23] = {",
" name = \"vanadium\",",
" symbol = \"V\",",
" mass = 50.9,",
" group = 5,",
" period = 4,",
" state = 3,",
" eleconfig = \"\",",
" },",
" [24] = {",
" name = \"chromium\",",
" symbol = \"Cr\",",
" mass = 51.9961,",
" group = 6,",
" period = 4,",
" state = 3,",
" eleconfig = \"\",",
" },",
" [25] = {",
" name = \"manganese\",",
" symbol = \"Mn\",",
" mass = 54.938044,",
" group = 7,",
" period = 4,",
" state = 3,",
" eleconfig = \"\",",
" },",
" [26] = {",
" name = \"iron\",",
" symbol = \"Fe\",",
" mass = 55.845,",
" group = 8,",
" period = 4,",
" state = 3,",
" eleconfig = \"\",",
" },",
" [27] = {",
" name = \"cobalt\",",
" symbol = \"Co\",",
" mass = 58.933194,",
" group = 9,",
" period = 4,",
" state = 3,",
" eleconfig = \"\",",
" },",
" [28] = {",
" name = \"nickel\",",
" symbol = \"Ni\",",
" mass = 58.6934,",
" group = 10,",
" period = 4,",
" state = 3,",
" eleconfig = \"\",",
" },",
" [29] = {",
" name = \"copper\",",
" symbol = \"Cu\",",
" mass = 63.546,",
" group = 11,",
" period = 4,",
" state = 3,",
" eleconfig = \"\",",
" },",
" [30] = {",
" name = \"zinc\",",
" symbol = \"Zn\",",
" mass = 65.38,",
" group = 12,",
" period = 4,",
" state = 3,",
" eleconfig = \"\",",
" },",
" [31] = {",
" name = \"gallium\",",
" symbol = \"Ga\",",
" mass = 69.723,",
" group = 13,",
" period = 4,",
" state = 3,",
" eleconfig = \"\",",
" },",
" [32] = {",
" name = \"germanium\",",
" symbol = \"Ge\",",
" mass = 72.63,",
" group = 14,",
" period = 4,",
" state = 3,",
" eleconfig = \"\",",
" },",
" [33] = {",
" name = \"arsenic\",",
" symbol = \"As\",",
" mass = 74.921595,",
" group = 15,",
" period = 4,",
" state = 3,",
" eleconfig = \"\",",
" },",
" [34] = {",
" name = \"selenium\",",
" symbol = \"Se\",",
" mass = 78.971,",
" group = 16,",
" period = 4,",
" state = 3,",
" eleconfig = \"\",",
" },",
" [35] = {",
" name = \"bromine\",",
" symbol = \"Br\",",
" mass = 79.904,",
" group = 17,",
" period = 4,",
" state = 2,",
" eleconfig = \"\",",
" },",
" [36] = {",
" name = \"krypton\",",
" symbol = \"Kr\",",
" mass = 83.798,",
" group = 18,",
" period = 4,",
" state = 1,",
" eleconfig = \"\",",
" },",
" [37] = {",
" name = \"rubidium\",",
" symbol = \"Rb\",",
" mass = 85.4678,",
" group = 1,",
" period = 5,",
" state = 1,",
" eleconfig = \"\",",
" },",
" [38] = {",
" name = \"strontium\",",
" symbol = \"Sr\",",
" mass = 87.62,",
" group = 2,",
" period = 5,",
" state = 3,",
" eleconfig = \"\",",
" },",
" [39] = {",
" name = \"yttrium\",",
" symbol = \"Y\",",
" mass = 88.90584,",
" group = 3,",
" period = 5,",
" state = 3,",
" eleconfig = \"\",",
" },",
" [40] = {",
" name = \"zirconium\",",
" symbol = \"Zr\",",
" mass = 91.224,",
" group = 4,",
" period = 5,",
" state = 3,",
" eleconfig = \"\",",
" },",
" [41] = {",
" name = \"niobium\",",
" symbol = \"Nb\",",
" mass = 92.90637,",
" group = 5,",
" period = 5,",
" state = 3,",
" eleconfig = \"\",",
" },",
" [42] = {",
" name = \"molybdenum\",",
" symbol = \"Mo\",",
" mass = 95.95,",
" group = 6,",
" period = 5,",
" state = 3,",
" eleconfig = \"\",",
" },",
" [43] = {",
" name = \"technetium\",",
" symbol = \"Tc\",",
" mass = 98,",
" group = 7,",
" period = 5,",
" state = 3,",
" eleconfig = \"\",",
" },",
" [44] = {",
" name = \"ruthenium\",",
" symbol = \"Ru\",",
" mass = 101.07,",
" group = 8,",
" period = 5,",
" state = 3,",
" eleconfig = \"\",",
" },",
" [45] = {",
" name = \"rhodium\",",
" symbol = \"Rh\",",
" mass = 102.9055,",
" group = 9,",
" period = 5,",
" state = 3,",
" eleconfig = \"\",",
" },",
" [46] = {",
" name = \"palladium\",",
" symbol = \"Pd\",",
" mass = 106.42,",
" group = 10,",
" period = 5,",
" state = 3,",
" eleconfig = \"\",",
" },",
" [47] = {",
" name = \"silver\",",
" symbol = \"Ag\",",
" mass = 107.8682,",
" group = 11,",
" period = 5,",
" state = 3,",
" eleconfig = \"\",",
" },",
" [48] = {",
" name = \"cadmium\",",
" symbol = \"Cd\",",
" mass = 112.414,",
" group = 12,",
" period = 5,",
" state = 3,",
" eleconfig = \"\",",
" },",
" [49] = {",
" name = \"indium\",",
" symbol = \"In\",",
" mass = 114.818,",
" group = 13,",
" period = 5,",
" state = 3,",
" eleconfig = \"\",",
" },",
" [50] = {",
" name = \"tin\",",
" symbol = \"Sn\",",
" mass = 118.710,",
" group = 14,",
" period = 5,",
" state = 3,",
" eleconfig = \"\",",
" },",
" [51] = {",
" name = \"antimony\",",
" symbol = \"Sb\",",
" mass = 121.760,",
" group = 15,",
" period = 5,",
" state = 3,",
" eleconfig = \"\",",
" },",
" [52] = {",
" name = \"tellurium\",",
" symbol = \"Te\",",
" mass = 127.6,",
" group = 16,",
" period = 5,",
" state = 3,",
" eleconfig = \"\",",
" },",
" [53] = {",
" name = \"iodine\",",
" symbol = \"I\",",
" mass = 126.90447,",
" group = 17,",
" period = 5,",
" state = 3,",
" eleconfig = \"\",",
" },",
" [54] = {",
" name = \"xenon\",",
" symbol = \"Xe\",",
" mass = 131.293,",
" group = 18,",
" period = 5,",
" state = 1,",
" eleconfig = \"\",",
" },",
" [55] = {",
" name = \"cesium\",",
" symbol = \"Cs\",",
" mass = 132.90545196,",
" group = 1,",
" period = 6,",
" state = 3,",
" eleconfig = \"\",",
" },",
" [56] = {",
" name = \"barium\",",
" symbol = \"Ba\",",
" mass = 137.327,",
" group = 2,",
" period = 6,",
" state = 3,",
" eleconfig = \"\",",
" },",
" [57] = {",
" name = \"lanthanum\",",
" symbol = \"La\",",
" mass = 138.90547,",
" group = 4,",
" period = 9,",
" state = 3,",
" eleconfig = \"\",",
" },",
" [58] = {",
" name = \"cerium\",",
" symbol = \"Ce\",",
" mass = 140.116,",
" group = 5,",
" period = 9,",
" state = 3,",
" eleconfig = \"\",",
" },",
" [59] = {",
" name = \"praseodymium \",",
" symbol = \"Pr\",",
" mass = 140.90766,",
" group = 6,",
" period = 9,",
" state = 3,",
" eleconfig = \"\",",
" },",
" [60] = {",
" name = \"neodymium\",",
" symbol = \"Nd\",",
" mass = 144.242,",
" group = 7,",
" period = 9,",
" state = 3,",
" eleconfig = \"\",",
" },",
" [61] = {",
" name = \"promethium\",",
" symbol = \"Pm\",",
" mass = 145,",
" group = 8,",
" period = 9,",
" state = 3,",
" eleconfig = \"\",",
" },",
" [62] = {",
" name = \"samarium\",",
" symbol = \"Sm\",",
" mass = 150.36,",
" group = 9,",
" period = 9,",
" state = 3,",
" eleconfig = \"\",",
" },",
" [63] = {",
" name = \"europium\",",
" symbol = \"Eu\",",
" mass = 151.964,",
" group = 10,",
" period = 9,",
" state = 3,",
" eleconfig = \"\",",
" },",
" [64] = {",
" name = \"gadolinium\",",
" symbol = \"Gd\",",
" mass = 157.25,",
" group = 11,",
" period = 9,",
" state = 3,",
" eleconfig = \"\",",
" },",
" [65] = {",
" name = \"terbium\",",
" symbol = \"Tb\",",
" mass = 158.92535,",
" group = 12,",
" period = 9,",
" state = 3,",
" eleconfig = \"\",",
" },",
" [66] = {",
" name = \"dysprosium\",",
" symbol = \"Dy\",",
" mass = 162.5,",
" group = 13,",
" period = 9,",
" state = 3,",
" eleconfig = \"\",",
" },",
" [67] = {",
" name = \"holmium\",",
" symbol = \"Ho\",",
" mass = 164.93033,",
" group = 14,",
" period = 9,",
" state = 3,",
" eleconfig = \"\",",
" },",
" [68] = {",
" name = \"erbium\",",
" symbol = \"Er\",",
" mass = 167.259,",
" group = 15,",
" period = 9,",
" state = 3,",
" eleconfig = \"\",",
" },",
" [69] = {",
" name = \"thulium\",",
" symbol = \"Tm\",",
" mass = 168.93422,",
" group = 16,",
" period = 9,",
" state = 3,",
" eleconfig = \"\",",
" },",
" [70] = {",
" name = \"ytterbium\",",
" symbol = \"Yb\",",
" mass = 173.045,",
" group = 17,",
" period = 9,",
" state = 3,",
" eleconfig = \"\",",
" },",
" [71] = {",
" name = \"lutetium\",",
" symbol = \"Lu\",",
" mass = 174.9668,",
" group = 18,",
" period = 9,",
" state = 3,",
" eleconfig = \"\",",
" },",
" [72] = {",
" name = \"hafnium\",",
" symbol = \"Hf\",",
" mass = 178.49,",
" group = 4,",
" period = 6,",
" state = 3,",
" eleconfig = \"\",",
" },",
" [73] = {",
" name = \"tantalum\",",
" symbol = \"Ta\",",
" mass = 180.94788,",
" group = 5,",
" period = 6,",
" state = 3,",
" eleconfig = \"\",",
" },",
" [74] = {",
" name = \"tungsten\",",
" symbol = \"W\",",
" mass = 183.84,",
" group = 6,",
" period = 6,",
" state = 3,",
" eleconfig = \"\",",
" },",
" [75] = {",
" name = \"rhenium\",",
" symbol = \"Re\",",
" mass = 186.207,",
" group = 7,",
" period = 6,",
" state = 3,",
" eleconfig = \"\",",
" },",
" [76] = {",
" name = \"osmium\",",
" symbol = \"Os\",",
" mass = 190.23,",
" group = 8,",
" period = 6,",
" state = 3,",
" eleconfig = \"\",",
" },",
" [77] = {",
" name = \"iridium\",",
" symbol = \"Ir\",",
" mass = 192.217,",
" group = 9,",
" period = 6,",
" state = 3,",
" eleconfig = \"\",",
" },",
" [78] = {",
" name = \"platinum\",",
" symbol = \"Pt\",",
" mass = 195.084,",
" group = 10,",
" period = 6,",
" state = 3,",
" eleconfig = \"\",",
" },",
" [79] = {",
" name = \"gold\",",
" symbol = \"Au\",",
" mass = 196.966569,",
" group = 11,",
" period = 6,",
" state = 3,",
" eleconfig = \"\",",
" },",
" [80] = {",
" name = \"mercury\",",
" symbol = \"Hg\",",
" mass = 200.59,",
" group = 12,",
" period = 6,",
" state = 2,",
" eleconfig = \"\",",
" },",
" [81] = {",
" name = \"thallium\",",
" symbol = \"Tl\",",
" mass = 204.38,",
" group = 13,",
" period = 6,",
" state = 3,",
" eleconfig = \"\",",
" },",
" [82] = {",
" name = \"lead\",",
" symbol = \"Pb\",",
" mass = 207.2,",
" group = 14,",
" period = 6,",
" state = 3,",
" eleconfig = \"\",",
" },",
" [83] = {",
" name = \"bismuth\",",
" symbol = \"Bi\",",
" mass = 208.9804,",
" group = 15,",
" period = 6,",
" state = 3,",
" eleconfig = \"\",",
" },",
" [84] = {",
" name = \"polonium\",",
" symbol = \"Po\",",
" mass = 209,",
" group = 16,",
" period = 6,",
" state = 3,",
" eleconfig = \"\",",
" },",
" [85] = {",
" name = \"astatine\",",
" symbol = \"At\",",
" mass = 210,",
" group = 17,",
" period = 6,",
" state = 3,",
" eleconfig = \"\",",
" },",
" [86] = {",
" name = \"radon\",",
" symbol = \"Rn\",",
" mass = 222,",
" group = 18,",
" period = 6,",
" state = 1,",
" eleconfig = \"\",",
" },",
" [87] = {",
" name = \"francium\",",
" symbol = \"Fr\",",
" mass = 223,",
" group = 1,",
" period = 7,",
" state = 3,",
" eleconfig = \"\",",
" },",
" [88] = {",
" name = \"radium\",",
" symbol = \"Ra\",",
" mass = 226,",
" group = 2,",
" period = 7,",
" state = 3,",
" eleconfig = \"\",",
" },",
" [89] = {",
" name = \"actinium\",",
" symbol = \"Ac\",",
" mass = 227,",
" group = 4,",
" period = 10,",
" state = 3,",
" eleconfig = \"\",",
" },",
" [90] = {",
" name = \"thorium\",",
" symbol = \"Th\",",
" mass = 232.0377,",
" group = 5,",
" period = 10,",
" state = 3,",
" eleconfig = \"\",",
" },",
" [91] = {",
" name = \"protactinium\",",
" symbol = \"Pa\",",
" mass = 231.03588,",
" group = 6,",
" period = 10,",
" state = 3,",
" eleconfig = \"\",",
" },",
" [92] = {",
" name = \"uranium\",",
" symbol = \"U\",",
" mass = 238.02891,",
" group = 7,",
" period = 10,",
" state = 3,",
" eleconfig = \"\",",
" },",
" [93] = {",
" name = \"neptunium\",",
" symbol = \"Np\",",
" mass = 237,",
" group = 8,",
" period = 10,",
" state = 3,",
" eleconfig = \"\",",
" },",
" [94] = {",
" name = \"plutonium\",",
" symbol = \"Pu\",",
" mass = 244,",
" group = 9,",
" period = 10,",
" state = 3,",
" eleconfig = \"\",",
" },",
" [95] = {",
" name = \"americium\",",
" symbol = \"Am\",",
" mass = 243,",
" group = 10,",
" period = 10,",
" state = 3,",
" eleconfig = \"\",",
" },",
" [96] = {",
" name = \"curium\",",
" symbol = \"Cm\",",
" mass = 247,",
" group = 11,",
" period = 10,",
" state = 3,",
" eleconfig = \"\",",
" },",
" [97] = {",
" name = \"berkelium\",",
" symbol = \"Bk\",",
" mass = 247,",
" group = 12,",
" period = 10,",
" state = 3,",
" eleconfig = \"\",",
" },",
" [98] = {",
" name = \"californium\",",
" symbol = \"Cf\",",
" mass = 251,",
" group = 13,",
" period = 10,",
" state = 3,",
" eleconfig = \"\",",
" },",
" [99] = {",
" name = \"einsteinium\",",
" symbol = \"Es\",",
" mass = 252,",
" group = 14,",
" period = 10,",
" state = 3,",
" eleconfig = \"\",",
" },",
" [100] = {",
" name = \"fermium\",",
" symbol = \"Fm\",",
" mass = 257,",
" group = 15,",
" period = 10,",
" state = 3,",
" eleconfig = \"\",",
" },",
" [101] = {",
" name = \"mendelevium\",",
" symbol = \"Md\",",
" mass = 258,",
" group = 16,",
" period = 10,",
" state = 3,",
" eleconfig = \"\",",
" },",
" [102] = {",
" name = \"nobelium\",",
" symbol = \"No\",",
" mass = 259,",
" group = 17,",
" period = 10,",
" state = 3,",
" eleconfig = \"\",",
" },",
" [103] = {",
" name = \"lawrencium\",",
" symbol = \"Lr\",",
" mass = 262,",
" group = 18,",
" period = 10,",
" state = 3,",
" eleconfig = \"\",",
" },",
" [104] = {",
" name = \"rutherfordium\",",
" symbol = \"Rf\",",
" mass = 267,",
" group = 4,",
" period = 7,",
" state = 0,",
" eleconfig = \"\",",
" },",
" [105] = {",
" name = \"dubnium\",",
" symbol = \"Db\",",
" mass = 268,",
" group = 5,",
" period = 7,",
" state = 0,",
" eleconfig = \"\",",
" },",
" [106] = {",
" name = \"seaborgium\",",
" symbol = \"Sg\",",
" mass = 271,",
" group = 6,",
" period = 7,",
" state = 0,",
" eleconfig = \"\",",
" },",
" [107] = {",
" name = \"bohrium\",",
" symbol = \"Bh\",",
" mass = 272,",
" group = 7,",
" period = 7,",
" state = 0,",
" eleconfig = \"\",",
" },",
" [108] = {",
" name = \"hassium\",",
" symbol = \"Hs\",",
" mass = 270,",
" group = 8,",
" period = 7,",
" state = 0,",
" eleconfig = \"\",",
" },",
" [109] = {",
" name = \"meitnerium\",",
" symbol = \"Mt\",",
" mass = 276,",
" group = 9,",
" period = 7,",
" state = 0,",
" eleconfig = \"\",",
" },",
" [110] = {",
" name = \"darmstadtium\",",
" symbol = \"Ds\",",
" mass = 281,",
" group = 10,",
" period = 7,",
" state = 0,",
" eleconfig = \"\",",
" },",
" [111] = {",
" name = \"roentgenium\",",
" symbol = \"Rg\",",
" mass = 280,",
" group = 11,",
" period = 7,",
" state = 0,",
" eleconfig = \"\",",
" },",
" [112] = {",
" name = \"copernicium\",",
" symbol = \"Cn\",",
" mass = 285,",
" group = 12,",
" period = 7,",
" state = 0,",
" eleconfig = \"\",",
" },",
" [113] = {",
" name = \"nihonium\",",
" symbol = \"Nh\",",
" mass = 284,",
" group = 13,",
" period = 7,",
" state = 0,",
" eleconfig = \"\",",
" },",
" [114] = {",
" name = \"flerovium\",",
" symbol = \"Fl\",",
" mass = 289,",
" group = 14,",
" period = 7,",
" state = 0,",
" eleconfig = \"\",",
" },",
" [115] = {",
" name = \"moscovium\",",
" symbol = \"Mc\",",
" mass = 288,",
" group = 15,",
" period = 7,",
" state = 0,",
" eleconfig = \"\",",
" },",
" [116] = {",
" name = \"livermorium\",",
" symbol = \"Lv\",",
" mass = 293,",
" group = 16,",
" period = 7,",
" state = 0,",
" eleconfig = \"\",",
" },",
" [117] = {",
" name = \"tennessine\",",
" symbol = \"Ts\",",
" mass = 294,",
" group = 17,",
" period = 7,",
" state = 0,",
" eleconfig = \"\",",
" },",
" [118] = {",
" name = \"oganesson\",",
" symbol = \"Og\",",
" mass = 294,",
" group = 18,",
" period = 7,",
" state = 0,",
" eleconfig = \"\",",
" },",
"}",
"for a = 1, #elements do",
" elements[a].number = a",
"end",
"",
"local drawing = {} -- renders colors below elements",
"-- F-block",
"for y = 12, 21 do",
" table.insert(drawing,{x=12,['y']=y,char=\" \",col=colors.lightBlue})",
"end",
"for y = 17, 21 do",
" table.insert(drawing,{x=12,['y']=y,char=(\" \"):rep(64),col=colors.lightBlue})",
"end",
"-- state labels",
"table.insert(drawing,{x=13,y=2,char=\"Solid \",col=colors.brown,txt=colors.white})",
"table.insert(drawing,{x=13,y=3,char=\"Liquid \",col=colors.blue,txt=colors.white})",
"table.insert(drawing,{x=13,y=4,char=\"Gas \",col=colors.yellow,txt=colors.black})",
"table.insert(drawing,{x=13,y=5,char=\"Unknown\",col=colors.black,txt=colors.white})",
"table.insert(drawing,{x=21,y=3,char=\"<-- State at 64 F\",col=colors.lightGray})",
"-- instructions",
"table.insert(drawing,{x=21,y=5,char=\"Arrow keys to scroll\",col=colors.lightGray})",
"table.insert(drawing,{x=21,y=6,char=\"Press [Q] to quit\",col=colors.lightGray})",
"",
"",
"local renderElements = function(ele,xscroll,yscroll)",
" term.current().setVisible(false)",
" term.setBackgroundColor(colors.lightGray)",
" term.clear()",
" term.setTextColor(colors.white)",
" for a = 1, #drawing do",
" term.setCursorPos((drawing[a].x)-xscroll,(drawing[a].y)-yscroll)",
" term.setBackgroundColor(drawing[a].col)",
" if drawing[a].txt then",
" term.setTextColor(drawing[a].txt)",
" else",
" term.setTextColor(colors.black)",
" end",
" term.write(drawing[a].char)",
" end",
" for a = 1, #ele do",
" if ele[a].state == 1 then",
" term.setBackgroundColor(colors.yellow)",
" term.setTextColor(colors.black)",
" elseif ele[a].state == 2 then",
" term.setBackgroundColor(colors.blue)",
" term.setTextColor(colors.white)",
" elseif ele[a].state == 3 then",
" term.setBackgroundColor(colors.brown)",
" term.setTextColor(colors.white)",
" else",
" term.setBackgroundColor(colors.black)",
" term.setTextColor(colors.white)",
" end",
" term.setCursorPos((ele[a].group*4)-xscroll,(ele[a].period*2)-yscroll)",
" term.write((ele[a].symbol..\" \"):sub(1,3))",
" end",
" term.current().setVisible(true)",
"end",
"",
"local cleanExit = function()",
" term.setBackgroundColor(colors.black)",
" term.setTextColor(colors.white)",
" term.clear()",
" term.setCursorPos(1,1)",
" print(\"Bye!\")",
" sleep(0)",
" return",
"end",
"",
"local xscr = 0",
"local yscr = 0",
"local keysDown = {}",
"local viewingElement = false",
"",
"local cprint = function(txt,_y)",
" local x,y = term.getSize()",
" local cx,cy = term.getCursorPos()",
" term.setCursorPos((x/2)-math.ceil(#txt/2),_y or cy)",
" return print(txt)",
"end",
"",
"local viewElement = function(ele)",
" term.setBackgroundColor(colors.white)",
" term.clear()",
" term.setBackgroundColor(colors.lightBlue)",
" term.setTextColor(colors.black)",
" term.setCursorPos(1,2)",
" term.clearLine()",
" cprint(ele.name:upper())",
" term.setBackgroundColor(colors.white)",
" print(\"Symbol: \"..ele.symbol)",
" print(\"Atomic #: \"..ele.number)",
" print(\"Atomic mass: \"..ele.mass)",
" print(\"Neutron #: \"..math.floor(ele.mass)-ele.number)",
" write(\"\\nState of matter: \")",
" if ele.state == 1 then",
" print(\"Gas\")",
" elseif ele.state == 2 then",
" print(\"Liquid\")",
" elseif ele.state == 3 then",
" print(\"Solid\")",
" else",
" print(\"Unknown\")",
" end",
" print(\"\\nPeriod \"..((ele.period <= 7 and ele.period) or (ele.period-3)))",
" print(\"Group \"..((ele.period <= 7 and ele.group) or \"F-block\")..\"\\n\")",
" if elements[ele.number-1] then",
" print(\"Prev: \"..elements[ele.number-1].name)",
" end",
" if elements[ele.number+1] then",
" print(\"Next: \"..elements[ele.number+1].name)",
" end",
" sleep(0)",
" local evt,butt",
" while true do",
" evt,butt = os.pullEvent()",
" if evt == \"key\" then",
" if butt == keys.left or butt == keys.right then",
" return butt",
" else",
" return",
" end",
" elseif evt == \"mouse_click\" then",
" if butt == 1 then",
" return",
" end",
" end",
" end",
"end",
"",
"local getKeys = function()",
" while true do",
" local evt,key = os.pullEvent()",
" if evt == \"key\" then",
" keysDown[key] = true",
" elseif evt == \"key_up\" then",
" keysDown[key] = false",
" end",
" end",
"end",
"",
"local getKeyScrolling = function()",
" while true do",
" sleep(0.05)",
" if not viewingElement then",
" if keysDown[keys.left] then",
" if xscr > 0 then",
" xscr = xscr - 1",
" end",
" elseif keysDown[keys.right] then",
" if xscr < 76-scr_x then",
" xscr = xscr + 1",
" end",
" end",
" if keysDown[keys.down] then",
" if yscr < 4 then",
" yscr = yscr + 1",
" end",
" elseif keysDown[keys.up] then",
" if yscr > 0 then",
" yscr = yscr - 1",
" end",
" end",
" if keysDown[keys.q] then",
" return cleanExit()",
" end",
" renderElements(elements,xscr,yscr)",
" end",
" end",
"end",
"",
"local getMouseInput = function()",
" while true do",
" local evt,butt,x,y = os.pullEvent(\"mouse_click\")",
" local _x,_y = x+xscr,y+yscr",
" for a = 1, #elements do",
" local e = elements[a]",
" if (_x >= (e.group*4) and _x <= (e.group*4)+2) and (_y == e.period*2) then",
" viewingElement = true",
" local b = a",
" while true do",
" e = elements[b]",
" local eeh = viewElement(e)",
" if eeh == keys.left and elements[b-1] then",
" b = b - 1",
" elseif eeh == keys.right and elements[b+1] then",
" b = b + 1",
" else",
" break",
" end",
" end",
" viewingElement = false",
" break",
" end",
" end",
" end",
"end",
"",
"local doFunks = {",
" getMouseInput,",
" getKeyScrolling,",
" getKeys,",
"}",
"",
"parallel.waitForAny(unpack(doFunks))",
},
[ "/game/data/sprites/megaman/buster2-2.nft" ] = {
"",
"4fŸ0‡0€4‚f”",
"4‚0‹4Ÿ0€4Ÿf4…",
},
[ "/util/http/stdgui.lua" ] = {
"--[[",
" STD Graphical User Interface! (STD-GUI)!",
" Made by LDDestroier/EldidiStroyrr (same guy)",
"",
" This program is a standalone GUI for Super Text Downloader, or STD for short.",
" It has category sorting, program searching, smooth scrolling, and run support (not just download)",
" This will tell you if you're overwriting a file, so no worry.",
"",
" As of May 15th (my GOSH DARN birthday) 2016, STD-GUI now lets you install SimSoft applications in the store interface!",
" As of Jan 11th 2018, STD-GUI now lets you install Axiom OS applications too!",
"",
" pastebin get P9dDhQ2m stdgui",
" std PB P9dDhQ2m stdgui",
" std ld stdgui stdgui",
"",
" This is a stable release. You fool!",
"--]]",
"",
"local tsv = term.current().setVisible --comment out if you are debugging",
"",
"local isBeta = false --changes the update URL",
"",
"if not http then --why, you...",
" return false, printError(\"HTTP must be enabled to use STD. Contact an administrator for assistance.\")",
"else",
" if not http.checkURL(\"http://pastebin.com\") then",
" return false, printError(\"For some reason, Pastebin.com is whitelisted. Abort.\")",
" end",
"end",
"local scr_x, scr_y = term.getSize()",
"",
"local doDisplayTitle = false",
"local relativePath = false",
"local doColorize = true",
"",
"if type(std) ~= \"table\" then std = {} end",
"",
"local overrideNoOS = false --prevent SimSoft functions, even if it's installed",
"local isSimSoft = false --special integration into SimSoft!",
"local isAxiom = false --special integration into Axiom!",
"std.channel = \"STD\"",
"std.prevChannel = std.channel",
"",
"std.channelURLs = { --special pastebin URLs for getting a list of files.",
" [\"STD\"] = \"https://raw.githubusercontent.com/LDDestroier/STD-GUI/master/list.lua\", --default store list on github, more updated",
" [\"STD PB\"] = \"http://pastebin.com/raw/zVws7eLq\", --default store list on pastebin",
" [\"Discover\"] = \"http://pastebin.com/raw/9bXfCz6M\", --owned by dannysmc95",
"-- [\"OnlineAPPS\"] = \"http://pastebin.com/raw/g2EnDYLp\", --owned by Twijn, but discontinued.",
" [\"STD-Media\"] = \"https://pastebin.com/raw/3JZHXTGL\", --list of pictures and music",
"}",
"local palate",
"palate = {",
" pleasewait = {",
" txt = colors.lightGray,",
" bg = colors.black,",
" },",
" store = {",
" bg = colors.black,",
" txt = colors.white,",
" bgchar = \" \",",
" entrybg = colors.gray,",
" entrytxt = colors.white,",
" entryasterisk = colors.lightGray,",
" closetxt = colors.white,",
" closebg = colors.red,",
" previewtxt = colors.white,",
" previewbg = colors.cyan,",
" findbg = colors.white,",
" findtxt = colors.black,",
" indicatetxt = colors.black,",
" indicatebg = colors.white,",
" theendtxt = colors.gray,",
" scrollbar = {",
" knobbg = colors.black,",
" knobtxt = colors.gray,",
" knobchar = \"|\",",
" barbg = colors.lightGray,",
" bartxt = colors.gray,",
" barchar = \"|\",",
" }",
" },",
" item = {",
" bg = colors.gray,",
" txt = colors.white,",
" specialtxt = colors.yellow,",
" previewtxt = colors.white,",
" previewbg = colors.black,",
" forumtxt = colors.lightGray,",
" forumbg = colors.gray,",
" closetxt = colors.white,",
" closebg = colors.red,",
" runtxt = colors.white,",
" runbg = colors.green,",
" downloadtxt = colors.white,",
" downloadbg = colors.green,",
" },",
" menubar = {",
" bg = colors.black,",
" categorytxt = colors.lightGray,",
" categorybg = colors.black,",
" channeltxt = colors.lightGray,",
" channelbg = colors.black,",
" hotkeytxt = colors.gray,",
" categorymenu = {",
" selecttxt = colors.lightGray,",
" selectbg = colors.black,",
" bg = colors.black,",
" txt = colors.lightGray,",
" orbtxt = colors.black,",
" cursortxt = colors.black,",
" cursorbg = colors.lightGray,",
" borderbg = colors.black,",
" },",
" channelmenu = {",
" selecttxt = colors.lightGray,",
" selectbg = colors.black,",
" bg = colors.lightGray,",
" txt = colors.lightGray,",
" orbtxt = colors.black,",
" cursortxt = colors.black,",
" cursorbg = colors.lightGray,",
" borderbg = colors.black,",
" }",
" }",
"}",
"",
"local getEvents = function(...)",
" local arg, output = table.pack(...)",
" while true do",
" output = {os.pullEvent()}",
" for a = 1, #arg do",
" if type(arg[a]) == \"boolean\" then",
" if doRender == arg[a] then",
" return {}",
" end",
" elseif output[1] == arg[a] then",
" return unpack(output)",
" end",
" end",
" end",
"end",
"",
"local charClear = function(char)",
" local cx,cy = term.getCursorPos()",
" for y = 1, scr_y do",
" term.setCursorPos(1,y)",
" term.write(char:sub(1,1):rep(scr_x))",
" end",
" term.setCursorPos(cx,cy)",
"end",
"",
"std.channelNames = {}",
"for k,v in pairs(std.channelURLs) do",
" table.insert(std.channelNames,k)",
"end",
"",
"std.stdList = \".\"..std.channel:lower()..\"_list\"",
"",
"if (fs.isDir(\"SimSoft/Data\") and fs.isDir(\"SimSoft/SappS\")) and (not overrideNoOS) then --checks if SimSoft is installed",
" isSimSoft = true",
"elseif (fs.isDir(\"Axiom\") and fs.exists(\"Axiom/sys.axs\")) and (not overrideNoOS) then --checks if Axiom is installed",
" isAxiom = true",
"end",
"",
"local cprint = function(txt,y)",
" local cX,cY = term.getCursorPos()",
" term.setCursorPos(math.ceil(scr_x/2)-math.floor(#txt/2),y or cY)",
" term.write(txt)",
"end",
"",
"local scroll = 1 --one is the loneliest number...weaboo",
"local scrollX = 1 --to view longer program names",
"local maxScroll",
"std.std_version = 101 --to prevent updating to std command line",
"",
"local setMaxScroll = function(catagory)",
" local output = 0",
" for k,v in pairs(std.storeURLs) do",
" if (v.catagory == catagory) or catagory == 0 then",
" output = output + 1",
" end",
" end",
" return (output*4)-(scr_y-4)",
"end",
"local catag = 0",
"",
"local pleaseWait = function(text)",
" term.setBackgroundColor(palate.pleasewait.bg)",
" term.setTextColor(palate.pleasewait.txt)",
" term.clear()",
" cprint(text or \"Getting list...please wait\",scr_y/2)",
"end",
"",
"local coolPleaseWait = function()",
" local scr_x, scr_y = term.getSize()",
" local cols = \"f7\"",
" local length = scr_x/2",
" local render = function(col1,col2,prog,forwards)",
" term.setCursorPos(1,1)",
" local screen = (col1:rep(prog)..col2:rep(length-prog)):rep(scr_x*scr_y):sub(1,(scr_x*scr_y))",
" local line",
" for a = forwards and 1 or scr_y, forwards and scr_y or 1, forwards and 1 or -1 do",
" line = screen:sub((a-1)*scr_x+1,a*scr_x)",
" term.setCursorPos(1,a)",
" term.blit((\"L\"):rep(#line),line,line)",
" end",
" end",
" local pos1 = 2",
" local pos2 = pos1 - 1",
" local forwards = true",
" local reverse = false",
" while true do",
" for a = reverse and length or 1, reverse and 1 or length, reverse and -1 or 1 do",
" render(cols:sub(pos1,pos1),cols:sub(pos2,pos2),a,forwards)",
" sleep(0.0)",
" end",
" forwards = not forwards",
" reverse = not reverse",
" pos1 = (pos1 + 1)",
" pos2 = (pos2 + 1)",
" if pos1 > #cols then pos1 = 1 end",
" if pos2 > #cols then pos2 = 1 end",
" end",
"end",
"",
"local setDefaultColors = function()",
" term.setBackgroundColor(palate.store.bg)",
" term.setTextColor(palate.store.txt)",
"end",
"",
"local displayHelp = function(cli)",
" local helptext = [[",
"This is a graphical interface to the STD downloader program.",
"Use 'stdgui update' to update the list, or use 'F5'.",
"If you want your program on it, PM LDDestroier on the CC forums.",
"Hotkeys:",
" 'Q' quit or back",
" 'F5' refresh",
" 'F1' set category",
" 'F3' set channel",
" 'F' or 'F6' search",
" 'F12' update STDGUI",
" if normal computer, press 0-9 to select store item",
"]]",
" if cli then",
" return print(helptext)",
" else",
" setDefaultColors()",
" term.clear()",
" term.setCursorPos(2,2)",
" print(helptext)",
" sleep(0)",
" print(\"\\nPress a key to go back.\")",
" os.pullEvent(\"key\")",
" return",
" end",
"end",
"",
"local getTableSize = function(tbl)",
" local amnt = 0",
" for k,v in pairs(tbl) do",
" amnt = amnt + 1",
" end",
" return amnt",
"end",
"",
"local colors_names = {",
" [\"0\"] = colors.white,",
" [\"1\"] = colors.orange,",
" [\"2\"] = colors.magenta,",
" [\"3\"] = colors.lightBlue,",
" [\"4\"] = colors.yellow,",
" [\"5\"] = colors.lime,",
" [\"6\"] = colors.pink,",
" [\"7\"] = colors.gray,",
" [\"8\"] = colors.lightGray,",
" [\"9\"] = colors.cyan,",
" [\"a\"] = colors.purple,",
" [\"b\"] = colors.blue,",
" [\"c\"] = colors.brown,",
" [\"d\"] = colors.green,",
" [\"e\"] = colors.red,",
" [\"f\"] = colors.black,",
"}",
"",
"local blit_names = {}",
"for k,v in pairs(colors_names) do",
" blit_names[v] = k",
"end",
"",
"local codeNames = { --just for checking, not for any translation",
" [\"r\"] = \"reset\",",
" [\"{\"] = \"stopFormatting\",",
" [\"}\"] = \"startFormatting\",",
"}",
"",
"local explode = function(div,str)",
" if (div=='') then return false end",
" local pos,arr = 0,{}",
" for st,sp in function() return string.find(str,div,pos,true) end do",
" table.insert(arr,string.sub(str,pos,st-1))",
" pos = sp + 1",
" end",
" table.insert(arr,string.sub(str,pos))",
" return arr",
"end",
"",
"local blitWrap = function(text,txt,bg)",
" local allIssues = \"\"",
" if not text then allIssues = allIssues..\"no text, \" end",
" if not txt then allIssues = allIssues..\"no txt, \" end",
" if not bg then allIssues = allIssues..\"no bg, \" end",
" if not (#text == #txt and #txt == #bg) then allIssues = allIssues..\"incongruent lengths\" end",
" if #allIssues > 0 then error(allIssues) end",
" local wordNo = 1",
" local words = explode(\" \",text)",
" local lines = 0",
" local scr_x, scr_y = term.getSize()",
" local cx,cy",
" for a = 1, #text do",
" cx,cy = term.getCursorPos()",
" if text:sub(a,a) == \" \" and text:sub(a-1,a-1) ~= \" \" and a > 1 then",
" wordNo = wordNo + 1",
" if cx + #words[wordNo] > scr_x then",
" term.setCursorPos(1,cy+1)",
" lines = lines + 1",
" end",
" end",
" cx,cy = term.getCursorPos()",
" if text:sub(a,a) == \"\\n\" then",
" term.setCursorPos(1,cy+1)",
" lines = lines + 1",
" elseif not (cx == 1 and text:sub(a,a) == \" \") then",
" term.blit(text:sub(a,a),txt:sub(a,a),bg:sub(a,a))",
" end",
" if cx == scr_x then",
" term.setCursorPos(1,cy+1)",
" lines = lines + 1",
" end",
" end",
" return lines",
"end",
"",
"local moveOn, textToBlit",
"textToBlit = function(str,substart,substop)",
" local p = 1",
" local output = \"\"",
" local txcolorout = \"\"",
" local bgcolorout = \"\"",
" local txcode = \"&\"",
" local bgcode = \"~\"",
" local doFormatting = true",
" local usedformats = {}",
" local txcol,bgcol = blit_names[term.getTextColor()], blit_names[term.getBackgroundColor()]",
" local origTX,origBG = blit_names[term.getTextColor()], blit_names[term.getBackgroundColor()]",
" local cx,cy,barestr",
" substart = substart or 0",
" substop = substop or #str",
" if not (substart == 0 and substop == #str) then",
" barestr = textToBlit(str)",
" else",
" if substart < 0 then",
" substart = #realstr - substart",
" end",
" if substop < 0 then",
" substop = #realstr - substop",
" end",
" end",
" moveOn = function(tx,bg)",
" if p >= substart and p <= substop then",
" output = output..str:sub(p,p)",
" txcolorout = txcolorout..tx",
" bgcolorout = bgcolorout..bg",
" end",
" end",
" while p <= #str do",
" if str:sub(p,p) == txcode then",
" if colors_names[str:sub(p+1,p+1)] and doFormatting then",
" txcol = str:sub(p+1,p+1)",
" usedformats.txcol = true",
" p = p + 1",
" elseif codeNames[str:sub(p+1,p+1)] then",
" if str:sub(p+1,p+1) == \"r\" and doFormatting then",
" txcol = blit_names[term.getTextColor()]",
" p = p + 1",
" elseif str:sub(p+1,p+1) == \"{\" and doFormatting then",
" doFormatting = false",
" p = p + 1",
" elseif str:sub(p+1,p+1) == \"}\" and (not doFormatting) then",
" doFormatting = true",
" p = p + 1",
" else",
" moveOn(txcol,bgcol)",
" end",
" else",
" moveOn(txcol,bgcol)",
" end",
" p = p + 1",
" elseif str:sub(p,p) == bgcode then",
" if colors_names[str:sub(p+1,p+1)] and doFormatting then",
" bgcol = str:sub(p+1,p+1)",
" usedformats.bgcol = true",
" p = p + 1",
" elseif codeNames[str:sub(p+1,p+1)] and (str:sub(p+1,p+1) == \"r\") and doFormatting then",
" bgcol = blit_names[term.getBackgroundColor()]",
" p = p + 1",
" else",
" moveOn(txcol,bgcol)",
" end",
" p = p + 1",
" else",
" moveOn(txcol,bgcol)",
" p = p + 1",
" end",
" end",
" return output, txcolorout, bgcolorout, usedformats",
"end",
"",
"local writef = function(txt,noWrite,substart,substop)",
" if doColorize then",
" local text, textCol, bgCol, usedformats = textToBlit(txt,substart,substop)",
" local out = blitWrap(text,textCol,bgCol,noWrite)",
" return out, #text, usedformats",
" else",
" if noWrite then",
" local cx,cy = term.getCursorPos()",
" return math.floor((cx+#cf(txt))/scr_x), #cf(txt), {} --this is approximate, and might mess up with multiline strings",
" else",
" return write(txt), #txt, {}",
" end",
" end",
"end",
"",
"local printf = function(txt,noWrite)",
" return writef(tostring(txt..\"\\n\"),noWrite)",
"end",
"",
"local runURL = function(url, ...)",
" local program = http.get(url)",
" if not program then return false end",
" program = program.readAll()",
" local func = load(program)",
" setfenv(func, getfenv())",
" return func(...)",
"end",
"",
"local bow = function()",
" term.setBackgroundColor(palate.store.findbg)",
" term.setTextColor(palate.store.findtxt)",
"end",
"",
"local strless = function(str,txt,bg)",
" local x,y = 0,0",
" local shiftDown = false",
" local str = explode(\"\\n\",str or \"\")",
" local render = function()",
" term.setBackgroundColor(bg)",
" term.setTextColor(txt)",
" for i = y+1, (scr_y+y)-1 do",
" term.setCursorPos(math.max(1,-x),i-y)",
" term.clearLine()",
" if str[i] then",
" term.write(str[i]:sub(math.max(1,x+1)))",
" end",
" end",
" term.setCursorPos(1,scr_y)",
" term.setBackgroundColor(colors.gray)",
" term.setTextColor(colors.white)",
" term.clearLine()",
" term.write(\"(Q)uit, Goto (L)ine\")",
" local ting = \"Ln.\"..math.min(math.max(y+1,0),#str)",
" term.setCursorPos((scr_x-#ting)+1,scr_y)",
" term.write(ting)",
" end",
" render()",
" maxY = (#str-scr_y)+1",
" while true do",
" local evt, key, mx, my = os.pullEvent()",
" local oldY = y",
" local oldX = x",
" if evt == \"key\" then",
" if key == keys.leftShift then",
" shiftDown = true",
" elseif key == keys.up then",
" y = y-1",
" elseif key == keys.down then",
" y = y+1",
" elseif key == keys.pageUp then",
" y = y-(scr_y-1)",
" elseif key == keys.pageDown then",
" y = y+(scr_y-1)",
" elseif key == keys.left then",
" x = x-1",
" elseif key == keys.right then",
" x = x+1",
" elseif key == keys.home then",
" y = 0",
" elseif key == keys[\"end\"] then",
" y = maxY",
" elseif (key == keys.q) or (key == keys.x) then",
" sleep(0)",
" break",
" elseif (key == keys.l) then",
" term.setCursorPos(1,scr_y)",
" term.setBackgroundColor(colors.gray)",
" term.setTextColor(colors.white)",
" term.clearLine()",
" term.write(\"Line #:\")",
" sleep(0)",
" y = (tonumber(read()) or (y+1)) - 1",
" end",
" elseif evt == \"key_up\" then",
" if key == keys.leftShift then",
" shiftDown = false",
" end",
" elseif evt == \"mouse_scroll\" then",
" if shiftDown then",
" x = x + key",
" else",
" y = y + key",
" end",
" elseif evt == \"mouse_click\" and key == 1 then",
" if my == scr_y and (mx >= 1 and mx <= 11) then",
" sleep(0)",
" break",
" end",
" end",
" if x < 0 then x = 0 end",
" if y < 0 then y = 0 end",
" if y > maxY then y = maxY end",
" if (x ~= oldX) or (y ~= oldY) or (key == keys.l) then",
" render()",
" end",
" end",
"end",
"local contentsFile = function(url)",
" local prog = http.get(url)",
" if prog then return prog.readAll()",
" else return false, \"could not connect\" end",
"end",
"local getFile = function(filename,url)",
" if fs.isReadOnly(filename) then",
" return false, \"access denied\"",
" end",
" local prog",
" if type(url) == \"table\" then",
" prog = std.contextualGet(url[1])",
" else",
" prog = http.get(url)",
" end",
" if not prog then",
" return false, \"could not connect\"",
" end",
" prog = prog.readAll()",
" local fyle = fs.open(filename,\"w\")",
" fyle.write(prog)",
" fyle.close()",
" return true, fs.getSize(filename)",
"end",
"local runFile = function(path, ...)",
" if not fs.exists(path) then",
" return false, \"No such file!\"",
" end",
" local file = fs.open(path,\"r\")",
" local contents = file.readAll()",
" file.close()",
" local func = load(contents, nil, nil, _ENV)",
" return func(...)",
"end",
"std.getSTDList = function(prevChannel)",
" catag = 0",
" local url = std.channelURLs[std.channel] --URL of URL list for whatever channel you have selected.",
" pleaseWait()",
" local outcome, size = getFile(std.stdList, std.channelURLs[std.channel])",
" if not outcome then",
" if shell then",
" print(\"Couldn't update list!\")",
" end",
" return false, \"Couldn't update list!\"",
" else",
" local outcome = runFile(std.stdList)",
" if outcome == false then",
" term.setBackgroundColor(colors.black)",
" term.setTextColor(term.isColor() and colors.red or colors.lightGray)",
" term.clear()",
" cprint(\"STD channel \\\"\"..std.channel..\"\\\" is down right now.\",2)",
" term.setTextColor(colors.white)",
" cprint(\"Either try again later,\",4)",
" cprint(\"contact LDDestroier on the CC forums,\",5)",
" cprint(\"or tell the owner of the channel.\",6)",
" cprint(\"Press a key to go back.\",8)",
" term.setTextColor(colors.gray)",
" cprint(\"Sorry bout that!\",scr_y)",
" std.channel = prevChannel",
" sleep(0.1)",
" os.pullEvent(\"char\")",
" pleaseWait(\"Changing list...please wait...\")",
" return std.getSTDList(\"STD\")",
" end",
" local output",
" if not fs.isReadOnly(std.stdList) then",
" output = \"Downloaded to \"..std.stdList",
" else",
" output = \"Got store codes.\"",
" end",
" maxScroll = setMaxScroll(catag)",
" return true, output",
" end",
"end",
"",
"local cisf = function(str,fin)",
" fin = fin:gsub(\"%[\",\"%%[\"):gsub(\"%(\",\"%%(\"):gsub(\"%]\",\"%%]\"):gsub(\"%)\",\"%%)\")",
" return string.find(str:lower(),fin:lower())",
"end",
"",
"local clearMostline = function(length,char)",
" local pX,pY = term.getCursorPos()",
" term.setCursorPos(1,pY)",
" term.write(string.rep(char or \" \",length or (scr_x-1)))",
" term.setCursorPos(pX,pY)",
"end",
"",
"local dotY",
"local doScrollBar = false",
"",
"local renderStore = function(list,filter,scrollY,namescroll,fixedDotY,buttonIndicate)",
" local fullrend = {}",
" local visiblerend = {}",
" local amnt = 0",
" local output = {}",
" local colors_output = {}",
" local num = 0",
" if tsv then tsv(false) end",
" for k,v in pairs(list) do",
" if (v.catagory == filter) or filter == 0 then",
" table.insert(fullrend,{\" &\"..blit_names[palate.store.entryasterisk]..\"*&\"..blit_names[palate.store.entrytxt]..v.title,v})",
" table.insert(fullrend,{\" by &r\"..v.creator,v})",
" table.insert(fullrend,{\" Category: \"..std.storeCatagoryNames[v.catagory],v,v.catagory})",
" table.insert(fullrend,\"nilline\")",
" end",
" end",
" table.insert(fullrend,\"\")",
" dotY = fixedDotY or math.floor((scr_y-2)*((scroll-1)/(maxScroll-1)))+2",
" for a = scrollY, (scr_y+scrollY)-1 do",
" if type(fullrend[a]) == \"table\" then",
" table.insert(visiblerend,fullrend[a][1])",
" table.insert(output,fullrend[a][2])",
" if fullrend[a][3] then",
" table.insert(colors_output,fullrend[a][3])",
" else",
" table.insert(colors_output,false)",
" end",
" else",
" table.insert(visiblerend,fullrend[a])",
" table.insert(output,{})",
" table.insert(colors_output,false)",
" end",
" end",
" setDefaultColors()",
" charClear(palate.store.bgchar)",
" for a = 1, #visiblerend do",
" term.setCursorPos(2-namescroll,a+1)",
" if visiblerend[a] == \"nilline\" then",
" setDefaultColors()",
" clearMostline()",
" else",
" if a < #visiblerend then",
" if term.isColor() then",
" if colors_output[a] then",
" term.setBackgroundColor(std.storeCatagoryColors[colors_output[a]].bg)",
" term.setTextColor(std.storeCatagoryColors[colors_output[a]].txt)",
" else",
" term.setBackgroundColor(palate.store.entrybg)",
" term.setTextColor(palate.store.entrytxt)",
" end",
" else",
" term.setBackgroundColor(colors.gray)",
" term.setTextColor(colors.white)",
" end",
" clearMostline()",
" writef(visiblerend[a])",
" else",
" term.setBackgroundColor(palate.store.bg)",
" term.setTextColor(palate.store.theendtxt)",
" cprint(\"That's them all!\")",
" end",
" end",
" end",
" local b",
" for a = 2, scr_y do",
" term.setCursorPos(scr_x,a)",
" if a == dotY then",
" term.setTextColor(palate.store.scrollbar.knobtxt)",
" term.setBackgroundColor(palate.store.scrollbar.knobbg)",
" term.write(palate.store.scrollbar.knobchar)",
" else",
" term.setTextColor(palate.store.scrollbar.bartxt)",
" term.setBackgroundColor(palate.store.scrollbar.barbg)",
" term.write(palate.store.scrollbar.barchar)",
" end",
" if buttonIndicate then",
" term.setCursorPos(scr_x-4,a)",
" term.setBackgroundColor(palate.store.indicatebg)",
" term.setTextColor(palate.store.indicatetxt)",
" b = (a+1)/4",
" if (b == math.floor(b)) and (visiblerend[a] and visiblerend[a] ~= \"nilline\") then",
" term.write(\" \"..tostring(b):sub(#tostring(b))..\" \")",
" end",
" end",
" end",
" if tsv then tsv(true) end",
" return output",
"end",
"",
"local simSoftInstall = function(obj,objname,appname)",
" local installSystemName = \"STD App Distribution (sad...)\"",
" appname = appname or objname",
" local getFromURL = function(url)",
" local cunt",
" if type(url) == \"table\" then",
" cunt = std.contextualGet(url[1])",
" else",
" cunt = http.get(url)",
" end",
" if not cunt then",
" return shit",
" else",
" if type(url) == \"table\" then",
" return cunt.readAll(), false",
" else",
" return cunt.readAll(), (string.find(url,\"://pastebin.com/raw/\") and (url:sub(-9):gsub(\"/\",\"\")) or false)",
" end",
" end",
" end",
" local mainpath = fs.combine(\"/SimSoft/SappS\",objname)",
" local cont,pbcode = getFromURL(obj.url)",
" local file = fs.open(\"\\\"\"..fs.combine(mainpath,pbcode or \"program\")..\"\\\"\",\"w\")",
" file.write(cont)",
" file.close()",
" local file = fs.open(fs.combine(mainpath,\"SappS\"),\"w\")",
" file.writeLine(installSystemName)",
" file.writeLine(\"\\\"\"..fs.combine(mainpath,pbcode or \"program\")..\"\\\"\")",
" file.writeLine(appname:sub(1,9))",
" file.close()",
" return true, \"Installed!\"",
"end",
"",
"local getFindList = function(name)",
" local output = {}",
" for k,v in pairs(std.storeURLs) do",
" if cisf(k,name) or cisf(textToBlit(v.title),name) or cisf(textToBlit(v.creator),name) then",
" output[k] = v",
" end",
" if output[k] ~= v and v.keywords then",
" for a = 1, #v.keywords do",
" if cisf(v.keywords[a],name) then",
" output[k] = v",
" break",
" end",
" end",
" end",
" end",
" return output",
"end",
"",
"local doFindFunc = function(name)",
" scroll = 1",
" maxScroll = setMaxScroll(catag)",
" renderStore(getFindList(name),catag,scroll,scrollX,_,not term.isColor())",
" term.setCursorPos(1,1)",
" bow()",
" term.clearLine()",
" write(\"Find: \")",
"end",
"",
"local funcread = function(repchar,rHistory,doFunc,noNewLine)",
" local scr_x,scr_y = term.getSize()",
" local sx,sy = term.getCursorPos()",
" local cursor = 1",
" rHistory = rHistory or {}",
" local rCursor = #rHistory+1",
" local output = \"\"",
" term.setCursorBlink(true)",
" while true do",
" local evt,key = os.pullEvent()",
" local cx,cy = term.getCursorPos()",
" if evt == \"key\" then",
" if key == keys.enter then",
" if not noNewLine then",
" write(\"\\n\")",
" end",
" term.setCursorBlink(false)",
" return output",
" elseif key == keys.left then",
" if cursor-1 >= 1 then",
" cursor = cursor - 1",
" end",
" elseif key == keys.right then",
" if cursor <= #output then",
" cursor = cursor + 1",
" end",
" elseif key == keys.up then",
" if rCursor > 1 then",
" rCursor = rCursor - 1",
" term.setCursorPos(sx,sy)",
" term.write((\" \"):rep(#output))",
" output = rHistory[rCursor] or \"\"",
" cursor = #output+1",
" pleaseDoFunc = true",
" end",
" elseif key == keys.down then",
" term.setCursorPos(sx,sy)",
" term.write((\" \"):rep(#output))",
" if rCursor < #rHistory then",
" rCursor = rCursor + 1",
" output = rHistory[rCursor] or \"\"",
" cursor = #output+1",
" pleaseDoFunc = true",
" else",
" rCursor = #rHistory+1",
" output = \"\"",
" cursor = 1",
" end",
" elseif key == keys.backspace then",
" if cursor > 1 and #output > 0 then",
" output = output:sub(1,cursor-2)..output:sub(cursor)",
" cursor = cursor - 1",
" pleaseDoFunc = true",
" end",
" elseif key == keys.delete then",
" if #output:sub(cursor,cursor) == 1 then",
" output = output:sub(1,cursor-1)..output:sub(cursor+1)",
" pleaseDoFunc = true",
" end",
" end",
" elseif evt == \"char\" or evt == \"paste\" then",
" output = output:sub(1,cursor-1)..key..output:sub(cursor+(#key-1))",
" cursor = cursor + #key",
" pleaseDoFunc = true",
" end",
" if pleaseDoFunc then",
" pleaseDoFunc = false",
" if type(doFunc) == \"function\" then",
" doFunc(output)",
" end",
" term.setCursorPos(sx,sy)",
" local pOut = output",
" if #output >= scr_x-(sx-2) then",
" pOut = output:sub((#output+(sx))-scr_x)",
" end",
" if repchar then",
" term.write(repchar:sub(1,1):rep(#pOut)..\" \")",
" else",
" term.write(pOut..\" \")",
" end",
" local cx,cy = term.getCursorPos()",
" end",
" term.setCursorPos(sx+cursor-1,cy)",
" end",
"end",
"",
"local prevList",
"local findPrompt = function()",
" local cX,cY = term.getCursorPos()",
" sleep(0)",
" if prevList then std.storeURLs = prevList end",
" doFindFunc(\"\")",
" prevList = std.storeURLs",
" std.storeURLs = getFindList(funcread(nil,{},doFindFunc,false))",
" term.setCursorBlink(false)",
" maxScroll = setMaxScroll(catag)",
"end",
"",
"local displayTitle = function()",
" local title = {{},{},{},{},{0,0,0,0,0,1,1,1,1,1,0,0,2,2,2,2,2,2,2,0,2,2,2,2,0,0,32768,},{0,0,0,0,1,1,0,0,0,1,1,0,0,0,0,2,0,0,0,0,0,2,0,2,2,0,32768,},{0,0,0,0,1,0,0,0,0,0,1,0,0,0,2,2,0,0,0,0,2,2,0,0,2,0,32768,},{0,0,0,0,1,1,0,0,0,0,0,0,0,0,2,0,0,0,0,0,2,0,0,0,2,0,32768,},{0,0,0,0,0,1,1,1,1,1,0,0,0,0,2,0,0,0,0,2,2,0,0,2,2,0,32768,},{0,0,0,0,0,0,0,0,0,1,0,0,0,2,2,0,0,0,2,2,0,0,2,2,0,0,32768,},{0,0,0,1,1,0,0,0,1,1,0,0,2,2,0,0,0,2,2,0,0,2,2,0,0,32768,1,},{0,0,0,0,1,1,1,1,1,0,0,0,2,0,0,0,2,2,2,2,2,2,0,0,32768,1,1,},{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,32768,1,1,1,},{0,0,0,32768,32768,32768,32768,32768,32768,32768,32768,32768,32768,32768,32768,32768,32768,32768,32768,32768,32768,32768,32768,1,1,1,1}}",
" setDefaultColors()",
" term.clear()",
" paintutils.drawImage(title,-1,1)",
" setDefaultColors()",
" term.setCursorPos(4,16)",
" term.write(\"STD-GUI \"..(isBeta and \"Beta\" or \"Stable\"))",
" sleep(0)",
" local evt",
" repeat",
" evt = os.pullEvent()",
" until evt == \"mouse_click\" or evt == \"key\"",
" sleep(0)",
"end",
"",
"local fixDotY",
"",
"local renderStoreItem = function(obj) --now being experimented on...",
" if not obj.title then return false end",
" local showPostURL = false",
" local bruffer",
" local scroll = 1",
" local doRedraw = true",
" local extraLines",
" while true do",
" bruffer = {",
" \"\",",
" \" &\"..blit_names[palate.item.specialtxt]..obj.title,",
" \" &\"..blit_names[palate.item.txt]..\"by &\"..blit_names[palate.item.specialtxt]..obj.creator,",
" \" &\"..blit_names[palate.item.txt]..\"Category: \"..std.storeCatagoryNames[obj.catagory],",
" \"\",",
" \"&\"..blit_names[palate.item.txt]..obj.description,",
" }",
" if showPostURL and obj.forumPost then",
" local post = \" &\"..blit_names[palate.item.forumtxt]..\"~\"..blit_names[palate.item.forumbg]..obj.forumPost:gsub(\"http://www.\",\"\"):sub(1,-2)",
" table.insert(bruffer,\"&8Forum URL: \"..post)",
" end",
" if doRedraw then",
" term.setBackgroundColor(palate.item.bg)",
" term.clear()",
" term.setCursorPos(1,(-scroll)+2)",
" extraLines = 0",
" for y = 1, #bruffer do",
" if not bruffer[y] then break end",
" extraLines = extraLines + printf(bruffer[y])",
" end",
" ",
" term.setCursorPos(1,scr_y)",
" if term.isColor() then",
" term.setTextColor(palate.item.closetxt)",
" term.setBackgroundColor(palate.item.closebg)",
" else",
" term.setTextColor(colors.black)",
" term.setBackgroundColor(colors.white)",
" end",
" term.clearLine()",
" if term.isColor() then",
" term.write(\"CLOSE\")",
" else",
" term.write(\"(Q) to CLOSE\")",
" end",
" if term.isColor() then",
" term.setTextColor(palate.store.previewtxt)",
" term.setBackgroundColor(palate.store.previewbg)",
" term.setCursorPos((scr_x-16),scr_y)",
" term.write(\"VIEW\")",
" term.setTextColor(palate.item.runtxt)",
" term.setBackgroundColor(palate.item.runbg)",
" term.setCursorPos((scr_x-11),scr_y)",
" term.write(\"RUN\")",
" else",
" term.setTextColor(colors.black)",
" term.setBackgroundColor(colors.white)",
" term.setCursorPos((scr_x-22),scr_y)",
" term.write(\"(V)IEW\")",
" term.setTextColor(colors.black)",
" term.setBackgroundColor(colors.white)",
" term.setCursorPos((scr_x-15),scr_y)",
" term.write(\"(R)UN\")",
" end",
" local txt",
" if isSimSoft or isAxiom then",
" if term.isColor() then --yeah yeah, simsoft can't run on normal computers, but axiom can, so shut your cunting trap",
" term.setTextColor(palate.item.downloadtxt)",
" term.setBackgroundColor(palate.item.downloadbg)",
" txt = \"INSTALL!\"",
" else",
" txt = \"(I)NSTALL\"",
" end",
" else",
" if term.isColor() then",
" term.setTextColor(palate.item.downloadtxt)",
" term.setBackgroundColor(palate.item.downloadbg)",
" txt = \"DOWNLOAD\"",
" else",
" txt = \"(D)OWNLOAD\"",
" end",
" end",
" term.setCursorPos((scr_x-(#txt-1)),scr_y)",
" term.write(txt)",
" doRedraw = false",
" end",
" local evt = {getEvents(\"key\",\"mouse_click\",\"mouse_scroll\",\"term_resize\")}",
" if evt[1] == \"key\" then",
" if evt[2] == keys.f then",
" showPostURL = not showPostURL",
" doRedraw = true",
" elseif evt[2] == keys.d or evt[2] == keys.i or evt[2] == keys.r or evt[2] == keys.q or evt[2] == keys.v then",
" return unpack(evt)",
" end",
" elseif evt[1] == \"mouse_click\" then",
" if evt[4] == scr_y then",
" return unpack(evt)",
" end",
" elseif evt[1] == \"mouse_scroll\" then",
" if scroll+evt[2] >= 1 and scroll+evt[2] <= (#bruffer+extraLines)-(scr_y-8) then",
" scroll = scroll + evt[2]",
" doRedraw = true",
" end",
" elseif evt[1] == \"term_resize\" then",
" doRedraw = true",
" scr_x,scr_y = term.getSize()",
" end",
" end",
"end",
"",
"local renderCatagoryMenu = function(expanded,cursor)",
" if expanded then",
" term.setCursorPos(1,1)",
" term.setBackgroundColor(palate.menubar.bg)",
" term.clearLine()",
" term.setBackgroundColor(palate.menubar.categorymenu.selectbg)",
" term.setTextColor(palate.menubar.categorymenu.selecttxt)",
" if term.isColor() then",
" if cursor == 0 then",
" term.setTextColor(palate.menubar.categorymenu.txt)",
" term.write(\" No category\")",
" else",
" term.write(\"Select category:\")",
" end",
" else",
" term.setCursorPos(1,1)",
" if cursor == 0 then",
" term.setTextColor(palate.menubar.categorymenu.txt)",
" term.write(\" No category\")",
" else",
" term.write(\" Pick category with up/down:\")",
" end",
" end",
" term.setTextColor(palate.menubar.categorymenu.txt)",
" term.setBackgroundColor(palate.menubar.categorymenu.bg)",
" local yposes = {}",
" local longestLen = 0",
" for a = 1, #std.storeCatagoryNames do",
" if #std.storeCatagoryNames[a]+2 > longestLen then",
" longestLen = #std.storeCatagoryNames[a]+2",
" end",
" end",
" longestLen = longestLen+1",
" for a = 0, #std.storeCatagoryNames do",
" term.setCursorPos(1,a+1)",
" if term.isColor() then",
" term.setTextColor(palate.menubar.categorymenu.orbtxt)",
" term.setBackgroundColor(palate.menubar.categorymenu.bg)",
" if type(std.storeCatagoryColors) == \"table\" then",
" if std.storeCatagoryColors[a] then",
" term.setTextColor(std.storeCatagoryColors[a].txt)",
" term.setBackgroundColor(std.storeCatagoryColors[a].bg)",
" end",
" end",
" else",
" term.setTextColor(colors.black)",
" term.setBackgroundColor(colors.lightGray)",
" end",
" if a > 0 then",
" clearMostline(longestLen+2)",
" end",
" if a == cursor then",
" if type(std.storeCatagoryColors) ~= \"table\" then",
" if term.isColor() then",
" if cursor == 0 then",
" term.setTextColor(palate.menubar.categorymenu.txt)",
" term.setBackgroundColor(palate.menubar.categorymenu.bg)",
" else",
" term.setTextColor(palate.menubar.categorymenu.cursortxt)",
" term.setBackgroundColor(palate.menubar.categorymenu.cursorbg)",
" end",
" else",
" term.setTextColor(colors.black)",
" term.setBackgroundColor(colors.lightGray)",
" end",
" elseif cursor == 0 then",
" term.setBackgroundColor(colors.black)",
" end",
" write(\">\")",
" elseif a > 0 then",
" write(\" \")",
" end",
" if a > 0 then",
" if type(std.storeCatagoryColors) ~= \"table\" then",
" term.setTextColor(palate.menubar.categorymenu.orbtxt)",
" term.setBackgroundColor(palate.menubar.categorymenu.bg)",
" end",
" if a == catag then",
" write(\"@ \")",
" else",
" write(\"O \")",
" end",
" write(std.storeCatagoryNames[a])",
" if term.isColor() then",
" term.setBackgroundColor(palate.menubar.categorymenu.borderbg)",
" else",
" term.setBackgroundColor(colors.black)",
" end",
" term.setCursorPos(longestLen+2,a+1)",
" term.write(\" \")",
" table.insert(yposes,a+1)",
" end",
" end",
" term.setCursorPos(1,#std.storeCatagoryNames+2)",
" term.write((\" \"):rep(longestLen+2))",
" return yposes,longestLen+2",
" else",
" term.setCursorPos(1,1)",
" term.setBackgroundColor(palate.menubar.bg)",
" term.clearLine()",
" term.setTextColor(palate.menubar.categorytxt)",
" term.setBackgroundColor(palate.menubar.categorybg)",
" term.write(\"Cat.\")",
" term.setTextColor(palate.menubar.hotkeytxt)",
" term.write(\"F1\")",
" term.setCursorPos(8,1)",
" term.setTextColor(palate.menubar.channeltxt)",
" term.setBackgroundColor(palate.menubar.channelbg)",
" term.write(\"Chan.\")",
" term.setTextColor(palate.menubar.hotkeytxt)",
" term.write(\"F3\")",
" --writef(\"~f&8Cat.&7F1~r&r ~f&8Chan.&7F3\")",
" end",
" if term.isColor() then",
" term.setCursorPos(scr_x-4,1)",
" term.setBackgroundColor(palate.store.closebg)",
" term.setTextColor(palate.store.closetxt)",
" term.write(\"CLOSE\")",
" else",
" term.setCursorPos(scr_x-11,1)",
" term.setBackgroundColor(colors.black)",
" term.setTextColor(colors.white)",
" term.write(\"'Q' to CLOSE\")",
" end",
" setDefaultColors()",
"end",
"",
"local renderChannelMenu = function(cursor)",
" term.setCursorPos(1,1)",
" term.setBackgroundColor(palate.menubar.bg)",
" term.clearLine()",
" term.setBackgroundColor(palate.menubar.channelmenu.selectbg)",
" term.setTextColor(palate.menubar.channelmenu.selecttxt)",
" term.write(\"Select channel:\")",
" term.setTextColor(palate.menubar.channelmenu.txt)",
" term.setBackgroundColor(palate.menubar.channelmenu.bg)",
" local yposes = {}",
" local longestLen = 0",
" for a = 1, #std.channelNames do",
" if #std.channelNames[a] > longestLen then",
" longestLen = #std.channelNames[a]",
" end",
" end",
" longestLen = longestLen + 4",
" for a = 1, #std.channelNames do",
" term.setBackgroundColor(palate.menubar.channelmenu.bg)",
" term.setCursorPos(1,a+1)",
" clearMostline(longestLen+2)",
" if a == cursor then",
" term.setTextColor(palate.menubar.channelmenu.cursortxt)",
" term.setBackgroundColor(palate.menubar.channelmenu.cursorbg)",
" write(\">\")",
" else",
" write(\" \")",
" end",
" term.setTextColor(palate.menubar.channelmenu.orbtxt)",
" term.setBackgroundColor(palate.menubar.channelmenu.bg)",
" if std.channel == std.channelNames[a] then",
" write(\"@ \")",
" else",
" write(\"O \")",
" end",
" term.write(\" \"..std.channelNames[a])",
" if term.isColor() then",
" term.setBackgroundColor(palate.menubar.channelmenu.borderbg)",
" else",
" term.setBackgroundColor(colors.black)",
" end",
" term.setCursorPos(longestLen+2,a+1)",
" term.write(\" \")",
" table.insert(yposes,{a+1,std.channelNames[a],std.channelURLs[std.channelNames[a]]})",
" end",
" term.setCursorPos(1,#std.channelNames+2)",
" term.write((\" \"):rep(longestLen+2))",
" return yposes,longestLen+2",
"end",
"",
"local tArg = {...}",
"",
"if tArg[1] == \"help\" then",
" return displayHelp(true)",
"elseif tArg[1] == \"upgrade\" then",
" local updateURL = isBeta and \"http://pastebin.com/raw/uMZ23APu\" or \"http://pastebin.com/raw/P9dDhQ2m\"",
" local res, outcome = getFile(shell.getRunningProgram(),updateURL)",
" if not res then",
" error(outcome)",
" else",
" print(\"Updated STD-GUI to latest \"..(isBeta and \"beta.\" or \"stable.\")..\" (\"..outcome..\" bytes)\")",
" return",
" end",
"end",
"",
"local res, outcome",
"if tArg[1] == \"update\" then",
" res, outcome = std.getSTDList(std.prevChannel)",
" print(outcome)",
" return",
"else",
" if not std.storeURLs then",
" pleaseWait() -- he said please",
" res, outcome = std.getSTDList(std.prevChannel)",
" end",
"end",
"",
"local cleanExit = function()",
" term.setTextColor(colors.white)",
" term.setBackgroundColor(colors.black)",
" term.clear()",
" local out",
" if pocket then",
" out = \"Thanks for using STD!\"",
" else",
" out = \"Thank you for using STD-GUI!\"",
" end",
" if isSimSoft or isAxiom then",
" term.setCursorBlink(false)",
" end",
" cprint(out,scr_y/2)",
" term.setCursorPos(1,scr_y)",
" sleep(0)",
" return true, \"This shouldn't be an error.\"",
"end",
"local STDdownloadPrompt = function(item)",
" term.setCursorPos(1,scr_y)",
" for k,v in pairs(std.storeURLs) do",
" if item.url == v.url then",
" itname = k",
" break",
" end",
" end",
" local savepath",
" if isAxiom then",
" if std.storeURLs[itname].catagory == 8 then --if an API",
" savepath = fs.combine(\"/home/APIs\",itname)",
" else",
" savepath = fs.combine(\"/Axiom/programs\",itname)..\".app\"",
" end",
" else",
" bow()",
" term.clearLine()",
" write(\"Save as: \")",
" savepath = funcread(nil,{},nil,true)",
" term.setCursorBlink(false)",
" end",
" if savepath:gsub(\" \",\"\") == \"\" then",
" sleep(0)",
" return",
" else",
" if relativePath then",
" savepath = fs.combine(shell.dir(),savepath)",
" end",
" if fs.exists(savepath) then",
" term.setCursorPos(1,scr_y)",
" term.clearLine()",
" write(\"Overwrite? (Y/N)\")",
" local key",
" repeat",
" _,key = os.pullEvent(\"char\")",
" until string.find(\"yn\",key)",
" if key == \"n\" then",
" sleep(0)",
" return",
" end",
" end",
" term.setCursorPos(1,scr_y)",
" term.clearLine()",
" term.write(\"Downloading...\")",
" local res, outcome = getFile(savepath,item.url)",
" term.setCursorPos(1,scr_y)",
" term.clearLine()",
" if not res then",
" term.write(outcome)",
" sleep(0.6)",
" else",
" if isAxiom then",
" if std.storeURLs[itname].catagory ~= 8 then --no need for an icon for an api, wouldn't you say",
" local file = fs.open(fs.combine(\"home/Desktop\",itname)..\".lnk\", \"w\")",
" file.write(savepath)",
" file.close()",
" end",
" end",
" term.write(\"Downloaded! (\"..outcome..\" bytes)\")",
" sleep(0.7)",
" end",
" end",
" return",
"end",
"",
"SimSoftDownloadPrompt = function(object)",
" local itname",
" for k,v in pairs(std.storeURLs) do",
" if object.url == v.url then",
" itname = k",
" break",
" end",
" end",
" term.setCursorPos(1,scr_y)",
" bow()",
" term.clearLine()",
" write(\"Label?:\")",
" local custLabel = funcread(_,_,_,true)",
" if #custLabel:gsub(\"%s\",\"\") == 0 then",
" custLabel = nil",
" else",
" custLabel = custLabel:sub(1,9)",
" end",
" term.setCursorPos(1,scr_y)",
" term.clearLine()",
" term.write(\"Downloading...\")",
" local res, outcome = simSoftInstall(object,itname or object.title:gsub(\" \",\"-\"),custLabel)",
" term.setCursorPos(1,scr_y)",
" term.clearLine()",
" term.write(outcome)",
" sleep(#outcome/13)",
"end",
"",
"local doCategoryMenu = function()",
" local mcursor = catag --(not term.isColor()) and (catag or 0) or false",
" local cats,longth = renderCatagoryMenu(true,mcursor)",
" local evt,butt,x,y",
" while true do",
" local evt,butt,x,y = os.pullEvent()",
" if evt == \"mouse_click\" or (evt == \"mouse_up\" and y ~= 1) then",
" doRedraw = true",
" if y == 1 then",
" catag = 0",
" break",
" else",
" for a = 1, #cats do",
" if cats[a] == y and x <= longth then",
" catag = a",
" scroll = 1",
" end",
" end",
" break",
" end",
" elseif evt == \"key\" then",
" if butt == keys.f1 then",
" break",
" elseif mcursor then",
" if (butt == keys.up) and (mcursor > 0) then",
" mcursor = mcursor - 1",
" doRedraw = true",
" elseif (butt == keys.down) and (mcursor < #std.storeCatagoryNames) then",
" mcursor = mcursor + 1",
" doRedraw = true",
" elseif (butt == keys.enter) or (butt == keys.space) then",
" os.queueEvent(\"mouse_click\",1,2,mcursor+1)",
" end",
" end",
" end",
" if doRedraw then",
" renderCatagoryMenu(true,mcursor)",
" doRedraw = false",
" end",
" end",
" maxScroll = setMaxScroll(catag)",
"end",
"",
"local doChannelMenu = function()",
" local mcursor = 1 --(not term.isColor()) and 1 or false",
" local yposes, longth = renderChannelMenu(mcursor)",
" local evt,butt,x,y",
" while true do",
" local evt,butt,x,y = os.pullEvent()",
" if evt == \"mouse_click\" or (evt == \"mouse_up\" and y ~= 1) then",
" if y == 1 then break else",
" for a = 1, #yposes do",
" if (yposes[a][1] == y) and (x <= longth) then",
" if std.channel ~= yposes[a][2] then",
" std.prevChannel = std.channel",
" std.channel = yposes[a][2]",
" scroll = 1",
" std.getSTDList(std.prevChannel)",
" end",
" break",
" end",
" end",
" break",
" end",
" elseif evt == \"key\" then",
" if butt == keys.f3 then",
" break",
" elseif mcursor then",
" if (butt == keys.up) and (mcursor > 1) then",
" mcursor = mcursor - 1",
" elseif (butt == keys.down) and (mcursor < #std.channelNames) then",
" mcursor = mcursor + 1",
" elseif (butt == keys.enter) or (butt == keys.space) then",
" os.queueEvent(\"mouse_click\",1,2,mcursor+1)",
" end",
" end",
" end",
" renderChannelMenu(mcursor)",
" end",
" maxScroll = setMaxScroll(catag)",
"end",
"",
"local STDViewEntry = function(url)",
" local contents, outcome = contentsFile(url)",
" if not contents then",
" term.write(outcome)",
" sleep(0.6)",
" return",
" else",
" strless(contents,palate.item.previewtxt,palate.item.previewbg)",
" end",
"end",
"",
"local doEverything = function() --do I have to do EVERYTHING?",
" if not std.storeURLs then",
" pleaseWait()",
" std.getSTDList(std.prevChannel)",
" end",
" maxScroll = setMaxScroll(catag)",
" local yposes",
" while true do",
" if scroll > maxScroll then",
" scroll = maxScroll",
" end",
" if scroll < 1 then",
" scroll = 1",
" end",
" if (scroll-1 % 4 ~= 0) and (not term.isColor()) then",
" scroll = scroll - ((scroll-1) % 4)",
" end",
" local mcursor = (not term.isColor()) and 1 or false",
" yposes = renderStore(std.storeURLs,catag,scroll,scrollX,fixDotY,not term.isColor())",
" renderCatagoryMenu(false,mcursor)",
" local evt = {getEvents(\"mouse_scroll\",\"mouse_click\",\"mouse_up\",\"key\",\"mouse_drag\",\"char\")}",
" scr_x, scr_y = term.getSize()",
" if evt[1] == \"mouse_scroll\" then",
" if scroll+evt[2] >= 1 and scroll+evt[2] <= maxScroll then",
" scroll = scroll+evt[2]",
" doRedraw = true",
" end",
" elseif evt[1] == \"mouse_click\" and (evt[2] == 1) and (evt[4] <= scr_y) and (evt[4] >= 1) then --left click only! must deport right mouse buttons!",
" if evt[3] == scr_x and evt[4] == math.floor(dotY) then",
" doScrollBar = true",
" end",
" if evt[4] == 1 then",
" if evt[3] >= scr_x-4 then",
" return cleanExit()",
" else",
" if evt[3] >= 1 and evt[3] <= 6 then",
" doCategoryMenu()",
" elseif evt[3] >= 8 and evt[3] <= 14 then",
" doChannelMenu()",
" end",
" end",
" elseif yposes[evt[4]-1] and evt[3] ~= scr_x then",
" local y = evt[4]-1",
" local showPostURL = false",
" local guud = yposes[y].title",
" scrollX = 1",
" while true do",
" if not guud then break end",
" local event,butt,cx,cy = renderStoreItem(yposes[y],showPostURL)",
" if event == \"key\" then",
" if butt == keys.q then",
" sleep(0)",
" break",
" elseif butt == keys.d then --hehe",
" sleep(0)",
" STDdownloadPrompt(yposes[y])",
" --break",
" elseif butt == keys.v then",
" sleep(0)",
" STDViewEntry(yposes[y].url)",
" --break",
" elseif (butt == keys.i) then",
" sleep(0)",
" if isSimSoft then",
" SimSoftDownloadPrompt(yposes[y])",
" elseif isAxiom then",
" STDdownloadPrompt(yposes[y]) --axiom only changes the ",
" end",
" --break",
" end",
" elseif event == \"mouse_click\" then",
" if cy == scr_y then",
" if (cx < scr_x-7) or (cx > scr_x) then",
" if cx >= scr_x-11 and cx < scr_x-8 then",
" term.setCursorPos(1,scr_y)",
" bow()",
" term.clearLine()",
" if pocket or turtle then",
" write(\"Args.: \")",
" else",
" write(\"Arguments:\")",
" end",
" local arguments = explode(\" \",funcread(nil,{},nil,true)) or {}",
" term.setTextColor(colors.white)",
" term.setBackgroundColor(colors.black)",
" term.clear()",
" term.setCursorPos(1,1)",
" local oldcpath",
" if shell then",
" oldcpath = shell.dir()",
" shell.setDir(\"\")",
" end",
" if #arguments == 0 then",
" runURL(yposes[y].url)",
" else",
" runURL(yposes[y].url,unpack(arguments))",
" end",
" if shell then",
" shell.setDir(oldcpath or \"\")",
" end",
" sleep(0)",
" write(\"[press a key]\")",
" os.pullEvent(\"key\")",
" elseif cx >= scr_x-16 and cx < scr_x-12 then",
" STDViewEntry(yposes[y].url)",
" end",
" sleep(0)",
" break",
" else",
" term.setCursorPos(1,scr_y)",
" bow()",
" term.clearLine()",
" if isSimSoft then",
" SimSoftDownloadPrompt(yposes[y])",
" break",
" else",
" STDdownloadPrompt(yposes[y])",
" break",
" end",
" end",
" end",
" end",
" end",
" end",
" elseif evt[1] == \"mouse_up\" then",
" doScrollBar = false",
" fixDotY = nil",
" elseif evt[1] == \"mouse_drag\" then",
" if doScrollBar then",
" local my = evt[4]",
" if my > scr_y then --operating systems might allow this to be true",
" my = scr_y",
" elseif my < 1 then --this too",
" my = 1",
" end",
" if my > 1 then",
" scroll = math.floor( (my-2)/(scr_y-2) * (maxScroll)) + 1",
" fixDotY = my",
" end",
" end",
" elseif evt[1] == \"key\" then",
" if evt[2] == keys.q then",
" return cleanExit()",
" elseif evt[2] == keys.down then",
" scroll = scroll + 4",
" elseif evt[2] == keys.up then",
" scroll = scroll - 4",
" elseif evt[2] == keys.pageDown then",
" scroll = scroll + (scr_y-1)",
" elseif evt[2] == keys.pageUp then",
" scroll = scroll - (scr_y-1)",
" elseif evt[2] == keys.home then",
" scroll = 1",
" elseif evt[2] == keys['end'] then",
" scroll = maxScroll",
" elseif evt[2] == keys.h then --help screen!",
" displayHelp(false)",
" elseif evt[2] == keys.right then",
" scrollX = scrollX + 1",
" elseif evt[2] == keys.left then",
" if scrollX > 1 then",
" scrollX = scrollX - 1",
" end",
" elseif (evt[2] == keys.numPadAdd) or (evt[2] == keys.rightBracket) then",
" catag = catag + 1",
" if catag > #std.storeCatagoryNames then",
" catag = 0",
" end",
" scroll = 1",
" maxScroll = setMaxScroll(catag)",
" elseif (evt[2] == keys.minus) or (evt[2] == keys.leftBracket) then",
" catag = catag - 1",
" if catag < 0 then",
" catag = #std.storeCatagoryNames",
" end",
" scroll = 1",
" maxScroll = setMaxScroll(catag)",
" elseif evt[2] == keys.f5 then",
" pleaseWait()",
" std.getSTDList(std.prevChannel)",
" elseif (evt[2] == keys.f12) and (not isSimSoft) then",
" local updateURL = isBeta and \"http://pastebin.com/raw/uMZ23APu\" or \"http://pastebin.com/raw/P9dDhQ2m\"",
" getFile(shell.getRunningProgram(),updateURL)",
" local flashes = {",
" colors.black,",
" colors.white,",
" colors.lightGray,",
" colors.gray,",
" colors.black,",
" }",
" for a = 1, #flashes do",
" term.setBackgroundColor(flashes[a])",
" term.clear()",
" sleep(0)",
" end",
" return",
" elseif evt[2] == keys.f1 then",
" doCategoryMenu()",
" elseif evt[2] == keys.f or evt[2] == keys.f6 then",
" --runFile(std.stdList)",
" findPrompt()",
" elseif evt[2] == keys.f3 then",
" doChannelMenu()",
" end",
" elseif evt[1] == \"char\" then",
" if tonumber(evt[2]) then",
" local a = tonumber(evt[2]) ~= \"0\" and tonumber(evt[2]) or \"10\"",
" local b = (a*4)-1",
" os.queueEvent(\"mouse_click\",1,scr_x-3,b)",
" end",
" end",
" end",
"end",
"",
"if doDisplayTitle then",
" displayTitle()",
"end",
"",
"if std.storeURLs then std.storeURLs = getFindList(\"\") end",
"",
"local errorHandler = function()",
" local success, message = pcall(doEverything)",
" if success then",
" return true",
" end",
" if message == \"Terminated\" then",
" term.setBackgroundColor(colors.black)",
" term.scroll(2)",
" term.setCursorPos(1, scr_y-1)",
" printError(message)",
" return false, message",
" else",
" term.setBackgroundColor(colors.white)",
" for a = 1, math.ceil(scr_y/2) do",
" term.scroll(2)",
" end",
" term.setTextColor(colors.black)",
" cprint(\"STD-GUI has encountered an error!\",2)",
" term.setCursorPos(1,4)",
" term.setTextColor(term.isColor() and colors.red or colors.gray)",
" print(message or \"\"..\"\\n\")",
" term.setTextColor(colors.black)",
" print(\" Please contact LDDestroier/EldidiStroyrr on either the ComputerCraft forums, or through other means.\")",
" sleep(0.5)",
" print(\"\\nPush a key.\")",
" os.pullEvent(\"key\")",
" term.setCursorPos(1,scr_y)",
" term.setBackgroundColor(colors.black)",
" term.setTextColor(colors.white)",
" term.clearLine()",
" return false, message",
" end",
"end",
"",
"return errorHandler()",
},
[ "/game/data/sprites/stickdude/walk1.nft" ] = {
"ž0f f0„",
"‹Ÿ",
"  f0•",
"˜‰",
"•  f0•",
},
[ "/util/http/std.lua" ] = {
"--[[",
"Super Text Downloader by EldidiStroyrr/LDDestroier",
"",
"The purpose of this program is to have a single",
"unified download script for ComputerCraft, as opposed",
"to making multiple programs, each able to download from one site.",
"",
"The main aspect to make this script more modular is having",
"a table (websiteSyntaxes) to store the website that it downloads",
"from, as well as what abbreviation it's called with and the",
"syntax of the raw download URL.",
"Later updates added special prefixes that act in different ways",
"that could not work with the standard syntax.",
"",
" pastebin get 3PBKGR4k std ",
" std ld std std ",
"--]]",
"",
"if type(std) ~= \"table\" then std = {} end",
"",
"std.channelURLs = { --special URLs for getting a list of files.",
" [\"STD\"] = \"https://raw.githubusercontent.com/LDDestroier/STD-GUI/master/list.lua\", --stock",
" [\"Discover\"] = \"https://pastebin.com/raw/9bXfCz6M\", --owned by dannysmc95",
" --[\"OnlineAPPS\"] = \"https://pastebin.com/raw/g2EnDYLp\", --owned by Twijn, but discontinued",
" [\"STD-Media\"] = \"https://pastebin.com/raw/3JZHXTGL\" --non-program media files",
"}",
"local goodchan = false",
"for k,v in pairs(std.channelURLs) do",
" if std.channel == k then",
" goodchan = true",
" break",
" end",
"end",
"if not goodchan then",
" std.channel = \"STD\"",
"end",
"std.prevChannel = std.channel",
"std.std_version = 1.453 --Number, not string!",
"std.stdList = \"/.\"..std.channel:lower()..\"_list\" --String, path of store listings",
"std.websiteList = \"/.std_websites\" --String, path of website listings",
"local doStore = true --If you do 'std ld', should you open up the store? Or just fuck off?",
"std.serious = true",
"",
"local logo = {[[",
" __________________________",
" / ___________ ______ ____ \\",
"/ / | | | | \\ \\",
"\\ \\______ | | | | | |",
" \\______ \\ | | | | | |",
" \\ \\ | | | | | |",
" ______/ / | | | |___/ /",
" /_______/ |_| |______/",
" Super Text Downloader",
"",
"]],[[",
" LLL LLLLL LLL",
" L L L L L",
" L L L L",
" LLL L L L",
" L L L L",
" L L L L L",
" LLL L LLL",
" Super Text Downloader]]",
"",
"}",
"",
"",
"-- start Base64",
"local b = \"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/\"",
"local encode = function(data)",
" return ((data:gsub('.', function(x) ",
" local r,b='',x:byte()",
" for i=8,1,-1 do r=r..(b%2^i-b%2^(i-1)>0 and '1' or '0') end",
" return r;",
" end)..'0000'):gsub('%d%d%d?%d?%d?%d?', function(x)",
" if (#x < 6) then return '' end",
" local c=0",
" for i=1,6 do c=c+(x:sub(i,i)=='1' and 2^(6-i) or 0) end",
" return b:sub(c+1,c+1)",
" end)..({ '', '==', '=' })[#data%3+1])",
"end",
"local decode = function(data)",
" data = string.gsub(data, '[^'..b..'=]', '')",
" return (data:gsub('.', function(x)",
" if (x == '=') then return '' end",
" local r,f='',(b:find(x)-1)",
" for i=6,1,-1 do r=r..(f%2^i-f%2^(i-1)>0 and '1' or '0') end",
" return r;",
" end):gsub('%d%d%d?%d?%d?%d?%d?%d?', function(x)",
" if (#x ~= 8) then return '' end",
" local c=0",
" for i=1,8 do c=c+(x:sub(i,i)=='1' and 2^(8-i) or 0) end",
" return string.char(c)",
" end))",
"end",
"-- finished Base64",
"",
"local runFile = function(path)",
" if not fs.exists(path) then",
" return false, \"No such file!\"",
" end",
" local file = fs.open(path,\"r\")",
" local contents = file.readAll()",
" file.close()",
" local func = loadstring(contents)",
" setfenv(func, getfenv())",
" return func()",
"end",
"",
"local function runURL(url, ...)",
" local program = http.get(url)",
" if not program then return false end",
" program = program.readAll()",
" local func = loadstring(program)",
" setfenv(func, getfenv())",
" return func(...)",
"end",
"",
"local function seperateMethods(input)",
" local output={}",
" for key,value in pairs(input) do",
" table.insert(output, {key,value})",
" end",
" return output",
"end",
"",
"local function displayHelp(mode)",
" if mode == 1 then",
" print(\"std <abbr> <fileid> [output]\")",
" print(\"Do 'std list' to see all codes\")",
" print(\"Do 'std ld' for a GUI\")",
" write(\"Channel '\")",
" if term.isColor() then term.setTextColor(colors.yellow) end",
" write(std.channel)",
" term.setTextColor(colors.white)",
" print(\"' is selected.\")",
" elseif mode == 2 then",
" if std.serious then",
" print(\"List of website codes:\")",
" else",
" print(\"all ur codes:\")",
" end",
" std.websiteSyntaxes[\"dd\"] = {} --Filler",
" std.websiteSyntaxes[\"dd64\"] = {}",
" std.websiteSyntaxes[\"PB\"] = {}",
" for k,v in pairs(std.websiteSyntaxes) do",
" if term.getTextColor then prevColor = term.getTextColor() else prevColor = colors.white end",
" write(\" '\")",
" if term.isColor() then term.setTextColor(colors.orange) end",
" write(k)",
" term.setTextColor(prevColor)",
" write(\"' \")",
" if k == \"dd\" then",
" print(\"direct download\")",
" elseif k == \"dd64\" then",
" print(\"direct download + Base64\")",
" elseif k == \"PB\" then",
" print(\"pastebin.com (safe)\")",
" elseif string.find(v.url,\"/\") then",
" start = string.find(v.url,\"://\")+3",
" finish = string.find(v.url,\"/\",9)-1",
" print(string.sub(v.url,start,finish))",
" end",
" end",
" elseif mode == 3 then",
" print(logo[pocket and 2 or 1])",
" end",
"end",
"",
"local function choice(input) --A useful function for input. Similar to the MS-DOS 6.0 command.",
" local event, key",
" repeat",
" event, key = os.pullEvent(\"key\")",
" if type(key) == \"number\" then key = keys.getName(key) end",
" if key == nil then key = \" \" end",
" until string.find(string.lower(input), string.lower(key))",
" return string.lower(key)",
"end",
"",
"--This list of websites is used as a backup, should you not be able to connect to pastebin.",
"std.websiteSyntaxes = {",
" pb = {",
" url = \"https://pastebin.com/raw.php?i=FILECODE\",",
" fullName = \"Pastebin\",",
" codeLength = 6,",
" },",
" hb = {",
" url = \"https://hastebin.com/raw/FILECODE\",",
" fullName = \"Hastebin\",",
" codeLength = 10,",
" },",
" pe = {",
" url = \"http://pastie.org/pastes/FILECODE/download\",",
" fullName = \"Pastie\",",
" codeLength = 0,",
" },",
" fn = {",
" url = \"https://fnpaste.com/FILECODE/raw\",",
" fullName = \"fnPaste\",",
" codeLength = 4,",
" },",
" gh = {",
" url = \"https://raw.githubusercontent.com/FILECODE\",",
" fullName = \"Github\",",
" codeLength = 0,",
" },",
" gg = {",
" url = \"https://gist.githubusercontent.com/FILECODE/raw/\",",
" fullName = \"Github Gist\",",
" codeLength = 0,",
" },",
" sn = {",
" url = \"http://s.drk.sc/FILECODE\",",
" fullName = \"Snippt\",",
" codeLength = 6,",
" },",
" cp = {",
" url = \"http://codepad.org/FILECODE/raw.txt\",",
" fullName = \"Codepad\",",
" codeLength = 8,",
" },",
" id = {",
" url = \"https://ideone.com/plain/FILECODE\",",
" fullName = \"Ideone\",",
" codeLength = 6,",
" },",
" db = {",
" url = \"https://www.dropbox.com/s/FILECODE?raw=true\",",
" fullName = \"Dropbox\",",
" codeLength = 0,",
" },",
" dd = {",
" url = \"FILECODE\",",
" fullName = \"Direct Download\",",
" codeLength = 0,",
" },",
"}",
"",
"local tArg = {...}",
"if shell then",
" std_file = shell.getRunningProgram()",
"else",
" std_file = \"\"",
"end",
"",
"local getTableSize = function(tbl)",
" local amnt = 0",
" for k,v in pairs(tbl) do",
" amnt = amnt + 1",
" end",
" return amnt",
"end",
"",
"std.getSTDList = function(prevChannel)",
" local weburl = \"http://pastebin.com/raw/FSCzZRUk\" --URL of URL list.",
" local storeurl = std.channelURLs[std.channel] --URL of store list.",
" local webcontents = http.get(weburl)",
" local storecontents = http.get(storeurl)",
" if not (webcontents and storecontents) then",
" if shell then",
" print(\"Couldn't update list!\")",
" end",
" return false, \"Couldn't update list!\"",
" else",
" local uut = runFile(std.stdList)",
" if not uut then std.storeURLs = nil end",
" local webprog = webcontents.readAll()",
" local storeprog = storecontents.readAll()",
" local webfile = fs.open(std.websiteList,\"w\")",
" local storefile = fs.open(std.stdList,\"w\")",
" ",
" webfile.writeLine(webprog)",
" webfile.close()",
" storefile.writeLine(storeprog)",
" storefile.close()",
" runFile(std.websiteList)",
" ",
" local outcome = runFile(std.stdList)",
" if outcome == false then",
" std.channel = prevChannel",
" return std.getSTDList(\"STD\")",
" end",
" return true, \"Downloaded to \"..std.stdList",
" end",
"end",
"",
"if tArg[1] == \"update\" or not fs.exists(std.stdList) then",
" local updateChan = tArg[2]",
" if (updateChan) and (not std.channelURLs[updateChan]) and tArg[1] == \"update\" then",
" printError(\"No such channel.\")",
" for k,v in pairs(std.channelURLs) do",
" term.setTextColor(colors.white)",
" write(\" \")",
" if k == std.channel then",
" write(\"@\")",
" if term.isColor() then term.setTextColor(colors.yellow) end",
" else",
" write(\"O\")",
" end",
" print(\" \"..k)",
" end",
" term.setTextColor(colors.white)",
" return",
" end",
" if std.serious then",
" write(\"Updating list...\")",
" else",
" write(\"just a sec, gettin your repo...\")",
" end",
" if updateChan and std.channelURLs[updateChan] then",
" std.prevChannel = std.channel",
" std.channel = updateChan",
" end",
" local success = std.getSTDList(std.prevChannel)",
" if not success then",
" if std.serious then",
" return printError(\"FAIL!\")",
" else",
" return printError(\"IT'S NO USE!\")",
" end",
" else",
" if std.serious then",
" print(\"good!\")",
" else",
" print(\"excellent!\")",
" end",
" if tArg[1] == \"update\" then return true end",
" end",
"end",
"",
"if not shell then return end",
"",
"local websiteCode = tArg[1]",
"local fileCode = tArg[2]",
"local retrieveName = tArg[3]",
"",
"if (websiteCode == \"list\") and (not fileCode) then",
" displayHelp(2)",
" return false",
"elseif (websiteCode == \"you foolish fool\") and (not fileCode) then",
" displayHelp(3)",
" return false",
"elseif (websiteCode ~= \"ld\") and (not fileCode) then",
" displayHelp(1)",
" return false",
"end",
"",
"local getFile = function(filename,url)",
" if fs.isReadOnly(filename) then",
" return false, \"access denied\"",
" end",
" local prog",
" if type(url) == \"table\" then",
" prog = contextualGet(url[1])",
" else",
" prog = http.get(url)",
" end",
" if not prog then",
" return false, \"could not connect\"",
" end",
" prog = prog.readAll()",
" local fyle = fs.open(filename,\"w\")",
" fyle.write(prog)",
" fyle.close()",
" return true, fs.getSize(filename)",
"end",
"",
"runFile(std.stdList)",
"runFile(std.websiteList)",
"local pastebinUpload = function(sName,sText)",
" write( \"Connecting to pastebin.com... \" )",
" local key = \"0ec2eb25b6166c0c27a394ae118ad829\"",
" local response = http.post(",
" \"http://pastebin.com/api/api_post.php\", ",
" \"api_option=paste&\"..",
" \"api_dev_key=\"..key..\"&\"..",
" \"api_paste_format=lua&\"..",
" \"api_paste_name=\"..textutils.urlEncode(sName)..\"&\"..",
" \"api_paste_code=\"..textutils.urlEncode(sText)",
" )",
" if response then",
" print( \"Success.\" )",
" local sResponse = response.readAll()",
" response.close()",
" return string.match( sResponse, \"[^/]+$\" )",
" end",
" return false",
"end",
"",
"local fileURL",
"if websiteCode == \"ld\" then",
" if not fileCode then",
" if doStore then",
" runURL(\"http://pastebin.com/raw/P9dDhQ2m\")",
" return",
" else",
" return print(\"GUI Store has been disabled.\")",
" end",
" else",
" if not std.storeURLs then",
" if std.serious then",
" write(\"Updating list...\")",
" else",
" write(\"just a sec, gettin your repo...\")",
" end",
" std.getSTDList()",
" end",
" if not std.storeURLs[fileCode] then",
" if std.serious then",
" return printError(\"Invalid store code '\" .. fileCode .. \"'\")",
" else",
" return printError(\"ld code \"..fileCode..\" not guuud!!!\")",
" end",
" else",
" fileURL = tostring(std.storeURLs[fileCode].url)",
" end",
" end",
"elseif websiteCode == \"PB\" then --Hope it's not confusing.",
" fileURL = \"https://pastebin.com/\"..fileCode:sub(1,8)",
" write(\"Conntecting to '\"..fileURL..\"' safely...\")",
" local prog = http.get(fileURL)",
" if not prog then",
" return printError(\"FAIL!\")",
" else",
" if term.isColor() then term.setTextColor(colors.green) end",
" print(\"GOOD!\")",
" term.setTextColor(colors.white)",
" local rawget = prog.readAll()",
" local s = string.find(rawget,\"<textarea id=\\\"paste_code\\\"\")+103",
" local e = string.find(rawget,\"</textarea>\")-1",
" local contents = string.gsub(string.sub(rawget,s,e),\"&quot;\",\"\\\"\")",
" contents = contents:gsub(\"&lt;\",\"<\")",
" contents = contents:gsub(\"&gt;\",\">\")",
" if retrieveName and shell then",
" local dlname = fs.combine(shell.dir(),retrieveName)",
" if fs.exists(dlname) then",
" if std.serious then",
" print(\"'\" .. dlname .. \"' exists! Overwrite?\")",
" write(\"[Y,N]?\")",
" else",
" print(\"yoo alreddy got a '\"..dlname..\"'!! redu eet?\")",
" write(\"[why,enn]??\")",
" end",
" local key = choice(\"yn\")",
" print(string.upper(key))",
" if key == \"n\" then",
" if std.serious then",
" print(\"Cancelled.\")",
" else",
" print(\"whatevz\")",
" end",
" sleep(0)",
" return false",
" end",
" end",
" local file = fs.open(dlname, \"w\")",
" file.writeLine(contents)",
" file.close()",
" if std.serious then",
" print(\"Done! DL'd \" .. fs.getSize(dlname) .. \" bytes.\")",
" else",
" print(\"yay guud! eets \".. fs.getSize(dlname)*2 ..\" nibbles\")",
" end",
" else",
" local func = loadstring(contents)",
" setfenv(func, getfenv())",
" func()",
" end",
" sleep(0)",
" return",
" end",
"elseif websiteCode == \"dd64\" then",
" write(\"Conntecting to '\"..fileCode..\"'...\")",
" local cont = http.get(fileCode)",
" local dlname = fs.combine(shell.dir(),retrieveName)",
" if cont then",
" if term.isColor() then term.setTextColor(colors.green) end",
" print(\"GOOD!\")",
" term.setTextColor(colors.white)",
" cont = decode(cont.readAll())",
" local file = fs.open(dlname,\"w\")",
" file.write(cont)",
" file.close()",
" if std.serious then",
" print(\"Done! DL'd \" .. fs.getSize(dlname) .. \" bytes.\")",
" else",
" print(\"yay guud! eets \".. fs.getSize(dlname)*2 ..\" nibbles\")",
" end",
" return true",
" else",
" return printError(\"FAIL!\")",
" end",
"elseif websiteCode == \"pbupload\" then",
" fileCode = fs.combine(\"\",fileCode)",
" if not fs.exists(fileCode) then",
" return printError(\"NO SUCH FILE!\")",
" else",
" local file = fs.open(fileCode,\"r\")",
" local cont = file.readAll()",
" file.close()",
" local sCode = pastebinUpload(fileCode,cont)",
" if sCode then",
" write(\"Uploaded with code:\")",
" if term.isColor() then term.setTextColor(colors.yellow) end",
" print(sCode)",
" term.setTextColor(colors.white)",
" print(\"Don't forget it!\")",
" else",
" return printError(\"FAIL!\")",
" end",
" return true",
" end",
"elseif websiteCode == \"pbupload64\" then",
" fileCode = fs.combine(\"\",fileCode)",
" if not fs.exists(fileCode) then",
" return printError(\"NO SUCH FILE!\")",
" else",
" local file = fs.open(fileCode,\"r\")",
" local cont = encode(file.readAll())",
" file.close()",
" local sCode = pastebinUpload(fileCode,cont)",
" if sCode then",
" write(\"Uploaded with Base64 with code:\")",
" if term.isColor() then term.setTextColor(colors.yellow) end",
" print(sCode)",
" term.setTextColor(colors.white)",
" print(\"Don't forget it!\")",
" else",
" return printError(\"FAIL!\")",
" end",
" return true",
" end",
"else",
" if not std.websiteSyntaxes[websiteCode] then",
" if std.serious then",
" return printError(\"Invalid website code '\" .. websiteCode .. \"'\")",
" else",
" return printError(\"dat '\"..websiteCode..\"' is NAWT GUUD!!\")",
" end",
" else",
" if (std.websiteSyntaxes[websiteCode].codeLength == 0) or (not std.websiteSyntaxes[websiteCode].codeLength) then",
" fileURL = string.gsub(std.websiteSyntaxes[websiteCode].url, \"FILECODE\", fileCode)",
" else",
" fileURL = string.gsub(std.websiteSyntaxes[websiteCode].url, \"FILECODE\", string.sub(fileCode,1,std.websiteSyntaxes[websiteCode].codeLength))",
" end",
" end",
" sleep(0)",
"end",
"",
"if std.serious then",
" write(\"Connecting to '\" .. fileURL .. \"'...\")",
"else",
" if math.random(1,2) == 1 then",
" write(\"gettin ze '\"..fileURL..\"'...\")",
" else",
" write(\"commeptin to '\"..fileURL..\"' naow...\")",
" end",
"end",
"local contents = http.get(fileURL)",
"if not contents then",
" if term.isColor() then",
" term.setTextColor(colors.red)",
" end",
" if std.serious then",
" print(\"NOPE!\")",
" else",
" print(\"NI!\")",
" end",
" sleep(0)",
" return false",
"else",
" if term.getTextColor then",
" prevColor = term.getTextColor()",
" else",
" prevColor = colors.white",
" end",
" if term.isColor() then",
" term.setTextColor(colors.green)",
" end",
" if std.serious then",
" print(\"good!\")",
" else",
" print(\"gud!\")",
" end",
" term.setTextColor(prevColor)",
" if retrieveName and shell then",
" local dlname = fs.combine(shell.dir(),retrieveName)",
" if fs.exists(dlname) then",
" if std.serious then",
" print(\"'\" .. dlname .. \"' exists! Overwrite?\")",
" write(\"[Y,N]?\")",
" else",
" print(\"yoo alreddy got a '\"..dlname..\"'!! redu eet?\")",
" write(\"[why,enn]??\")",
" end",
" local key = choice(\"yn\")",
" print(string.upper(key))",
" if key == \"n\" then",
" if std.serious then",
" print(\"Cancelled.\")",
" else",
" print(\"whatevz\")",
" end",
" sleep(0)",
" return false",
" end",
" end",
" local file = fs.open(dlname, \"w\")",
" file.writeLine(contents.readAll())",
" file.close()",
" if std.serious then",
" print(\"Done! DL'd \" .. fs.getSize(dlname) .. \" bytes.\")",
" else",
" print(\"yay guud! eets \".. fs.getSize(dlname)*2 ..\" nibbles\")",
" end",
" else",
" local contents = loadstring(contents.readAll())",
" setfenv(contents, getfenv())",
" contents()",
" end",
" sleep(0)",
" return true",
"end",
},
[ "/util/http/enchat3.lua" ] = {
"--[[",
" Enchat 3.0",
" Get with:",
" wget https://github.com/LDDestroier/enchat/raw/master/enchat3.lua enchat3.lua",
"",
"This is a stable release. You fool!",
"--]]",
"",
"local scr_x, scr_y = term.getSize()",
"local CHATBOX_SAFEMODE = nil",
"",
"local chatboxName = \"ec\"",
"local optInPhrase = \"opt in\"",
"local optOutPhrase = \"opt out\"",
"",
"-- non-changable settings",
"local enchat = {",
" version = 3.0,",
" isBeta = false,",
" port = 11000,",
" skynetPort = \"enchat3-default\",",
" url = \"https://github.com/LDDestroier/enchat/raw/master/enchat3.lua\",",
" betaurl = \"https://github.com/LDDestroier/enchat/raw/beta/enchat3.lua\",",
" ignoreModem = false,",
" dataDir = \"/.enchat\",",
" useChatbox = false,",
" disableChatboxWithRedstone = false,",
" useChatboxWhitelist = true",
"}",
"",
"local chatboxWhitelist = {}",
"",
"local enchatSettings = { -- DEFAULT, changable settings.",
" animDiv = 4, -- divisor of text animation speed (scrolling from left)",
" doAnimate = true, -- whether or not to animate text moving from left side of screen",
" reverseScroll = false, -- whether or not to make scrolling up really scroll down",
" redrawDelay = 0.1, -- delay between redrawing",
" useSetVisible = true, -- whether or not to use term.current().setVisible(), which has performance and flickering improvements",
" pageKeySpeed = 8, -- how far PageUP or PageDOWN should scroll",
" doNotif = true, -- whether or not to use oveerlay glasses for notifications, if possible",
" doKrazy = true, -- whether or not to add &k obfuscation",
" useSkynet = true, -- whether or not to use gollark's Skynet in addition to modem calls",
" extraNewline = true, -- adds an extra newline after every message since setting to true",
" acceptPictoChat = true -- whether or not to allow tablular enchat input, which is what /picto uses",
"}",
"",
"-- colors for various elements",
"local palette = {",
" bg = colors.black, -- background color",
" txt = colors.white, -- text color (should contrast with bg)",
" promptbg = colors.gray, -- chat prompt background",
" prompttxt = colors.white, -- chat prompt text",
" scrollMeter = colors.lightGray, -- scroll indicator",
" chevron = colors.black, -- color of \">\" left of text prompt",
" title = colors.lightGray, -- color of title, if available",
" titlebg = colors.lightGray -- background color of title, if available",
"}",
"",
"-- UI adjustments, used to emulate the appearence of other chat programs",
"local UIconf = {",
" promptY = 1, -- Y position of read prompt, relative to bottom of screen",
" chevron = \">\", -- symbol before read prompt",
" chatlogTop = 1, -- where chatlog is written to screen, relative to top of screen",
" title = \"\", -- overwritten every render, don't bother here",
" doTitle = false, -- whether or not to draw UIconf.title at the top of the screen",
" nameDecolor = false, -- if true, sets all names to palette.chevron color,",
" centerTitle = false, -- if true, centers the title",
" prefix = \"<\",",
" suffix = \"> \"",
"}",
"",
"-- Attempt to get some slight optimization through localizing basic functions.",
"local mathmax, mathmin, mathrandom = math.max, math.min, math.random",
"local termblit, termwrite = term.blit, term.write",
"local termsetCursorPos, termgetCursorPos, termsetCursorBlink = term.setCursorPos, term.getCursorPos, term.setCursorBlink",
"local termsetTextColor, termsetBackgroundColor = term.setTextColor, term.setBackgroundColor",
"local termgetTextColor, termgetBackgroundColor = term.getTextColor, term.getBackgroundColor",
"local termclear, termclearLine = term.clear, term.clearLine",
"local tableinsert, tableremove, tableconcat = table.insert, table.remove, table.concat",
"local textutilsserialize, textutilsunserialize = textutils.serialize, textutils.unserialize",
"local stringsub, stringgsub, stringrep = string.sub, string.gsub, string.rep",
"local unpack = unpack",
"-- This better do something.",
"",
"local initcolors = {",
" bg = termgetBackgroundColor(),",
" txt = termgetTextColor()",
"}",
"",
"local tArg = {...}",
"",
"local yourName = tArg[1]",
"local encKey = tArg[2]",
"",
"local setEncKey = function(newKey)",
" encKey = newKey",
"end",
"",
"local saveSettings = function()",
" local file = fs.open(fs.combine(enchat.dataDir, \"settings\"), \"w\")",
" file.write(",
" textutilsserialize({",
" enchatSettings = enchatSettings,",
" palette = palette,",
" UIconf = UIconf,",
" chatboxWhitelist = chatboxWhitelist,",
" })",
" )",
" file.close()",
"end",
"",
"local loadSettings = function()",
" local contents",
" if not fs.exists(fs.combine(enchat.dataDir, \"settings\")) then",
" saveSettings()",
" end",
" local file = fs.open(fs.combine(enchat.dataDir, \"settings\"), \"r\")",
" contents = file.readAll()",
" file.close()",
" local newSettings = textutilsunserialize(contents)",
" if newSettings then",
" for k,v in pairs(newSettings.enchatSettings) do",
" enchatSettings[k] = v",
" end",
" for k,v in pairs(newSettings.palette) do",
" palette[k] = v",
" end",
" for k,v in pairs(newSettings.UIconf) do",
" UIconf[k] = v",
" end",
" for k,v in pairs(newSettings.chatboxWhitelist) do",
" chatboxWhitelist[k] = v",
" end",
" else",
" saveSettings()",
" end",
"end",
"",
"local updateEnchat = function(doBeta)",
" local pPath = shell.getRunningProgram()",
" local h = http.get((doBeta or enchat.isBeta) and enchat.betaurl or enchat.url)",
" if not h then",
" return false, \"Could not connect.\"",
" else",
" local content = h.readAll()",
" local file = fs.open(pPath, \"w\")",
" file.write(content)",
" file.close()",
" return true, \"Updated!\"",
" end",
"end",
"",
"-- disables chat screen updating",
"local pauseRendering = true",
"",
"-- primarily for use when using the pallete command, hoh hoh",
"local colors_strnames = {",
" [\"white\"] = colors.white,",
" [\"pearl\"] = colors.white,",
" [\"silver\"] = colors.white,",
" [\"aryan\"] = colors.white,",
" [\"#f0f0f0\"] = colors.white,",
" ",
" [\"orange\"] = colors.orange,",
" [\"carrot\"] = colors.orange,",
" [\"fuhrer\"] = colors.orange,",
" [\"pumpkin\"] = colors.orange,",
" [\"#f2b233\"] = colors.orange,",
" ",
" [\"magenta\"] = colors.magenta,",
" [\"hotpink\"] = colors.magenta,",
" [\"lightpurple\"] = colors.magenta,",
" [\"light purple\"] = colors.magenta,",
" [\"#e57fd8\"] = colors.magenta,",
" ",
" [\"lightblue\"] = colors.lightBlue,",
" [\"light blue\"] = colors.lightBlue,",
" [\"skyblue\"] = colors.lightBlue,",
" [\"#99b2f2\"] = colors.lightBlue,",
" ",
" [\"yellow\"] = colors.yellow,",
" [\"piss\"] = colors.yellow,",
" [\"pee\"] = colors.yellow,",
" [\"lemon\"] = colors.yellow,",
" [\"cowardice\"] = colors.yellow,",
" [\"#dede6c\"] = colors.yellow,",
" ",
" [\"lime\"] = colors.lime,",
" [\"lightgreen\"] = colors.lime,",
" [\"light green\"] = colors.lime,",
" [\"slime\"] = colors.lime,",
" [\"radiation\"] = colors.lime,",
" [\"#7fcc19\"] = colors.lime,",
" ",
" [\"pink\"] = colors.pink,",
" [\"lightishred\"] = colors.pink,",
" [\"lightish red\"] = colors.pink,",
" [\"communist\"] = colors.pink,",
" [\"commie\"] = colors.pink,",
" [\"patrick\"] = colors.pink,",
" [\"#f2b2cc\"] = colors.pink,",
" ",
" [\"gray\"] = colors.gray,",
" [\"grey\"] = colors.gray,",
" [\"graey\"] = colors.gray,",
" [\"steel\"] = colors.gray,",
" [\"gunmetal\"] = colors.gray,",
" [\"#4c4c4c\"] = colors.gray,",
" ",
" [\"lightgray\"] = colors.lightGray,",
" [\"lightgrey\"] = colors.lightGray,",
" [\"light gray\"] = colors.lightGray,",
" [\"light grey\"] = colors.lightGray,",
" [\"iron\"] = colors.lightGray,",
" [\"#999999\"] = colors.lightGray,",
" ",
" [\"cyan\"] = colors.cyan,",
" [\"aqua\"] = colors.cyan,",
" [\"teal\"] = colors.cyan,",
" [\"seawater\"] = colors.cyan,",
" [\"brine\"] = colors.cyan,",
" [\"#4c99b2\"] = colors.cyan,",
" ",
" [\"purple\"] = colors.purple,",
" [\"purble\"] = colors.purple,",
" [\"obsidian\"] = colors.purple,",
" [\"diviner\"] = colors.purple,",
" [\"#b266e5\"] = colors.purple,",
" ",
" [\"blue\"] = colors.blue,",
" [\"blu\"] = colors.blue,",
" [\"azure\"] = colors.blue,",
" [\"sapphire\"] = colors.blue,",
" [\"lapis\"] = colors.blue,",
" [\"volnutt\"] = colors.blue,",
" [\"blueberry\"] = colors.blue,",
" [\"x\"] = colors.blue,",
" [\"megaman\"] = colors.blue,",
" [\"#3366bb\"] = colors.blue,",
" ",
" [\"brown\"] = colors.brown,",
" [\"shit\"] = colors.brown,",
" [\"dirt\"] = colors.brown,",
" [\"mud\"] = colors.brown,",
" [\"bricks\"] = colors.brown,",
" [\"#7f664c\"] = colors.brown,",
" ",
" [\"green\"] = colors.green,",
" [\"grass\"] = colors.green,",
" [\"verdant\"] = colors.green,",
" [\"leaf\"] = colors.green,",
" [\"#57a64e\"] = colors.green,",
" ",
" [\"red\"] = colors.red,",
" [\"crimson\"] = colors.red,",
" [\"vermillion\"] = colors.red,",
" [\"menstration\"] = colors.red,",
" [\"blood\"] = colors.red,",
" [\"marinara\"] = colors.red,",
" [\"zero\"] = colors.red,",
" [\"protoman\"] = colors.red,",
" [\"communism\"] = colors.red,",
" [\"#cc4c4c\"] = colors.red,",
" ",
" [\"black\"] = colors.black,",
" [\"dark\"] = colors.black,",
" [\"darkness\"] = colors.black,",
" [\"space\"] = colors.black,",
" [\"coal\"] = colors.black,",
" [\"onyx\"] = colors.black,",
" [\"#191919\"] = colors.black,",
"}",
"",
"local toblit = {",
" [0] = \" \",",
" [1] = \"0\",",
" [2] = \"1\",",
" [4] = \"2\",",
" [8] = \"3\",",
" [16] = \"4\",",
" [32] = \"5\",",
" [64] = \"6\",",
" [128] = \"7\",",
" [256] = \"8\",",
" [512] = \"9\",",
" [1024] = \"a\",",
" [2048] = \"b\",",
" [4096] = \"c\",",
" [8192] = \"d\",",
" [16384] = \"e\",",
" [32768] = \"f\"",
"}",
"local tocolors = {}",
"for k,v in pairs(toblit) do",
" tocolors[v] = k",
"end",
"",
"local codeNames = {",
" [\"r\"] = \"reset\", -- Sets either the text (&) or background (~) colors to their original color.",
" [\"{\"] = \"stopFormatting\", -- Toggles formatting text off",
" [\"}\"] = \"startFormatting\", -- Toggles formatting text on",
" [\"k\"] = \"krazy\" -- Makes the font kuh-razy!",
"}",
"",
"-- indicates which character should turn into which random &k character",
"local kraziez = {",
" [\"l\"] = {",
" \"!\",",
" \"l\",",
" \"1\",",
" \"|\",",
" \"i\",",
" \"I\",",
" \":\",",
" \";\",",
" },",
" [\"m\"] = {",
" \"M\",",
" \"W\",",
" \"w\",",
" \"m\",",
" \"X\",",
" \"N\",",
" \"_\",",
" \"%\",",
" \"@\",",
" },",
" [\"all\"] = {}",
"}",
"",
"for a = 1, #kraziez[\"l\"] do",
" kraziez[kraziez[\"l\"][a]] = kraziez[\"l\"]",
"end",
"for k,v in pairs(kraziez) do",
" for a = 1, #v do",
" kraziez[kraziez[k][a]] = v",
" end",
"end",
"",
"-- check if using older CC version, and omit special characters if it's too old to avoid crash",
"if tonumber(_CC_VERSION or 0) >= 1.76 then",
" for a = 1, 255 do",
" if (a ~= 32) and (a ~= 13) and (a ~= 10) then",
" kraziez[\"all\"][#kraziez[\"all\"]+1] = string.char(a)",
" end",
" end",
"else",
" for a = 33, 126 do",
" kraziez[\"all\"][#kraziez[\"all\"]+1] = string.char(a)",
" end",
"end",
"",
"local explode = function(div, str, replstr, includeDiv)",
" if (div == '') then",
" return false",
" end",
" local pos, arr = 0, {}",
" for st, sp in function() return string.find(str, div, pos, false) end do",
" tableinsert(arr, string.sub(replstr or str, pos, st - 1 + (includeDiv and #div or 0)))",
" pos = sp + 1",
" end",
" tableinsert(arr, string.sub(replstr or str, pos))",
" return arr",
"end",
"",
"local parseKrazy = function(c)",
" if kraziez[c] then",
" return kraziez[c][mathrandom(1, #kraziez[c])]",
" else",
" return kraziez.all[mathrandom(1, #kraziez.all)]",
" end",
"end",
"",
"-- my main man, the function that turns unformatted strings into formatted strings",
"local textToBlit = function(input, onlyString, initText, initBack, checkPos, useJSONformat)",
" if not input then return end",
" checkPos = checkPos or -1",
" initText, initBack = initText or toblit[term.getTextColor()], initBack or toblit[term.getBackgroundColor()]",
" tcode, bcode = \"&\", \"~\"",
" local cpos, cx = 0, 0",
" local skip, ignore, ex = nil, false, nil",
" local text, back, nex = initText, initBack, nil",
" ",
" local charOut, textOut, backOut = {}, {}, {}",
" local JSONoutput = {}",
" ",
" local krazy = false",
" local bold = false",
" local strikethrough = false",
" local underline = false",
" local italic = false",
" ",
" local codes = {}",
" codes[\"r\"] = function(prev)",
" if not ignore then",
" if prev == tcode then",
" text = initText",
" bold = false",
" strikethrough = false",
" underline = false",
" italic = false",
" elseif prev == bcode then",
" if useJSONformat then",
" return 0",
" else",
" back = initBack",
" end",
" end",
" krazy = false",
" else",
" return 0",
" end",
" end",
" codes[\"k\"] = function(prev)",
" if not ignore then",
" krazy = not krazy",
" else",
" return 0",
" end",
" end",
" codes[\"{\"] = function(prev)",
" if not ignore then",
" ignore = true",
" else",
" return 0",
" end",
" end",
" codes[\"}\"] = function(prev)",
" if ignore then",
" ignore = false",
" else",
" return 0",
" end",
" end",
" ",
" if useJSONformat then",
" codes[\"l\"] = function(prev)",
" bold = true",
" end",
" codes[\"m\"] = function(prev)",
" strikethrough = true",
" end",
" codes[\"n\"] = function(prev)",
" underline = true",
" end",
" codes[\"o\"] = function(prev)",
" italic = true",
" end",
" end",
" ",
" local sx, str = 0",
" input = stringgsub(input, \"(\\\\)(%d%d?%d?)\", function(cap, val)",
" if tonumber(val) < 256 then",
" cpos = cpos - #val",
" return string.char(val)",
" else",
" return cap..val",
" end",
" end)",
" ",
" local MCcolors = {",
" [\"0\"] = \"white\", ",
" [\"1\"] = \"gold\",",
" [\"2\"] = \"light_purple\",",
" [\"3\"] = \"aqua\",",
" [\"4\"] = \"yellow\",",
" [\"5\"] = \"green\",",
" [\"6\"] = \"light_purple\",",
" [\"7\"] = \"dark_gray\",",
" [\"8\"] = \"gray\",",
" [\"9\"] = \"dark_aqua\",",
" [\"a\"] = \"dark_purple\",",
" [\"b\"] = \"dark_blue\",",
" [\"c\"] = \"gold\",",
" [\"d\"] = \"dark_green\",",
" [\"e\"] = \"red\",",
" [\"f\"] = \"black\",",
" }",
" ",
" for cx = 1, #input do",
" str = stringsub(input,cx,cx)",
" if skip then",
" if tocolors[str] and not ignore then",
" if skip == tcode then",
" text = str == \" \" and initText or str",
" if sx < checkPos then",
" cpos = cpos - 2",
" end",
" elseif skip == bcode then",
" back = str == \" \" and initBack or str",
" if sx < checkPos then",
" cpos = cpos - 2",
" end",
" end",
" elseif codes[str] and not (ignore and str == \"{\") then",
" ex = codes[str](skip) or 0",
" sx = sx + ex",
" if sx < checkPos then",
" cpos = cpos - ex - 2",
" end",
" else",
" sx = sx + 1",
" if useJSONformat then",
" JSONoutput[sx] = {",
" text = (skip..str),",
" color = onlyString and \"f\" or MCcolors[text],",
" bold = (not onlyString) and bold,",
" italic = (not onlyString) and italic,",
" underline = (not onlyString) and underline,",
" obfuscated = (not onlyString) and krazy,",
" strikethrough = (not onlyString) and strikethrough",
" }",
" else",
" charOut[sx] = krazy and parseKrazy(prev..str) or (skip..str)",
" textOut[sx] = stringrep(text,2)",
" backOut[sx] = stringrep(back,2)",
" end",
" end",
" skip = nil",
" else",
" if (str == tcode or str == bcode) and (codes[stringsub(input, 1+cx, 1+cx)] or tocolors[stringsub(input,1+cx,1+cx)]) then",
" skip = str",
" else",
" sx = sx + 1",
" if useJSONformat then",
" JSONoutput[sx] = {",
" text = str,",
" color = onlyString and \"f\" or MCcolors[text],",
" bold = (not onlyString) and bold,",
" italic = (not onlyString) and italic,",
" underline = (not onlyString) and underline,",
" obfuscated = (not onlyString) and krazy,",
" strikethrough = (not onlyString) and strikethrough",
" }",
" else",
" charOut[sx] = krazy and parseKrazy(str) or str",
" textOut[sx] = text",
" backOut[sx] = back",
" end",
" end",
" end",
" end",
" if useJSONformat then",
" return textutils.serializeJSON(JSONoutput)",
" else",
" if onlyString then",
" return tableconcat(charOut), (checkPos > -1) and cpos or nil",
" else",
" return {tableconcat(charOut), tableconcat(textOut), tableconcat(backOut)}, (checkPos > -1) and cpos or nil",
" end",
" end",
"end",
"_G.textToBlit = textToBlit",
"",
"-- convoluted read function that renders color codes as they are written.",
"-- struggles with { codes, but hey, fuck you",
"local colorRead = function(maxLength, _history)",
" local output = \"\"",
" local history, _history = {}, _history or {}",
" for a = 1, #_history do",
" history[a] = _history[a]",
" end",
" history[#history+1] = \"\"",
" local hPos = #history",
" local cx, cy = termgetCursorPos()",
" local x, xscroll = 1, 1",
" local ctrlDown = false",
" termsetCursorBlink(true)",
" local evt, key, bout, xmod, timtam",
" while true do",
" termsetCursorPos(cx, cy)",
" bout, xmod = textToBlit(output, false, nil, nil, x)",
" for a = 1, #bout do",
" bout[a] = stringsub(bout[a], xscroll, xscroll + scr_x - cx)",
" end",
" termblit(unpack(bout))",
" termwrite((\" \"):rep(scr_x - cx))",
" termsetCursorPos(cx + x + xmod - xscroll, cy)",
" evt = {os.pullEvent()}",
" if evt[1] == \"char\" or evt[1] == \"paste\" then",
" output = (output:sub(1, x-1)..evt[2]..output:sub(x)):sub(1, maxLength or -1)",
" x = mathmin(x + #evt[2], #output+1)",
" elseif evt[1] == \"key\" then",
" key = evt[2]",
" if key == keys.leftCtrl then",
" ctrlDown = true",
" elseif key == keys.left then",
" x = mathmax(x - 1, 1)",
" elseif key == keys.right then",
" x = mathmin(x + 1, #output+1)",
" elseif key == keys.backspace then",
" if x > 1 then",
" repeat",
" output = output:sub(1,x-2)..output:sub(x)",
" x = x - 1",
" until output:sub(x-1,x-1) == \" \" or (not ctrlDown) or (x == 1)",
" end",
" elseif key == keys.delete then",
" if x < #output+1 then",
" repeat",
" output = output:sub(1,x-1)..output:sub(x+1)",
" until output:sub(x,x) == \" \" or (not ctrlDown) or (x == #output+1)",
" end",
" elseif key == keys.enter then",
" termsetCursorBlink(false)",
" return output",
" elseif key == keys.home then",
" x = 1",
" elseif key == keys[\"end\"] then",
" x = #output+1",
" elseif key == keys.up then",
" if history[hPos-1] then",
" hPos = hPos - 1",
" output = history[hPos]",
" x = #output+1",
" end",
" elseif key == keys.down then",
" if history[hPos+1] then",
" hPos = hPos + 1",
" output = history[hPos]",
" x = #output+1",
" end",
" end",
" elseif evt[1] == \"key_up\" then",
" if evt[2] == keys.leftCtrl then",
" ctrlDown = false",
" end",
" end",
" if hPos > 1 then",
" history[hPos] = output",
" end",
" if x+cx-xscroll+xmod > scr_x then",
" xscroll = x-(scr_x-cx)+xmod",
" elseif x-xscroll+xmod < 0 then",
" repeat",
" xscroll = xscroll - 1",
" until x-xscroll-xmod >= 0",
" end",
" xscroll = math.max(1, xscroll)",
" end",
"end",
"_G.colorRead = colorRead",
"",
"local checkValidName = function(_nayme)",
" local nayme = textToBlit(_nayme,true)",
" if type(nayme) ~= \"string\" then",
" return false",
" else",
" return (#nayme >= 2 and #nayme <= 32 and nayme:gsub(\" \",\"\") ~= \"\")",
" end",
"end",
"",
"if tArg[1] == \"update\" then",
" local res, message = updateEnchat(tArg[2] == \"beta\")",
" return print(message)",
"end",
"",
"local prettyClearScreen = function(start, stop)",
" termsetTextColor(colors.lightGray)",
" termsetBackgroundColor(colors.gray)",
" if _VERSION then",
" for y = start or 1, stop or scr_y do",
" termsetCursorPos(1,y)",
" if y == (start or 1) then",
" termwrite((\"‡\"):rep(scr_x))",
" elseif y == (stop or scr_y) then",
" termsetTextColor(colors.gray)",
" termsetBackgroundColor(colors.lightGray)",
" termwrite((\"‡\"):rep(scr_x))",
" else",
" termclearLine()",
" end",
" end",
" else",
" termclear()",
" end",
"end",
"",
"local cwrite = function(text, y)",
" local cx, cy = termgetCursorPos()",
" termsetCursorPos((scr_x/2) - math.ceil(#text/2), y or cy)",
" return write(text)",
"end",
"",
"local prettyCenterWrite = function(text, y)",
" local words = explode(\" \", text, nil, true)",
" local buff = \"\"",
" local lines = 0",
" for w = 1, #words do",
" if #buff + #words[w] > scr_x then",
" cwrite(buff, y + lines)",
" buff = \"\"",
" lines = lines + 1",
" end",
" buff = buff..words[w]",
" end",
" cwrite(buff, y + lines)",
" return lines",
"end",
"",
"local prettyPrompt = function(prompt, y, replchar, doColor)",
" local cy, cx = termgetCursorPos()",
" termsetBackgroundColor(colors.gray)",
" termsetTextColor(colors.white)",
" local yadj = 1 + prettyCenterWrite(prompt, y or cy)",
" termsetCursorPos(1, y + yadj)",
" termsetBackgroundColor(colors.lightGray)",
" termclearLine()",
" local output",
" if doColor then",
" output = colorRead()",
" else",
" output = read(replchar)",
" end",
" return output",
"end",
"",
"local fwrite = function(text)",
" local b = textToBlit(text)",
" return termblit(unpack(b))",
"end",
"",
"local cfwrite = function(text, y)",
" local cx, cy = termgetCursorPos()",
" termsetCursorPos((scr_x/2) - math.ceil(#textToBlit(text,true)/2), y or cy)",
" return fwrite(text)",
"end",
"",
"-- execution start!",
"",
"if not checkValidName(yourName) then -- not so fast, evildoers",
" yourName = nil",
"end",
"",
"local currentY = 2",
"",
"if not (yourName and encKey) then",
" prettyClearScreen()",
"end",
"",
"if not yourName then",
" cfwrite(\"&8~7Text = &, Background = ~\", scr_y-3)",
" cfwrite(\"&8~7&{Krazy = &k, Reset = &r\", scr_y-2)",
" cfwrite(\"&7~00~11~22~33~44~55~66&8~77&7~88~99~aa~bb~cc~dd~ee~ff\", scr_y-1)",
" yourName = prettyPrompt(\"Enter your name.\", currentY, nil, true)",
" if not checkValidName(yourName) then",
" while true do",
" yourName = prettyPrompt(\"That name isn't valid. Enter another.\", currentY, nil, true)",
" if checkValidName(yourName) then",
" break",
" end",
" end",
" end",
" currentY = currentY + 3",
"end",
"",
"if not encKey then",
" setEncKey(prettyPrompt(\"Enter an encryption key.\", currentY, \"*\"))",
" currentY = currentY + 3",
"end",
"",
"-- prevents terminating. it is reversed upon exit.",
"local oldePullEvent = os.pullEvent",
"os.pullEvent = os.pullEventRaw",
"",
"local bottomMessage = function(text)",
" termsetCursorPos(1,scr_y)",
" termsetTextColor(colors.gray)",
" termclearLine()",
" termwrite(text)",
"end",
"",
"loadSettings()",
"saveSettings()",
"",
"termsetBackgroundColor(colors.black)",
"termclear()",
"",
"local getAPI = function(apiname, apipath, apiurl, doDoFile, doScroll)",
" apipath = fs.combine(fs.combine(enchat.dataDir,\"api\"), apipath)",
" if (not fs.exists(apipath)) then",
" if doScroll then term.scroll(1) end",
" bottomMessage(apiname .. \" API not found! Downloading...\")",
" local prog = http.get(apiurl)",
" if not prog then",
" if doScroll then term.scroll(1) end",
" bottomMessage(\"Failed to download \" .. apiname .. \" API. Abort.\")",
" termsetCursorPos(1,1)",
" return",
" end",
" local file = fs.open(apipath,\"w\")",
" file.write(prog.readAll())",
" file.close()",
" end",
" if doDoFile then",
" return dofile(apipath)",
" else",
" os.loadAPI(apipath)",
" end",
" if not _ENV[fs.getName(apipath)] then",
" if doScroll then term.scroll(1) end",
" bottomMessage(\"Failed to load \" .. apiname .. \" API. Abort.\")",
" termsetCursorPos(1,1)",
" return",
" else",
" return _ENV[fs.getName(apipath)]",
" end",
"end",
"",
"local skynet, aes, bigfont",
"_G.skynet_CBOR_path = fs.combine(enchat.dataDir,\"/api/cbor\")",
"aes = getAPI(\"AES\", \"aes\", \"http://pastebin.com/raw/9E5UHiqv\", false, false)",
"skynet = getAPI(\"Skynet\", \"skynet\", \"https://raw.githubusercontent.com/osmarks/skynet/master/client.lua\", true, true)",
"bigfont = getAPI(\"BigFont\", \"bigfont\", \"https://pastebin.com/raw/3LfWxRWh\", false, true)",
"",
"if encKey and skynet then",
" bottomMessage(\"Connecting to Skynet...\")",
" local success = parallel.waitForAny(",
" function()",
" skynet.open(enchat.skynetPort)",
" end,",
" function()",
" sleep(3)",
" end",
" )",
" if success == 2 then",
" term.scroll(1)",
" bottomMessage(\"Failed to connect to skynet.\")",
" skynet = nil",
" sleep(0.5)",
" end",
"end",
"",
"local log = {} -- Records all sorts of data on text.",
"local renderlog = {} -- Only records straight terminal output. Generated from 'log'",
"local IDlog = {} -- Really only used with skynet, will prevent duplicate messages.",
"",
"local scroll = 0",
"local maxScroll = 0",
"",
"local getModem = function()",
" if enchat.ignoreModem then",
" return nil",
" else",
" local modems = {peripheral.find(\"modem\")}",
" return modems[1]",
" end",
"end",
"",
"local getChatbox = function()",
" if enchat.useChatbox then",
" if commands then -- oh baby, a command computer, now we're talkin'",
" -- mind you, you still need a chatbox to get chat input...",
" return {",
" say = function(text)",
" if enchat.useChatboxWhitelist then",
" for player,v in pairs(chatboxWhitelist) do",
" commands.tellraw(player, textToBlit(text, false, \"0\", \"f\", nil, true))",
" end",
" else",
" commands.tellraw(\"@a\", textToBlit(text, false, \"0\", \"f\", nil, true))",
" end",
" end,",
" tell = function(player, text)",
" commands.tellraw(player, textToBlit(text, false, \"0\", \"f\", nil, true))",
" end",
" }",
" else",
" local cb = peripheral.find(\"chat_box\")",
" if cb then",
" if cb.setName then -- Computronics",
" cb.setName(yourName)",
" return {",
" say = cb.say,",
" tell = cb.say -- why is there no tell command???",
" }",
" else -- whatever whackjob mod SwitchCraft uses I forget",
" return {",
" say = function(text, block)",
" if CHATBOX_SAFEMODE then",
" cb.tell(CHATBOX_SAFEMODE, text, yourName)",
" else",
" if enchat.useChatboxWhitelist then",
" for player,v in pairs(chatboxWhitelist) do",
" if player ~= block then",
" cb.tell(player, text, yourName)",
" end",
" end",
" else",
" local players = cb.getPlayerList()",
" for i = 1, #players do",
" if players[i] ~= block then",
" cb.tell(players[i], text, yourName)",
" end",
" end",
" end",
" end",
" end,",
" tell = function(user, text)",
" cb.tell(user, text, yourName)",
" end",
" }",
" end",
" else",
" return nil",
" end",
" end",
" else",
" return nil",
" end",
"end",
"",
"local modem = getModem()",
"local chatbox = getChatbox()",
"",
"if (not modem) and (not enchat.ignoreModem) then",
" if ccemux and (not enchat.ignoreModem) then",
" ccemux.attach(\"top\", \"wireless_modem\")",
" modem = getModem()",
" elseif not skynet then",
" error(\"You should get a modem.\")",
" end",
"end",
"",
"if modem then modem.open(enchat.port) end",
"",
"local modemTransmit = function(freq, repfreq, message)",
" if modem then",
" modem.transmit(freq, repfreq, message)",
" end",
"end",
"",
"local encrite = function(input) -- standardized encryption function",
" if not input then return input end",
" return aes.encrypt(encKey, textutilsserialize(input))",
"end",
"",
"local decrite = function(input) -- redundant comments cause tuberculosis",
" if not input then return input end",
" return textutilsunserialize(aes.decrypt(encKey, input) or \"\")",
"end",
"",
"local dab = function(func, ...) -- \"do and back\", not...never mind",
" local x, y = termgetCursorPos()",
" local b, t = termgetBackgroundColor(), termgetTextColor()",
" local output = {func(...)}",
" termsetCursorPos(x,y)",
" termsetTextColor(t)",
" termsetBackgroundColor(b)",
" return unpack(output)",
"end",
"",
"local splitStr = function(str, maxLength)",
" local output = {}",
" for l = 1, #str, maxLength do",
" output[#output+1] = str:sub(l,l+maxLength+-1)",
" end",
" return output",
"end",
"",
"local splitStrTbl = function(tbl, maxLength)",
" local output, tline = {}",
" for w = 1, #tbl do",
" tline = splitStr(tbl[w], maxLength)",
" for t = 1, #tline do",
" output[#output+1] = tline[t]",
" end",
" end",
" return output",
"end",
"",
"-- same as term.blit, but wraps by-word.",
"local blitWrap = function(char, text, back, noWrite) -- where ALL of the onscreen wrapping is done",
" local cWords = splitStrTbl(explode(\" \",char,nil, true), scr_x)",
" local tWords = splitStrTbl(explode(\" \",char,text,true), scr_x)",
" local bWords = splitStrTbl(explode(\" \",char,back,true), scr_x)",
"",
" local ox,oy = termgetCursorPos()",
" local cx,cy,ty = ox,oy,1",
" local output = {}",
" local length = 0",
" local maxLength = 0",
" for a = 1, #cWords do",
" length = length + #cWords[a]",
" maxLength = mathmax(maxLength, length)",
" if ((cx + #cWords[a]) > scr_x) then",
" cx = 1",
" length = 0",
" if (cy == scr_y) then",
" term.scroll(1)",
" end",
" cy = mathmin(cy+1, scr_y)",
" ty = ty + 1",
" end",
" if not noWrite then",
" termsetCursorPos(cx,cy)",
" termblit(cWords[a],tWords[a],bWords[a])",
" end",
" cx = cx + #cWords[a]",
" output[ty] = output[ty] or {\"\",\"\",\"\"}",
" output[ty][1] = output[ty][1]..cWords[a]",
" output[ty][2] = output[ty][2]..tWords[a]",
" output[ty][3] = output[ty][3]..bWords[a]",
" end",
" return output, maxLength",
"end",
"",
"-- simple picture drawing function, for /picto",
"local pictochat = function(xsize, ysize)",
" local output = {{},{},{}}",
" local maxWidth, minMargin = 0, math.huge",
" for y = 1, ysize do",
" output[1][y] = {}",
" output[2][y] = {}",
" output[3][y] = {}",
" for x = 1, xsize do",
" output[1][y][x] = \" \"",
" output[2][y][x] = \" \"",
" output[3][y][x] = \" \"",
" end",
" end",
"",
" termsetBackgroundColor(colors.gray)",
" termsetTextColor(colors.black)",
" for y = 1, scr_y do",
" termsetCursorPos(1, y)",
" termwrite((\"/\"):rep(scr_x))",
" end",
" cwrite(\" [ENTER] to finish. \", scr_y)",
" cwrite(\"Push a key to change char.\", scr_y-1)",
"",
" local cx, cy = math.floor((scr_x/2)-(xsize/2)), math.floor((scr_y/2)-(ysize/2))",
"",
" local allCols = \"0123456789abcdef\"",
" local tPos, bPos = 16, 1",
" local char, text, back = \" \", allCols:sub(tPos,tPos), allCols:sub(bPos,bPos)",
"",
" local render = function()",
" termsetTextColor(colors.white)",
" termsetBackgroundColor(colors.black)",
" local mx, my",
" for y = 1, ysize do",
" for x = 1, xsize do",
" mx, my = x+cx+-1, y+cy+-1",
" termsetCursorPos(mx,my)",
" termblit(output[1][y][x], output[2][y][x], output[3][y][x])",
" end",
" end",
" termsetCursorPos((scr_x/2)-5,ysize+cy+1)",
" termwrite(\"Char = '\")",
" termblit(char, text, back)",
" termwrite(\"'\")",
" end",
" local evt, butt, mx, my",
" local isShiftDown = false",
"",
" render()",
"",
" while true do",
" evt = {os.pullEvent()}",
" if evt[1] == \"mouse_click\" or evt[1] == \"mouse_drag\" then",
" butt, mx, my = evt[2], evt[3]-cx+1, evt[4]-cy+1",
" if mx >= 1 and mx <= xsize and my >= 1 and my <= ysize then",
" if butt == 1 then",
" output[1][my][mx] = char",
" output[2][my][mx] = text",
" output[3][my][mx] = back",
" elseif butt == 2 then",
" output[1][my][mx] = \" \"",
" output[2][my][mx] = \" \"",
" output[3][my][mx] = \" \"",
" end",
" render()",
" end",
" elseif evt[1] == \"mouse_scroll\" then",
" local oldTpos, oldBpos = tPos, bPos",
" if isShiftDown then",
" tPos = mathmax(1, mathmin(16, tPos + evt[2]))",
" else",
" bPos = mathmax(1, mathmin(16, bPos + evt[2]))",
" end",
" text, back = stringsub(allCols,tPos,tPos), stringsub(allCols,bPos,bPos)",
" if oldTpos ~= tPos or oldBpos ~= bPos then",
" render()",
" end",
" elseif evt[1] == \"key\" then",
" if evt[2] == keys.enter then",
" for y = 1, ysize do",
" output[1][y] = table.concat(output[1][y])",
" output[2][y] = table.concat(output[2][y])",
" output[3][y] = table.concat(output[3][y])",
" maxWidth = math.max(maxWidth, #stringgsub(output[3][y], \" +$\", \"\"))",
" minMargin = math.min(minMargin, output[3][y]:find(\"[^ ]\") or math.huge)",
" end",
" --error(minMargin)",
" local croppedOutput = {}",
" local touched = false",
" local crY = 0",
" for a = 1, ysize do",
" if output[1][1] == (\" \"):rep(xsize) and output[3][1] == (\" \"):rep(xsize) then",
" tableremove(output[1],1)",
" tableremove(output[2],1)",
" tableremove(output[3],1)",
" else",
" for y = #output[1], 1, -1 do",
" if output[1][y] == (\" \"):rep(xsize) and output[3][y] == (\" \"):rep(xsize) then",
" tableremove(output[1],y)",
" tableremove(output[2],y)",
" tableremove(output[3],y)",
" else",
" break",
" end",
" end",
" break",
" end",
" end",
" for y = 1, #output[1] do",
" output[1][y] = output[1][y]:sub(minMargin, maxWidth)",
" output[2][y] = output[2][y]:sub(minMargin, maxWidth)",
" output[3][y] = output[3][y]:sub(minMargin, maxWidth)",
" end",
" return output",
" elseif evt[2] == keys.leftShift then",
" isShiftDown = true",
" elseif evt[2] == keys.left or evt[2] == keys.right then",
" local oldTpos, oldBpos = tPos, bPos",
" if isShiftDown then",
" tPos = mathmax(1, mathmin(16, tPos + (evt[2] == keys.right and 1 or -1)))",
" else",
" bPos = mathmax(1, mathmin(16, bPos + (evt[2] == keys.right and 1 or -1)))",
" end",
" text, back = allCols:sub(tPos,tPos), allCols:sub(bPos,bPos)",
" if oldTpos ~= tPos or oldBpos ~= bPos then",
" render()",
" end",
" end",
" elseif evt[1] == \"key_up\" then",
" if evt[2] == keys.leftShift then",
" isShiftDown = false",
" end",
" elseif evt[1] == \"char\" then",
" if char ~= evt[2] then",
" char = evt[2]",
" render()",
" end",
" end",
" end",
"end",
"",
"-- notifications will only appear if you have plethora's neural connector and overlay glasses on your person",
"",
"local notif = {}",
"notif.alpha = 248",
"notif.height = 10",
"notif.width = 6",
"notif.time = 40",
"notif.wrapX = 350",
"notif.maxNotifs = 15",
"local nList = {}",
"local colorTranslate = {",
" [\" \"] = {240, 240, 240},",
" [\"0\"] = {240, 240, 240},",
" [\"1\"] = {242, 178, 51 },",
" [\"2\"] = {229, 127, 216},",
" [\"3\"] = {153, 178, 242},",
" [\"4\"] = {222, 222, 108},",
" [\"5\"] = {127, 204, 25 },",
" [\"6\"] = {242, 178, 204},",
" [\"7\"] = {76, 76, 76 },",
" [\"8\"] = {153, 153, 153},",
" [\"9\"] = {76, 153, 178},",
" [\"a\"] = {178, 102, 229},",
" [\"b\"] = {51, 102, 204},",
" [\"c\"] = {127, 102, 76 },",
" [\"d\"] = {87, 166, 78 },",
" [\"e\"] = {204, 76, 76 },",
" [\"f\"] = {25, 25, 25 }",
"}",
"local interface, canvas = peripheral.find(\"neuralInterface\")",
"if interface then",
" if interface.canvas then",
" canvas = interface.canvas()",
" notif.newNotification = function(char, text, back, time)",
" if #nList > notif.maxNotifs then",
" tableremove(nList, 1)",
" end",
" nList[#nList+1] = {char,text,back,time,1} -- the last one is the alpha multiplier",
" end",
" notif.displayNotifications = function(doCountDown)",
" local adjList = {",
" [\"i\"] = -4,",
" [\"l\"] = -3,",
" [\"I\"] = -1,",
" [\"t\"] = -2,",
" [\"k\"] = -1,",
" [\"!\"] = -4,",
" [\"|\"] = -4,",
" [\".\"] = -4,",
" [\",\"] = -4,",
" [\":\"] = -4,",
" [\";\"] = -4,",
" [\"f\"] = -1,",
" [\"'\"] = -3,",
" [\"\\\"\"] = -1,",
" [\"<\"] = -1,",
" [\">\"] = -1,",
" }",
" local drawEdgeLine = function(y,alpha)",
" local l = canvas.addRectangle(notif.wrapX, 1+(y-1)*notif.height, 1, notif.height)",
" l.setColor(unpack(colorTranslate[\"0\"]))",
" l.setAlpha(alpha / 2)",
" end",
" local getWordWidth = function(str)",
" local output = 0",
" for a = 1, #str do",
" output = output + notif.width + (adjList[stringsub(str,a,a)] or 0)",
" end",
" return output",
" end",
" canvas.clear()",
" local xadj, charadj, wordadj, t, r",
" local x, y, words, txtwords, bgwords = 0, 0",
" for n = 1, mathmin(#nList, notif.maxNotifs) do",
" xadj, charadj = 0, 0",
" y = y + 1",
" x = 0",
" words = explode(\" \",nList[n][1],nil,true)",
" txtwords = explode(\" \",nList[n][1],nList[n][2],true)",
" bgwords = explode(\" \",nList[n][1],nList[n][3],true)",
" local char, text, back",
" local currentX = 0",
" for w = 1, #words do",
" char = words[w]",
" text = txtwords[w]",
" back = bgwords[w]",
" if currentX + getWordWidth(char) > notif.wrapX then",
" y = y + 1",
" x = 2",
" xadj = 0",
" currentX = x * notif.width",
" end",
" for cx = 1, #char do",
" x = x + 1",
" charadj = (adjList[stringsub(char,cx,cx)] or 0)",
" r = canvas.addRectangle(xadj+1+(x-1)*notif.width, 1+(y-1)*notif.height, charadj+notif.width, notif.height)",
" if stringsub(back,cx,cx) ~= \" \" then",
" r.setAlpha(notif.alpha * nList[n][5])",
" r.setColor(unpack(colorTranslate[stringsub(back,cx,cx)]))",
" else",
" r.setAlpha(100 * nList[n][5])",
" r.setColor(unpack(colorTranslate[\"7\"]))",
" end",
" drawEdgeLine(y,notif.alpha * nList[n][5])",
" t = canvas.addText({xadj+1+(x-1)*notif.width,2+(y-1)*notif.height}, stringsub(char,cx,cx))",
" t.setAlpha(notif.alpha * nList[n][5])",
" t.setColor(unpack(colorTranslate[stringsub(text,cx,cx)]))",
" xadj = xadj + charadj",
" currentX = currentX + charadj+notif.width",
" end",
" end",
" end",
" for n = mathmin(#nList, notif.maxNotifs), 1, -1 do",
" if doCountDown then",
" if nList[n][4] > 1 then",
" nList[n][4] = nList[n][4] - 1",
" else",
" if nList[n][5] > 0 then",
" while true do",
" nList[n][5] = mathmax(nList[n][5] - 0.2, 0)",
" notif.displayNotifications(false)",
" if nList[n][5] == 0 then break else sleep(0.05) end",
" end",
" end",
" tableremove(nList,n)",
" end",
" end",
" end",
" end",
" end",
"end",
"",
"local darkerCols = {",
" [\"0\"] = \"8\",",
" [\"1\"] = \"c\",",
" [\"2\"] = \"a\",",
" [\"3\"] = \"b\",",
" [\"4\"] = \"1\",",
" [\"5\"] = \"d\",",
" [\"6\"] = \"2\",",
" [\"7\"] = \"f\",",
" [\"8\"] = \"7\",",
" [\"9\"] = \"b\",",
" [\"a\"] = \"7\",",
" [\"b\"] = \"7\",",
" [\"c\"] = \"f\",",
" [\"d\"] = \"7\",",
" [\"e\"] = \"7\",",
" [\"f\"] = \"f\"",
"}",
"",
"-- used for regular chat. they can be disabled if you hate fun",
"local animations = {",
" slideFromLeft = function(char, text, back, frame, maxFrame, length)",
" return {",
" stringsub(char, (length or #char) - ((frame/maxFrame)*(length or #char))),",
" stringsub(text, (length or #text) - ((frame/maxFrame)*(length or #text))),",
" stringsub(back, (length or #back) - ((frame/maxFrame)*(length or #back)))",
" }",
" end,",
" fadeIn = function(char, text, back, frame, maxFrame, length)",
" -- a good example:",
" -- &1what &2in &3the &4world &5are &6you &7doing &8in &9my &aswamp",
" for i = 1, 3 - math.ceil(frame/maxFrame * 3) do",
" text = stringgsub(text, \".\", darkerCols)",
" end",
" return {",
" char,",
" text,",
" back",
" }",
" end,",
" flash = function(char, text, back, frame, maxFrame, length)",
" local t = palette.txt",
" if frame ~= maxFrame then",
" t = (frame % 2 == 0) and t or palette.bg",
" end",
" return {",
" char,",
" toblit[t]:rep(#text),",
" (frame % 2 == 0) and back or (\" \"):rep(#back)",
" }",
" end,",
" none = function(char, text, back, frame, maxFrame, length)",
" return {",
" char,",
" text,",
" back",
" }",
" end",
"}",
"",
"local inAnimate = function(animType, buff, frame, maxFrame, length)",
" local char, text, back = buff[1], buff[2], buff[3]",
" if enchatSettings.doAnimate and (frame >= 0) and (maxFrame > 0) then",
" return animations[animType or \"slideFromleft\"](char, text, back, frame, maxFrame, length)",
" else",
" return {char,text,back}",
" end",
"end",
"",
"local genRenderLog = function()",
" local buff, prebuff, maxLength",
" local scrollToBottom = scroll == maxScroll",
" renderlog = {}",
" for a = 1, #log do",
" termsetCursorPos(1,1)",
" if UIconf.nameDecolor then",
" local dcName = textToBlit(table.concat({log[a].prefix,log[a].name,log[a].suffix}), true, toblit[palette.txt], toblit[palette.bg])",
" local dcMessage = textToBlit(log[a].message, false, toblit[palette.txt], toblit[palette.bg])",
" prebuff = {",
" dcName..dcMessage[1],",
" toblit[palette.chevron]:rep(#dcName)..dcMessage[2],",
" toblit[palette.bg]:rep(#dcName)..dcMessage[3]",
" }",
" else",
" prebuff = textToBlit(table.concat(",
" {log[a].prefix, \"&}&r~r\", log[a].name, \"&}&r~r\", log[a].suffix, \"&}&r~r\", log[a].message}",
" ), false, toblit[palette.txt], toblit[palette.bg])",
" end",
" if (log[a].frame == 0) and (canvas and enchatSettings.doNotif) then",
" if not (log[a].name == \"\" and log[a].message == \" \") then",
" notif.newNotification(prebuff[1],prebuff[2],prebuff[3],notif.time * 4)",
" end",
" end",
" if log[a].maxFrame == true then",
" log[a].maxFrame = math.floor(mathmin(#prebuff[1], scr_x) / enchatSettings.animDiv)",
" end",
" if log[a].ignoreWrap then",
" buff, maxLength = {prebuff}, mathmin(#prebuff[1], scr_x)",
" else",
" buff, maxLength = blitWrap(prebuff[1], prebuff[2], prebuff[3], true)",
" end",
" -- repeat every line in multiline entries",
" for l = 1, #buff do",
" -- holy shit, two animations, lookit mr. roxas over here",
" if log[a].animType then",
" renderlog[#renderlog + 1] = inAnimate(log[a].animType, buff[l], log[a].frame, log[a].maxFrame, maxLength)",
" else",
" renderlog[#renderlog + 1] = inAnimate(\"fadeIn\", inAnimate(\"slideFromLeft\", buff[l], log[a].frame, log[a].maxFrame, maxLength), log[a].frame, log[a].maxFrame, maxLength)",
" end",
" end",
" if (log[a].frame < log[a].maxFrame) and log[a].frame >= 0 then",
" log[a].frame = log[a].frame + 1",
" else",
" log[a].frame = -1",
" end",
" end",
" maxScroll = mathmax(0, #renderlog - (scr_y - 2))",
" if scrollToBottom then",
" scroll = maxScroll",
" end",
"end",
"",
"-- there is probably a much better way of doing this, but I don't care at the moment",
"local tsv = function(visible)",
" if term.current().setVisible and enchatSettings.useSetVisible then",
" return term.current().setVisible(visible)",
" end",
"end",
"",
"local renderChat = function(doScrollBackUp)",
" tsv(false)",
" termsetCursorBlink(false)",
" genRenderLog(log)",
" local ry",
" termsetBackgroundColor(palette.bg)",
" for y = UIconf.chatlogTop, (scr_y-UIconf.promptY) - 1 do",
" ry = (y + scroll - (UIconf.chatlogTop - 1))",
" termsetCursorPos(1,y)",
" termclearLine()",
" if renderlog[ry] then",
" termblit(unpack(renderlog[ry]))",
" end",
" end",
" if UIconf.promptY ~= 0 then",
" termsetCursorPos(1,scr_y)",
" termsetTextColor(palette.scrollMeter)",
" termclearLine()",
" termwrite(scroll..\" / \"..maxScroll..\" \")",
" end",
"",
" local _title = UIconf.title:gsub(\"YOURNAME\", yourName..\"&}&r~r\"):gsub(\"ENCKEY\", encKey..\"&}&r~r\"):gsub(\"PORT\", tostring(enchat.port))",
" if UIconf.doTitle then",
" termsetTextColor(palette.title)",
" term.setBackgroundColor(palette.titlebg)",
" if UIconf.nameDecolor then",
" if UIconf.centerTitle then",
" cwrite((\" \"):rep(scr_x)..textToBlit(_title, true)..(\" \"):rep(scr_x), UIconf.titleY or 1)",
" else",
" termsetCursorPos(1, UIconf.titleY or 1)",
" termwrite(textToBlit(_title, true)..(\" \"):rep(scr_x))",
" end",
" else",
" local blTitle = textToBlit(_title)",
" termsetCursorPos(UIconf.centerTitle and ((scr_x/2) - math.ceil(#blTitle[1]/2)) or 1, UIconf.titleY or 1)",
" termclearLine()",
" termblit(unpack(blTitle))",
" end",
" end",
" termsetCursorBlink(true)",
" tsv(true)",
"end",
"",
"local logadd = function(name, message, animType, maxFrame, ignoreWrap)",
" log[#log + 1] = {",
" prefix = name and UIconf.prefix or \"\",",
" suffix = name and UIconf.suffix or \"\",",
" name = name or \"\",",
" message = message or \" \",",
" ignoreWrap = ignoreWrap,",
" frame = 0,",
" maxFrame = maxFrame or true,",
" animType = animType",
" }",
"end",
"",
"local logaddTable = function(name, message, animType, maxFrame, ignoreWrap)",
" if type(message) == \"table\" and type(name) == \"string\" then",
" if #message > 0 then",
" local isGood = true",
" for l = 1, #message do",
" if type(message[l]) ~= \"string\" then",
" isGood = false",
" break",
" end",
" end",
" if isGood then",
" logadd(name,message[1],animType,maxFrame,ignoreWrap)",
" for l = 2, #message do",
" logadd(nil,message[l],animType,maxFrame,ignoreWrap)",
" end",
" end",
" end",
" end",
"end",
"",
"local makeRandomString = function(length)",
" local output = \"\"",
" for a = 1, length do",
" output = output .. string.char(math.random(1,255))",
" end",
" return output",
"end",
"",
"local enchatSend = function(name, message, doLog, animType, maxFrame, crying, recipient, ignoreWrap)",
" if doLog then",
" if type(message) == \"string\" then",
" logadd(name, message, animType, maxFrame, ignoreWrap)",
" else",
" logaddTable(name, message, animType, maxFrame, ignoreWrap)",
" end",
" end",
" local messageID = makeRandomString(64)",
" local outmsg = encrite({",
" name = name,",
" message = message,",
" animType = animType,",
" maxFrame = maxFrame,",
" messageID = messageID,",
" recipient = recipient,",
" ignoreWrap = ignoreWrap,",
" cry = crying",
" })",
" IDlog[messageID] = true",
" if not enchat.ignoreModem then modemTransmit(enchat.port, enchat.port, outmsg) end",
" if skynet and enchatSettings.useSkynet then",
" skynet.send(enchat.skynetPort, outmsg)",
" end",
"end",
"",
"local cryOut = function(name, crying)",
" enchatSend(name, nil, false, nil, nil, crying)",
"end",
"",
"local getPictureFile = function(path) -- ONLY NFP or NFT, fuck BLT",
" if not fs.exists(path) then",
" return false, \"No such image.\"",
" else",
" local file = fs.open(path,\"r\")",
" local content = file.readAll()",
" file.close()",
" local output",
" if content:find(\"\\31\") and content:find(\"\\30\") then",
" output = explode(\"\\n\",content:gsub(\"\\31\",\"&\"):gsub(\"\\30\",\"~\"),nil,false)",
" else",
" if content:lower():gsub(\"[0123456789abcdef\\n ]\",\"\") ~= \"\" then",
" return false, \"Invalid image.\"",
" else",
" output = explode(\"\\n\",content:gsub(\"[^\\n]\",\"~%1 \"),nil,false)",
" end",
" end",
" return output",
" end",
"end",
"",
"local getTableLength = function(tbl)",
" local output = 0",
" for k,v in pairs(tbl) do",
" output = output + 1",
" end",
" return output",
"end",
"",
"local userCryList = {}",
"",
"local commandInit = \"/\"",
"local commands = {}",
"-- Commands only have one argument, being a single string.",
"-- Separate arguments can be extrapolated with the explode() function.",
"commands.about = function()",
" if enchatSettings.extraNewline then",
" logadd(nil,nil)",
" end",
" logadd(nil,\"Enchat \"..enchat.version..\" by LDDestroier.\")",
" logadd(nil,\"'Encrypted, decentralized, &1c&2o&3l&4o&5r&6i&7z&8e&9d&r chat program'\")",
" logadd(nil,\"Made in 2018, out of gum and procrastination.\")",
" logadd(nil,nil)",
" logadd(nil,\"AES Lua implementation made by SquidDev.\")",
" logadd(nil,\"'Skynet' (enables HTTP chat) belongs to gollark (osmarks).\")",
"end",
"commands.exit = function()",
" enchatSend(\"*\", \"'\"..yourName..\"&}&r~r' buggered off. (disconnect)\")",
" return \"exit\"",
"end",
"commands.me = function(msg)",
" if enchatSettings.extraNewline then",
" logadd(nil,nil)",
" end",
" if msg then",
" enchatSend(\"&2*\", yourName..\"~r&2 \"..msg, true)",
" else",
" logadd(\"*\",commandInit..\"me [message]\")",
" end",
"end",
"commands.tron = function()",
" local url = \"https://raw.githubusercontent.com/LDDestroier/CC/master/tron.lua\"",
" local prog, contents = http.get(url)",
" if prog then",
" enchatSend(\"*\", yourName .. \"&}&r~r has started a game of TRON.\")",
" contents = prog.readAll()",
" pauseRendering = true",
" prog = load(contents, nil, nil, _ENV)(enchatSettings.useSkynet and \"skynet\", \"quick\", yourName)",
" else",
" logadd(\"*\", \"Could not download TRON.\")",
" end",
" pauseRendering = false",
" doRender = true",
"end",
"commands.colors = function()",
" if enchatSettings.extraNewline then",
" logadd(nil,nil)",
" end",
" logadd(\"*\", \"&{Color codes: (use & or ~)&}\")",
" logadd(nil, \" &7~11~22~33~44~55~66~7&87~8&78~99~aa~bb~cc~dd~ee~ff\")",
" logadd(nil, \" &{Reset text/BG with &r and ~r.&}\")",
" logadd(nil, \" &{Use &k for krazy text.&}\")",
"end",
"commands.update = function()",
" local res, message = updateEnchat()",
" if res then",
" enchatSend(\"*\",yourName..\"&}&r~r has updated and exited.\")",
" termsetBackgroundColor(colors.black)",
" termsetTextColor(colors.white)",
" termclear()",
" termsetCursorPos(1,1)",
" print(message)",
" return \"exit\"",
" else",
" logadd(\"*\", res)",
" end",
"end",
"commands.picto = function(filename)",
" local image, output, res",
" local isEmpty",
" if filename then",
" output, res = getPictureFile(filename)",
" if not output then",
" logadd(\"*\",res)",
" logadd(nil,nil)",
" return",
" else",
" tableinsert(output,1,\"\")",
" end",
" else",
" isEmpty = true",
" output = {\"\"}",
" pauseRendering = true",
" local image = pictochat(26,11)",
" pauseRendering = false",
" for y = 1, #image[1] do",
" output[#output+1] = \"\"",
" for x = 1, #image[1][1] do",
" output[#output] = table.concat({",
" output[#output],",
" \"&\",",
" image[2][y]:sub(x,x),",
" \"~\",",
" image[3][y]:sub(x,x),",
" image[1][y]:sub(x,x)",
" })",
" isEmpty = isEmpty and (image[1][y]:sub(x,x) == \" \" and image[3][y]:sub(x,x) == \" \")",
" end",
" end",
" end",
" if not isEmpty then",
" enchatSend(yourName,output,true,\"slideFromLeft\",nil,nil,nil,true)",
" end",
"end",
"commands.list = function()",
" userCryList = {}",
" local tim = os.startTimer(0.5)",
" cryOut(yourName, true)",
" while true do",
" local evt = {os.pullEvent()}",
" if evt[1] == \"timer\" then",
" if evt[2] == tim then",
" break",
" end",
" end",
" end",
" if enchatSettings.extraNewline then",
" logadd(nil,nil)",
" end",
" if getTableLength(userCryList) == 0 then",
" logadd(nil,\"Nobody's there.\")",
" else",
" for k,v in pairs(userCryList) do",
" logadd(nil,\"+'\"..k..\"'\")",
" end",
" end",
"end",
"commands.nick = function(newName)",
" if enchatSettings.extraNewline then",
" logadd(nil,nil)",
" end",
" if newName then",
" if checkValidName(newName) then",
" if newName == yourName then",
" logadd(\"*\",\"But you're already called that!\")",
" else",
" enchatSend(\"*\",\"'\"..yourName..\"&}&r~r' is now known as '\"..newName..\"&}&r~r'.\", true)",
" yourName = newName",
" end",
" else",
" if #newName < 2 then",
" logadd(\"*\",\"That name is too damned small.\")",
" elseif #newName > 32 then",
" logadd(\"*\",\"Woah there, that name is too large.\")",
" end",
" end",
" else",
" logadd(\"*\",commandInit..\"nick [newName]\")",
" end",
"end",
"commands.whoami = function(now)",
" if enchatSettings.extraNewline then",
" logadd(nil,nil)",
" end",
" if now == \"now\" then",
" logadd(\"*\",\"You are still '\"..yourName..\"&}&r~r'!\")",
" else",
" logadd(\"*\",\"You are '\"..yourName..\"&}&r~r'!\")",
" end",
"end",
"commands.key = function(newKey)",
" if enchatSettings.extraNewline then",
" logadd(nil,nil)",
" end",
" if newKey then",
" if newKey ~= encKey then",
" enchatSend(\"*\", \"'\"..yourName..\"&}&r~r' buggered off. (keychange)\", false)",
" setEncKey(newKey)",
" logadd(\"*\", \"Key changed to '\"..encKey..\"&}&r~r'.\")",
" enchatSend(\"*\", \"'\"..yourName..\"&}&r~r' has moseyed on over.\", false)",
" else",
" logadd(\"*\", \"That's already the key, though.\")",
" end",
" else",
" logadd(\"*\",\"Key = '\"..encKey..\"&}&r~r'\")",
" logadd(\"*\",\"Channel = '\"..enchat.port..\"'\")",
" end",
"end",
"commands.shrug = function(face)",
" if enchatSettings.extraNewline then",
" logadd(nil,nil)",
" end",
" enchatSend(yourName, \"¯\\\\_\"..(face and (\"(\"..face..\")\") or \"\\2\")..\"_/¯\", true)",
"end",
"commands.asay = function(_argument)",
" local sPoint = (_argument or \"\"):find(\" \")",
" if enchatSettings.extraNewline then",
" logadd(nil,nil)",
" end",
" if not sPoint then",
" logadd(\"*\",\"Animation types:\")",
" for k,v in pairs(animations) do",
" logadd(nil,\" '\"..k..\"'\")",
" end",
" else",
" local animType = _argument:sub(1,sPoint-1)",
" local message = _argument:sub(sPoint+1)",
" local animFrameMod = {",
" flash = 8,",
" fadeIn = 4,",
" }",
" if animations[animType] then",
" if textToBlit(message,true):gsub(\" \",\"\") ~= \"\" then",
" enchatSend(yourName, message, true, animType, animFrameMod[animType])",
" else",
" logadd(\"*\",\"That message is no good.\")",
" end",
" else",
" logadd(\"*\",\"Invalid animation type.\")",
" end",
" end",
"end",
"commands.big = function(_argument)",
" local sPoint = (_argument or \"\"):find(\" \")",
" if enchatSettings.extraNewline then",
" logadd(nil,nil)",
" end",
" if not sPoint then",
" logadd(\"*\",commandInit .. \"big <size> <text>\")",
" else",
" local fontSize = tonumber(_argument:sub(1,sPoint-1))",
" local message = _argument:sub(sPoint+1)",
" if not fontSize then",
" logadd(\"*\",\"Size must be number between 1 and 3.\")",
" elseif fontSize < 0 or fontSize > 3 then",
" logadd(\"*\",\"Size must be number between 1 and 3.\")",
" else",
" fontSize = math.floor(.5+fontSize)",
" local tOutput",
" if fontSize > 0 then",
" message = textToBlit(message, false, \"0\", \"f\")",
" local output = {{},{},{}}",
" local x, y = 1, 1",
" local char",
" for i = 1, #message[1] do",
" char = bigfont.makeBlittleText(",
" fontSize,",
" stringsub(message[1],i,i),",
" stringsub(message[2],i,i),",
" stringsub(message[3],i,i)",
" )",
" x = x + char.width",
" if x >= scr_x then",
" y = y + char.height",
" x = char.width",
" end",
" for charY = 1, char.height do",
" output[1][y+charY-1] = (output[1][y+charY-1] or \" \") .. char[1][charY]",
" output[2][y+charY-1] = (output[2][y+charY-1] or \" \") .. char[2][charY]",
" output[3][y+charY-1] = (output[3][y+charY-1] or \" \") .. char[3][charY]",
" end",
" end",
" tOutput = {\"\"}",
" for y = 1, #output[1] do",
" tOutput[#tOutput+1] = \"\"",
" for x = 1, #output[1][y] do",
" tOutput[#tOutput] = table.concat({tOutput[#tOutput],\"&\",output[2][y]:sub(x,x),\"~\",output[3][y]:sub(x,x),output[1][y]:sub(x,x)})",
" end",
" end",
" else",
" tOutput = message",
" end",
" enchatSend(yourName, tOutput, true)",
" end",
" end",
"end",
"commands.msg = function(_argument)",
" local sPoint = (_argument or \"\"):find(\" \")",
" if enchatSettings.extraNewline then",
" logadd(nil,nil)",
" end",
" if not sPoint then",
" logadd(\"*\",commandInit..\"msg <recipient> <message>\")",
" else",
" local recipient = _argument:sub(1,sPoint-1)",
" local message = _argument:sub(sPoint+1)",
" if not message then",
" logadd(\"*\",\"You got half of the arguments down pat, at least.\")",
" else",
" if textToBlit(message,true):gsub(\" \",\"\") == \"\" then",
" logadd(\"*\",\"That message is no good.\")",
" else",
" enchatSend(yourName, message, false, nil, nil, false, recipient)",
" logadd(\"*\",\"to '\"..recipient..\"': \"..message)",
" end",
" end",
" end",
"end",
"commands.palette = function(_argument)",
" local argument = _argument or \"\"",
" if enchatSettings.extraNewline then",
" logadd(nil,nil)",
" end",
" if argument:gsub(\"%s\",\"\") == \"\" then",
" local buff = \"\"",
" for k,v in pairs(palette) do",
" buff = buff..k..\", \"",
" end",
" buff = buff:sub(1,-3)",
" logadd(\"*\",commandInit..\"palette \"..buff..\" <colorcode>\")",
" else",
" argument = explode(\" \",argument)",
" if #argument == 1 then",
" if argument[1]:gsub(\"%s\",\"\"):lower() == \"reset\" or argument[1]:gsub(\"%s\",\"\"):lower() == \"enchat3\" then",
" palette = {",
" bg = colors.black,",
" txt = colors.white,",
" promptbg = colors.gray,",
" prompttxt = colors.white,",
" scrollMeter = colors.lightGray,",
" chevron = colors.black,",
" title = colors.lightGray,",
" titlebg = colors.lightGray,",
" }",
" UIconf = {",
" promptY = 1,",
" chevron = \">\",",
" chatlogTop = 1,",
" title = \"\",",
" doTitle = false,",
" titleY = 1,",
" nameDecolor = false,",
" centerTitle = false,",
" prefix = \"<\",",
" suffix = \"> \"",
" }",
" termsetBackgroundColor(palette.bg)",
" termclear()",
" logadd(\"*\",\"You cleansed your palette.\")",
" saveSettings()",
" elseif argument[1]:gsub(\"%s\",\"\"):lower() == \"enchat2\" then",
" palette = {",
" bg = colors.gray,",
" txt = colors.white,",
" promptbg = colors.white,",
" prompttxt = colors.black,",
" scrollMeter = colors.white,",
" chevron = colors.lightGray,",
" title = colors.lightGray,",
" titlebg = colors.lightGray,",
" }",
" UIconf = {",
" promptY = 1,",
" chevron = \">\",",
" chatlogTop = 1,",
" title = \"\",",
" doTitle = false,",
" titleY = 1,",
" nameDecolor = false,",
" centerTitle = false,",
" prefix = \"<\",",
" suffix = \"> \"",
" }",
" termsetBackgroundColor(palette.bg)",
" termclear()",
" logadd(\"*\",\"Switched to the old Enchat2 palette.\")",
" saveSettings()",
" elseif argument[1]:gsub(\"%s\",\"\"):lower() == \"enchat1\" then",
" logadd(\"*\",\"We don't talk about that one.\")",
" elseif argument[1]:gsub(\"%s\",\"\"):lower() == \"enchat4\" then",
" logadd(\"*\",\"Let's leave that to future LDD.\")",
" elseif argument[1]:gsub(\"%s\",\"\"):lower() == \"chat.lua\" then",
" palette = {",
" bg = colors.black,",
" txt = colors.white,",
" promptbg = colors.black,",
" prompttxt = colors.white,",
" scrollMeter = colors.white,",
" chevron = colors.yellow,",
" title = colors.yellow,",
" titlebg = colors.black,",
" }",
" UIconf = {",
" promptY = 0,",
" chevron = \": \",",
" chatlogTop = 2,",
" title = \"YOURNAME on ENCKEY\",",
" doTitle = true,",
" titleY = 1,",
" nameDecolor = true,",
" centerTitle = true,",
" prefix = \"<\",",
" suffix = \"> \"",
" }",
" termsetBackgroundColor(palette.bg)",
" termclear()",
" logadd(\"*\",\"Switched to /rom/programs/rednet/chat.lua palette.\")",
" saveSettings()",
" elseif argument[1]:gsub(\"%s\",\"\"):lower() == \"talk\" then",
" palette = {",
" bg = colors.black,",
" txt = colors.white,",
" promptbg = colors.black,",
" prompttxt = colors.white,",
" scrollMeter = colors.white,",
" chevron = colors.white,",
" title = colors.black,",
" titlebg = colors.white,",
" }",
" UIconf = {",
" promptY = 0,",
" chevron = \"\",",
" chatlogTop = 1,",
" title = \" enchat v3.0 channel: ENCKEY:PORT\",",
" titleY = scr_y - 1,",
" doTitle = true,",
" nameDecolor = false,",
" centerTitle = false,",
" prefix = \"<\",",
" suffix = \"> \"",
" }",
" termsetBackgroundColor(palette.bg)",
" termclear()",
" logadd(\"*\",\"Switched to Talk palette.\")",
" saveSettings()",
" elseif argument[1]:gsub(\"%s\",\"\"):lower() == \"darkchat\" then",
" palette = {",
" bg = colors.black,",
" txt = colors.white,",
" promptbg = colors.black,",
" prompttxt = colors.white,",
" scrollMeter = colors.white,",
" chevron = colors.white,",
" title = colors.white,",
" titlebg = colors.blue,",
" }",
" UIconf = {",
" promptY = 0,",
" chevron = \"Message: \",",
" chatlogTop = 1,",
" title = \"<User: YOURNAME> <Channel: ENCKEY>\",",
" titleY = scr_y - 1,",
" doTitle = true,",
" nameDecolor = false,",
" centerTitle = true,",
" prefix = \"\",",
" suffix = \": \"",
" }",
" termsetBackgroundColor(palette.bg)",
" termclear()",
" logadd(\"*\",\"Switched to DarkChat palette.\")",
" saveSettings()",
" else",
" if not palette[argument[1]] then",
" logadd(\"*\",\"There's no such palette option.\")",
" else",
" logadd(\"*\",\"'\"..argument[1]..\"' = '\"..toblit[palette[argument[1]]]..\"'\")",
" end",
" end",
" else",
" if #argument > 2 then",
" argument = {argument[1], table.concat(argument,\" \",2)}",
" end",
" argument[1] = argument[1]:lower()",
" local newcol = argument[2]:lower()",
" if not palette[argument[1]] then",
" logadd(\"*\",\"That's not a valid palette choice.\")",
" else",
" if not (tocolors[newcol] or colors_strnames[newcol]) then",
" logadd(\"*\",\"That isn't a valid color code. (0-f)\")",
" else",
" palette[argument[1]] = (tocolors[newcol] or colors_strnames[newcol])",
" logadd(\"*\",\"Palette changed.\",false)",
" saveSettings()",
" end",
" end",
" end",
" end",
"end",
"commands.clear = function()",
" log = {}",
" IDlog = {}",
"end",
"commands.ping = function(pong)",
" if enchatSettings.extraNewline then",
" logadd(nil,nil)",
" end",
" logadd(nil, pong or \"Pong!\")",
"end",
"commands.set = function(_argument)",
" if enchatSettings.extraNewline then",
" logadd(nil,nil)",
" end",
" argument = _argument or \"\"",
" local collist = {",
" [\"string\"] = function() return \"0\" end,",
" [\"table\"] = function() return \"5\" end,",
" [\"number\"] = function() return \"0\" end,",
" [\"boolean\"] = function(val) if val then return \"d\" else return \"e\" end end,",
" [\"function\"] = function() return \"c\" end,",
" [\"nil\"] = function() return \"8\" end,",
" [\"thread\"] = function() return \"d\" end,",
" [\"userdata\"] = function() return \"c\" end, -- ha",
" }",
" local custColorize = function(input)",
" return \"&\"..collist[type(input)](input)",
" end",
" local contextualQuote = function(judgetxt,txt)",
" if type(judgetxt) == \"string\" then",
" return table.concat({\"'\",txt,\"'\"})",
" else",
" return txt",
" end",
" end",
" local arguments = explode(\" \",argument)",
" if #argument == 0 then",
" for k,v in pairs(enchatSettings) do",
" logadd(nil,\"&4'\"..k..\"'&r = \"..contextualQuote(v,custColorize(v)..tostring(v)..\"&r\"))",
" end",
" else",
" if enchatSettings[arguments[1]] ~= nil then",
" if #arguments >= 2 then",
" local newval = table.concat(arguments,\" \",2)",
" if tonumber(newval) then",
" newval = tonumber(newval)",
" elseif textutilsunserialize(newval) ~= nil then",
" newval = textutilsunserialize(newval)",
" end",
" if type(enchatSettings[arguments[1]]) == type(newval) then",
" enchatSettings[arguments[1]] = newval",
" logadd(\"*\",\"Set '&4\"..arguments[1]..\"&r' to &{\"..contextualQuote(newval,textutilsserialize(newval)..\"&}\")..\" (\"..type(newval)..\")\")",
" saveSettings()",
" else",
" logadd(\"*\",\"Wrong value type (it's \"..type(enchatSettings[arguments[1]])..\")\")",
" end",
" else",
" logadd(\"*\",\"'\"..arguments[1]..\"' is set to \"..contextualQuote(enchatSettings[arguments[1]],custColorize(enchatSettings[arguments[1]])..textutilsserialize(enchatSettings[arguments[1]])..\"&r\")..\" (\"..type(enchatSettings[arguments[1]])..\")\")",
" end",
" else",
" logadd(\"*\",\"No such setting.\")",
" end",
" end",
" if enchatSettings.useSkynet and (not skynet) then",
" pauseRendering = true",
" termsetBackgroundColor(colors.black)",
" termclear()",
" pauseRendering = false",
" end",
"end",
"commands.help = function(cmdname)",
" if enchatSettings.extraNewline then",
" logadd(nil,nil)",
" end",
" if cmdname then",
" local helpList = {",
" exit = \"Exits Enchat and returns to loader (most likely CraftOS)\",",
" about = \"Tells you a bit about this here Enchat.\",",
" me = \"Sends a message in the format of \\\"* yourName message\\\"\",",
" colors = \"Lists all the colors you can use.\",",
" update = \"Updates and overwrites Enchat, then exits if successful.\",",
" list = \"Lists all users in range using the same key.\",",
" nick = \"Give yourself a different username.\",",
" whoami = \"Tells you your current username.\",",
" key = \"Change the current encryption key. Tells you the key, if without argument.\",",
" clear = \"Clears the local chat log. Not your inventory, I swear.\",",
" ping = \"Pong. *sigh*\",",
" shrug = \"Sends out a shrugging emoticon.\",",
" set = \"Changes config options during the current session. Lists all options, if without argument.\",",
" msg = \"Sends a message that is only logged by a specific user.\",",
" picto = \"Opens an image maker and sends the result. Use the scroll wheel to change color, and hold left shift to change text color. If argument given, will look for an image at the given path and use that instead.\",",
" tron = \"Starts up a game of TRON.\",",
" big = \"Sends your message, but enlarged by a specified amount via Wojbie's BigFont API.\",",
" help = \"Shows every command, or describes a specific command.\",",
" }",
" cmdname = cmdname:gsub(\" \",\"\"):gsub(\"/\",\"\")",
" if helpList[cmdname] then",
" logadd(\"*\", helpList[cmdname])",
" else",
" if commands[cmdname] then",
" logadd(\"*\", \"No help info for that command.\")",
" else",
" logadd(\"*\", \"No such command to get help for.\")",
" end",
" end",
" else",
" logadd(\"*\",\"All commands:\")",
" local output = \"\"",
" for k,v in pairs(commands) do",
" output = output..\" \"..commandInit..k..\",\"",
" end",
" logadd(nil, output:sub(1,-2))",
" end",
"end",
"commandAliases = {",
" quit = commands.exit,",
" colours = commands.colors,",
" ls = commands.list,",
" cry = commands.list,",
" nickname = commands.nick,",
" channel = commands.key,",
" palate = commands.palette,",
" tell = commands.msg,",
" whisper = commands.msg,",
" [\"?\"] = commands.help,",
" porn = function() logadd(\"*\",\"Yeah, no.\") end,",
" whoareyou = function() logadd(\"*\", \"I'm Enchat. But surely, you know this?\") end,",
" fuck = function() logadd(\"*\",\"A mind is a terrible thing to waste.\") end,",
" hello = function() logadd(\"*\",\"Hey.\") end,",
" hi = function() logadd(\"*\",\"Hiya.\") end,",
" hey = function() logadd(\"*\",\"That's for horses.\") end,",
" bye = function() logadd(\"*\",\"You know, you can use /exit.\") end,",
" die = function() logadd(\"*\",\"You wish.\") end,",
" nap = function() logadd(\"*\",\"The time for napping has passed.\") end,",
" sorry = function() logadd(\"*\",\"That's okay.\") end,",
" jump = function() logadd(\"*\",\"Sorry. This program is in a NO JUMPING zone.\") end,",
" enchat = function() logadd(\"*\",\"At your service!\") end,",
" win = function() logadd(\"*\",\"Naturally!\") end,",
" lose = function() logadd(\"*\",\"Preposterous!\") end,",
" xyzzy = function() logadd(\"*\",\"A hollow voice says \\\"Fool.\\\"\") end,",
" wait = function() logadd(\"*\",\"Time passes...\") end,",
" stop = function() logadd(\"*\",\"Hammertime!\",\"fadeIn\") end,",
" shit = function() logadd(\"*\",\"Man, you're telling me!\") end,",
" eat = function() logadd(\"*\",\"You're not hungry.\") end,",
" what = function() logadd(\"*\",\"What indeed.\") end,",
" ldd = function() logadd(nil,\"& that's me\") end,",
" OrElseYouWill = function()",
" enchatSend(\"*\", \"'\"..yourName..\"&}&r~r' buggered off. (disconnect)\")",
" error(\"DIE\")",
" end",
"}",
"",
"local checkIfCommand = function(input)",
" if input:sub(1,#commandInit) == commandInit then",
" return true",
" else",
" return false",
" end",
"end",
"",
"local parseCommand = function(input)",
" local sPos1, sPos2 = input:find(\" \")",
" local cmdName, cmdArgs",
" if sPos1 then",
" cmdName = input:sub(#commandInit+1, sPos1-1)",
" cmdArgs = input:sub(sPos2+1)",
" else",
" cmdName = input:sub(#commandInit+1)",
" cmdArgs = nil",
" end",
"",
" local res",
" local CMD = commands[cmdName] or commandAliases[cmdName]",
" if CMD then",
" res = CMD(cmdArgs)",
" if res == \"exit\" then",
" return \"exit\"",
" end",
" else",
" logadd(\"*\", \"No such command.\")",
" end",
"end",
"",
"local main = function()",
" termsetBackgroundColor(palette.bg)",
" termclear()",
" os.queueEvent(\"render_enchat\")",
" local mHistory = {}",
"",
" while true do",
"",
" termsetCursorPos(1, scr_y-UIconf.promptY)",
" termsetBackgroundColor(palette.promptbg)",
" termclearLine()",
" termsetTextColor(palette.chevron)",
" termwrite(UIconf.chevron)",
" termsetTextColor(palette.prompttxt)",
"",
" local input = colorRead(nil, mHistory)",
" if textToBlit(input,true):gsub(\" \",\"\") ~= \"\" then -- people who send blank messages in chat programs deserve to die",
" if checkIfCommand(input) then",
" local res = parseCommand(input)",
" if res == \"exit\" then",
" return \"exit\"",
" end",
" else",
" if enchatSettings.extraNewline then",
" logadd(nil,nil) -- readability is key",
" end",
" enchatSend(yourName, input, true)",
" end",
" if mHistory[#mHistory] ~= input then",
" mHistory[#mHistory+1] = input",
" end",
" elseif input == \"\" then",
" logadd(nil,nil)",
" end",
" os.queueEvent(\"render_enchat\")",
"",
" end",
"",
"end",
"",
"local handleReceiveMessage = function(user, message, animType, maxFrame)",
" if enchatSettings.extraNewline then",
" logadd(nil,nil) -- readability is still key",
" end",
" logadd(user, message,animations[animType] and animType or nil,(type(maxFrame) == \"number\") and maxFrame or nil)",
" os.queueEvent(\"render_enchat\")",
"end",
"",
"local adjScroll = function(distance)",
" scroll = mathmin(maxScroll, mathmax(0, scroll + distance))",
"end",
"",
"local checkRSinput = function()",
" return (",
" rs.getInput(\"front\") or",
" rs.getInput(\"back\") or",
" rs.getInput(\"left\") or",
" rs.getInput(\"right\") or",
" rs.getInput(\"top\") or",
" rs.getInput(\"bottom\")",
" )",
"end",
"",
"local handleEvents = function()",
" local oldScroll",
" local keysDown = {}",
" while true do",
" local evt = {os.pullEvent()}",
" if evt[1] == \"enchat_receive\" then",
" if type(evt[2]) == \"string\" and type(evt[3]) == \"string\" then",
" handleReceiveMessage(evt[2], evt[3])",
" end",
" elseif evt[1] == \"chat\" and ((not checkRSinput()) or (not enchat.disableChatboxWithRedstone)) and enchat.useChatbox then",
" if enchatSettings.extraNewline then",
" logadd(nil,nil) -- readability is key",
" end",
" enchatSend(evt[2], evt[3], true)",
" elseif evt[1] == \"chat_message\" and ((not checkRSinput()) or (not enchat.disableChatboxWithRedstone)) and enchat.useChatbox then -- computronics",
" if enchat.useChatboxWhitelist then",
" if evt[4] == (\"\\\\\"..chatboxName..\" \"..optInPhrase) and not chatboxWhitelist[evt[3]] then",
" chatboxWhitelist[evt[3]] = true",
" chatbox.tell(evt[3], \"Opted in to Enchat's chatbox messages.\")",
" elseif evt[4] == (\"\\\\\"..chatboxName..\" \"..optOutPhrase) and chatboxWhitelist[evt[3]] then",
" chatboxWhitelist[evt[3]] = nil",
" chatbox.tell(evt[3], \"Opted out from Enchat's chatbox messages.\")",
" else",
" if enchatSettings.extraNewline then",
" logadd(nil,nil) -- readability is key",
" end",
" enchatSend(evt[3], evt[4], true)",
" end",
" else",
" if enchatSettings.extraNewline then",
" logadd(nil,nil) -- readability is still key",
" end",
" enchatSend(evt[3], evt[4], true)",
" end",
" elseif evt[1] == \"command\" and enchat.useChatbox then",
" if evt[3] == chatboxName then",
" if evt[4][1] == \"opt\" then",
" if evt[4][2] == \"in\" then",
" if chatboxWhitelist[evt[2]] then",
" chatbox.tell(evt[2], \"You're already opted in.\")",
" else",
" chatboxWhitelist[evt[2]] = true",
" chatbox.tell(evt[2], \"Opted in to Enchat's chatbox messages.\")",
" saveSettings()",
" end",
" elseif evt[4][2] == \"out\" then",
" if not chatboxWhitelist[evt[2]] then",
" chatbox.tell(evt[2], \"You're already opted out.\")",
" else",
" chatboxWhitelist[evt[2]] = nil",
" chatbox.tell(evt[2], \"Opted out from Enchat's chatbox messages.\")",
" saveSettings()",
" end",
" end",
" end",
" end",
" elseif (evt[1] == \"modem_message\") or (evt[1] == \"skynet_message\" and enchatSettings.useSkynet) then",
" local side, freq, repfreq, msg, distance",
" if evt[1] == \"modem_message\" then",
" side, freq, repfreq, msg, distance = evt[2], evt[3], evt[4], evt[5], evt[6]",
" else",
" freq, msg = evt[2], evt[3]",
" end",
" if (freq == enchat.port) or (freq == enchat.skynetPort) then",
" msg = decrite(msg)",
" if type(msg) == \"table\" then",
" if (type(msg.name) == \"string\") then",
" if #msg.name <= 32 then",
" if msg.messageID and (not IDlog[msg.messageID]) then",
" userCryList[msg.name] = true",
" IDlog[msg.messageID] = true",
" if ((not msg.recipient) or (msg.recipient == yourName or msg.recipient == textToBlit(yourName,true))) then",
" if type(msg.message) == \"string\" then",
" handleReceiveMessage(msg.name, tostring(msg.message), msg.animType, msg.maxFrame, msg.ignoreWrap)",
" if chatbox and enchat.useChatbox and ((not checkRSinput()) or (not enchat.disableChatboxWithRedstone)) then",
" chatbox.say(textToBlit(UIconf.prefix .. msg.name .. UIconf.suffix .. msg.message, true), msg.name)",
" end",
" elseif type(msg.message) == \"table\" and enchatSettings.acceptPictoChat and #msg.message <= 64 then",
" logaddTable(msg.name, msg.message, msg.animType, msg.maxFrame, msg.ignoreWrap)",
" if enchatSettings.extraNewline then",
" logadd(nil,nil)",
" end",
" end",
" end",
" if (msg.cry == true) then",
" cryOut(yourName, false)",
" end",
" end",
" end",
" end",
" end",
" end",
" elseif evt[1] == \"mouse_scroll\" and (not pauseRendering) then",
" local dist = evt[2]",
" oldScroll = scroll",
" adjScroll(enchatSettings.reverseScroll and -dist or dist)",
" if scroll ~= oldScroll then",
" dab(renderChat)",
" end",
" elseif evt[1] == \"key\" and (not pauseRendering) then",
" local key = evt[2]",
" keysDown[key] = true",
" oldScroll = scroll",
" local pageSize = (scr_y-UIconf.promptY) - UIconf.chatlogTop",
" if key == keys.pageUp then",
" adjScroll(-(keysDown[keys.leftCtrl] and pageSize or enchatSettings.pageKeySpeed))",
" elseif key == keys.pageDown then",
" adjScroll(keysDown[keys.leftCtrl] and pageSize or enchatSettings.pageKeySpeed)",
" end",
" if scroll ~= oldScroll then",
" dab(renderChat)",
" end",
" elseif evt[1] == \"key_up\" then",
" local key = evt[2]",
" keysDown[key] = nil",
" elseif (evt[1] == \"render_enchat\") and (not pauseRendering) then",
" dab(renderChat)",
" elseif (evt[1] == \"tron_complete\") then",
" if evt[3] then",
" if enchatSettings.extraNewline then",
" logadd(nil,nil)",
" end",
" if evt[2] == \"win\" then",
" enchatSend(\"*\", yourName .. \"&}&r~r beat \" .. (evt[4] or \"someone\") .. \"&}&r~r in TRON!\", true)",
" elseif evt[2] == \"lose\" then",
" enchatSend(\"*\", (evt[4] or \"Someone\") .. \"&}&r~r beat \" .. yourName .. \"&}&r~r in TRON!\", true)",
" elseif evt[2] == \"tie\" then",
" enchatSend(\"*\", yourName .. \"&}&r~r tied with \" .. (evt[4] or \"someone\") .. \"&}&r~r in TRON!\", true)",
" end",
" elseif evt[2] == \"timeout\" then",
" if enchatSettings.extraNewline then",
" logadd(nil,nil)",
" end",
" enchatSend(\"*\", yourName .. \"&}&r~r timed out against \" .. (evt[4] or \"someone\") .. \"&}&r~r in TRON...\", true)",
" end",
" elseif evt[1] == \"terminate\" then",
" return \"exit\"",
" end",
" end",
"end",
"",
"local keepRedrawing = function()",
" while true do",
" sleep(enchatSettings.redrawDelay)",
" if not pauseRendering then",
" os.queueEvent(\"render_enchat\")",
" end",
" end",
"end",
"",
"local handleNotifications = function()",
" while true do",
" os.pullEvent(\"render_enchat\")",
" if canvas and enchatSettings.doNotif then",
" notif.displayNotifications(true)",
" end",
" end",
"end",
"",
"getModem()",
"",
"enchatSend(\"*\", \"'\"..yourName..\"&}&r~r' has moseyed on over.\", true)",
"",
"local funky = {",
" main,",
" handleEvents,",
" keepRedrawing,",
" handleNotifications",
"}",
"",
"if skynet then",
" funky[#funky+1] = function()",
" while true do",
" if skynet then",
" pcall(skynet.listen)",
" local success, msg = pcall(skynet.open, enchat.skynetPort)",
" if not success then",
" skynet = nil",
" end",
" end",
" sleep(5)",
" end",
" end",
"end",
"",
"pauseRendering = false",
"",
"local res, outcome = pcall(function()",
" return parallel.waitForAny(unpack(funky))",
"end)",
"",
"os.pullEvent = oldePullEvent",
"if skynet then",
" if skynet.socket then",
" skynet.socket.close()",
" end",
"end",
"",
"if canvas then",
" canvas.clear()",
"end",
"",
"tsv(true) -- in case it's false, y'know",
"",
"if not res then",
" prettyClearScreen(1,scr_y-1)",
" termsetTextColor(colors.white)",
" termsetBackgroundColor(colors.gray)",
" cwrite(\"There was an error.\",2)",
" cfwrite(\"Report this to &3@LDDestroier#2901&r\",3)",
" cwrite(\"on Discord,\",4)",
" cwrite(\"if you feel like it.\",5)",
" termsetCursorPos(1,7)",
" printError(outcome)",
" termsetTextColor(colors.lightGray)",
" cwrite(\"I'll probably fix it, maybe.\",10)",
"end",
"",
"termsetCursorPos(1, scr_y)",
"termsetBackgroundColor(initcolors.bg)",
"termsetTextColor(initcolors.txt)",
"termclearLine()",
},
[ "/game/data/sprites/megaman/buster3-3.nft" ] = {
"",
"  0f‡ƒf0  bf—99€b‚fƒfb",
"4f…f0Ÿ40‹  bfŸ9b‡9€€€€€bŠf",
"04f0•  9f•9€€€€€€€fb•",
"4Š0‚f‹f0ž  fb‹9f9€€€€b…",
"  f4‚ƒ  fb‚9‹ƒ",
},
[ "/util/progdor.lua" ] = {
"--[[",
" PROGDOR file bundling program",
"",
"Download with:",
" pastebin get YXx5jjMV progdor",
" std ld progdor progdor",
"",
"This is a stable release. You fool!",
"--]]",
"",
"local doCompress = false --even if this is false, it will decompress compressed files. nifty, huh?",
"",
"local doPastebin = false",
"local tArg = {...}",
"local input, outpath",
"if tArg[1] == \"-p\" then --the p is for pastebin",
" doPastebin = true",
" input = tArg[2]",
" outpath = tArg[3]",
"else",
" input = tArg[1]",
" outpath = tArg[2]",
"end",
"",
"local progdor = fs.getName(shell.getRunningProgram())",
"local dir = shell.dir()",
"local displayHelp = function()",
" local txt = progdor..\" <input> [output]\\nCompression is \"..tostring(doCompress):upper()..\".\"",
" return print(txt)",
"end",
"",
"local yield = function()",
" os.queueEvent(\"yield\")",
" os.pullEvent(\"yield\")",
"end",
"",
"-- CCA API START --",
"",
"local bit = bit32",
"local function pack(bn1, bn2)",
" return bit.band(bn1, 0xFF), bit.rshift(bn1, 8) + bit.lshift(bit.band(bn2, 0xF), 4), bit.rshift(bn2, 4)",
"end",
"local function upack(b1, b2, b3)",
" return (b1 + bit.lshift(bit.band(b2, 0xF), 8)), (bit.lshift(b3,4) + bit.band(bit.rshift(b2, 4), 0xF))",
"end",
"local function createDict(bool)",
" local ret = {}",
" for i = 1, 255 do",
" if bool then",
" ret[string.char(i)] = i",
" else",
" ret[i] = string.char(i)",
" end",
" end",
" if not bool then ret[256] = 256 end",
" return ret",
"end",
"local function cp(sInput)",
" local dic = createDict(true)",
" local s = \"\"",
" local ch",
" local dlen = 256",
" local result = {}",
" local temp",
" for i = 1, #sInput do",
" if dlen == 4095 then",
" result[#result + 1] = dic[s]",
" result[#result + 1] = 256",
" dic = createDict(true)",
" dlen = 256",
" s = \"\"",
" end",
" ch = sInput:sub(i, i)",
" temp = s..ch",
" if dic[temp] then",
" s = temp",
" else",
" result[#result + 1] = dic[s]",
" dlen = dlen +1",
" dic[temp] = dlen ",
" s = ch",
" end",
" end",
" result[#result + 1] = dic[s]",
" ",
" return result",
"end",
"local function dc(data)",
" local dic = createDict(false) ",
" local entry",
" local ch",
" local currCode",
" local result = {}",
" result[#result + 1] = dic[data[1]]",
" prefix = dic[data[1]]",
" for i = 2, #data do",
" currCode = data[i]",
" if currCode == 256 then",
" dic = createDict(false)",
" prefix = \"\"",
" else",
" entry = dic[currCode]",
" if entry then--exists in dictionary",
" ch = entry:sub(1, 1) ",
" result[#result + 1] = entry",
" if prefix ~= \"\" then",
" dic[#dic+1] = prefix .. ch",
" end",
" else ",
" ch = prefix:sub(1, 1)",
" result[#result + 1] = prefix..ch",
" dic[#dic + 1] = prefix..ch",
" end",
" ",
" prefix = dic[currCode]",
" end",
" end",
" ",
" return table.concat(result)",
"end",
"local function trim(inp)",
" for i = 0,2 do",
" if inp[#inp] == 0 then",
" inp[#inp] = nil",
" end",
" end",
"end",
"local function decompress(input)",
" local rec = {}",
" for i = 1, #input, 3 do",
" if i % 66 == 0 then",
" yield()",
" end",
" rec[#rec+1], rec[#rec+2] = upack(input[i], input[i+1] or 0, input[i+2] or 0)",
" end",
" trim(rec)",
" return dc(rec)",
"end",
"local function compress(input)",
" local rec = {}",
" local data = cp(input)",
" for i=1, #data, 2 do",
" yield()",
" rec[#rec+1], rec[#rec+2], rec[#rec+3] = pack(data[i], data[i+1] or 0)",
" end",
" trim(rec)",
" return rec",
"end",
"",
"-- CCA API END --",
"",
"local fixstr = function(str)",
" return str:gsub(\"\\\\(%d%d%d)\",string.char)",
"end",
"",
"local explode = function(div,str)",
" if (div=='') then return false end",
" local pos,arr = 0,{}",
" for st,sp in function() return string.find(str,div,pos,true) end do",
" table.insert(arr,str:sub(pos,st-1))",
" pos = sp + 1",
" end",
" table.insert(arr,str:sub(pos))",
" return arr",
"end",
"local sanitize = function(sani,tize)",
" local _,x = string.find(sani,tize)",
" if x then",
" return sani:sub(x+1)",
" else",
" return sani",
" end",
"end",
"local tablize = function(input)",
" if type(input) == \"string\" then",
" return explode(\"\\n\",input)",
" elseif type(input) == \"table\" then",
" return table.concat(input,\"\\n\")",
" end",
"end",
"local compyress = function(input)",
" return string.char(unpack(compress(input)))",
"end",
"local decompyress = function(input)",
" local out = {}",
" for a = 1, #input do",
" table.insert(out,string.byte(input:sub(a,a)))",
" end",
" return decompress(out)",
"end",
"local listAll",
"listAll = function(_path, _files, noredundant)",
" local path = _path or \"\"",
" local files = _files or {}",
" if #path > 1 then table.insert(files, path) end",
" for _, file in ipairs(fs.list(path)) do",
" local path = fs.combine(path, file)",
" if (file ~= thisProgram) then",
" local guud = true",
" if guud then",
" if fs.isDir(path) then",
" listAll(path, files, noredundant)",
" else",
" table.insert(files, path)",
" end",
" end",
" end",
" end",
" if noredundant then",
" for a = 1, #files do",
" if fs.isDir(tostring(files[a])) then",
" if #fs.list(tostring(files[a])) ~= 0 then",
" table.remove(files,a)",
" end",
" end",
" end",
" end",
" return files",
"end",
"if not (input) then",
" return displayHelp()",
"end",
"if not outpath then",
" outpath = input",
"end",
"",
"local choice = function(input,verbose)",
" if not input then",
" input = \"yn\"",
" end",
" if verbose then",
" write(\"[\")",
" for a = 1, #input do",
" write(input:sub(a,a):upper())",
" if a < #input then",
" write(\",\")",
" end",
" end",
" write(\"]?\")",
" end",
" local evt,char",
" repeat",
" evt,char = os.pullEvent(\"char\")",
" until string.find(input:lower(),char:lower())",
" if verbose then",
" print(char:upper())",
" end",
" local pos = string.find(input:lower(),char:lower())",
" return pos, char:lower()",
"end",
"",
"local postToPastebin = function(name, contents)",
" local key = \"0ec2eb25b6166c0c27a394ae118ad829\"",
" local response = http.post(",
" \"http://pastebin.com/api/api_post.php\",",
" \"api_option=paste&\"..",
" \"api_dev_key=\"..key..\"&\"..",
" \"api_paste_format=lua&\"..",
" \"api_paste_name=\"..textutils.urlEncode(name)..\"&\"..",
" \"api_paste_code=\"..textutils.urlEncode(contents)",
" )",
" if response then",
" local sResponse = response.readAll()",
" response.close()",
" local sCode = string.match( sResponse, \"[^/]+$\" )",
" return sCode",
" else",
" return false",
" end",
" return ",
"end",
"",
"function doPack(input,output,doCompress,verbose) --make sure that shell exists before using verbose mode",
" local tx = term.getTextColor()",
" if not doPastebin then",
" if not fs.exists(input) then return 3 end",
" if fs.isReadOnly(output) then return 5 end",
" end",
" local packageSelf = true",
" local packageReadOnly = true",
" local ro_asked = false",
" local ps_asked = false",
" if fs.isDir(input) then --if not a package",
" local out = {}",
" local list = listAll(input,nil,true)",
" if verbose then",
" for a = 1, #list do --this checks for self and read-only files",
" if fs.isReadOnly(list[a]) and (not ro_asked) then",
" write(\"Include read-only files? \")",
" if choice(\"yn\",true) == 2 then",
" packageReadOnly = false",
" end",
" ro_asked = true",
" end",
" if fs.combine(\"\",list[a]) == shell.getRunningProgram() and (not ps_asked) then",
" write(\"Include self? \")",
" if choice(\"yn\",true) == 2 then",
" packageSelf = false",
" end",
" ps_asked = true",
" end",
" end",
" end",
" for a = 1, #list do --this loop kills fascists",
" local is_self = fs.combine(\"\",list[a]) == fs.combine(\"\",shell.getRunningProgram())",
" if not ((is_self and not packageSelf) or (fs.isReadOnly(list[a]) and not packageReadOnly)) then",
" if verbose then",
" write(\"[\")",
" if term.isColor() then term.setTextColor(colors.lightGray) end",
" write(sanitize(list[a],fs.combine(dir,input)))",
" term.setTextColor(tx)",
" write(\"]\")",
" end",
" if fs.isDir(list[a]) then",
" out[sanitize(list[a],fs.combine(dir,input))] = true",
" else",
" local file = fs.open(list[a],\"r\")",
" local cont = file.readAll()",
" file.close()",
" if doCompress then",
" out[sanitize(list[a],fs.combine(dir,input))] = tablize(compyress(cont))",
" else",
" out[sanitize(list[a],fs.combine(dir,input))] = tablize(cont)",
" end",
" end",
" local tx = term.getTextColor()",
" if fs.getName(list[a]):lower() == \"peasant\" then",
" if term.isColor() then",
" term.setTextColor(colors.orange)",
" end",
" print(\" BURNINATED\")",
" else",
" if term.isColor() then",
" term.setTextColor(colors.green)",
" end",
" print(\" GOOD\")",
" end",
" term.setTextColor(tx)",
" else",
" if fs.getName(list[a]):lower() == \"peasant\" then",
" print(\"Spared \"..list[a])",
" else",
" print(\"Skipped \"..list[a])",
" end",
" end",
" end",
" local fullOutput = tostring(doCompress)..\"\\n\"..fixstr(textutils.serialize(out))",
" local sCode",
" if doPastebin then",
" print(\"Uploading...\")",
" sCode = postToPastebin(input,fullOutput)",
" return 7, \"Code = '\"..sCode..\"'\"",
" else",
" if fs.isDir(output) then fs.delete(output) end",
" local file = fs.open(output,\"w\")",
" file.write(fullOutput)",
" file.close()",
" return 1",
" end",
" else --if a package",
" local list, isCompy",
" if not doPastebin then",
" local file = fs.open(input,\"r\")",
" isCompy = file.readLine()",
" list = file.readAll()",
" file.close()",
" else",
" local file = http.get(\"http://pastebin.com/raw/\"..tostring(input))",
" if file then",
" isCompy = file.readLine()",
" list = file.readAll()",
" else",
" return 6",
" end",
" end",
" local list = textutils.unserialize(list)",
" if type(list) ~= \"table\" then",
" return 4",
" end",
" if fs.exists(output) then",
" fs.delete(output)",
" end",
" local amnt = 0",
" for k,v in pairs(list) do",
" amnt = amnt + 1",
" end",
" local num = 0",
" for k,v in pairs(list) do",
" num = num + 1",
" if v == true then",
" fs.makeDir(fs.combine(output,fs.combine(k,dir)))",
" else",
" local file = fs.open(fs.combine(output,fs.combine(k,dir)),\"w\")",
" if verbose then",
" write(\"[\")",
" if term.isColor() then term.setTextColor(colors.lightGray) end",
" write(k)",
" term.setTextColor(tx)",
" write(\"]\")",
" end",
" if isCompy:gsub(\" \",\"\") == \"true\" then",
" file.write(decompyress(tablize(v)))",
" else",
" file.write(tablize(v))",
" end",
" file.close()",
" local tx = term.getTextColor()",
" if fs.getName(k):lower() == \"peasant\" then",
" if term.isColor() then",
" term.setTextColor(colors.orange)",
" end",
" print(\" UNBURNINATED\")",
" else",
" if term.isColor() then",
" term.setTextColor(colors.green)",
" end",
" print(\" GOOD\")",
" end",
" term.setTextColor(tx)",
" end",
" end",
" return 2",
" end",
"end",
"",
"local success, res, otherRes = pcall( function() return doPack(input,outpath,doCompress,true) end ) --functionized it!",
"",
"if not success then",
" term.setTextColor(colors.white)",
" print(\"\\n***Something went wrong!***\")",
" return printError(res)",
"end",
"",
"if res then",
" local msgs = {",
" [1] = \"Successfully packed '\"..input..\"/' as '\"..outpath..\"'\",",
" [2] = \"Successfully unpacked '\"..input..\"' to '\"..outpath..\"/'\",",
" [3] = \"That file/folder does not exist.\",",
" [4] = \"That file isn't a packed folder.\",",
" [5] = \"You don't have permission.\",",
" [6] = \"Failed to connect.\",",
" [7] = \"Uploaded successfully.\",",
" }",
" print(msgs[res])",
" if otherRes then",
" print(otherRes)",
" end",
"end",
},
[ "/game/data/sprites/megaman/buster3-4.nft" ] = {
"",
"",
"  4fŸ0‡ƒƒf4",
"4Š40Ÿ0€€€f•",
"  f4‚0ƒ4ƒ",
},
[ "/game/dodge2.lua" ] = {
"--[[",
"SUPER Dodge!!",
"A remake of that last game I made. Mostly an experiment with cool background.",
"Get with",
" pastebin get 5BUnGkUJ dodge2",
"And soon",
" std ld dodge2 dodge2",
"",
"This game isn't finished, but it is certainly playable.",
"",
"...you fool!",
"--]]",
"local scr_x, scr_y = term.getSize()",
"local sprite = {}",
"sprite.dw = {{128,128,128,128,128,128,},{128,256,256,256,256,128,},{128,256,256,256,256,128,},{128,256,256,256,256,128,},{128,256,256,256,256,128,},{128,256,256,256,256,128,},{128,256,256,256,256,128,},{128,256,256,256,256,128,},{128,256,256,256,256,128,},{128,256,256,256,256,128,},{128,256,256,256,256,128,},{128,256,256,256,256,128,},{128,256,256,256,256,128,},{128,256,256,256,256,128,},{128,128,256,256,128,128,},{0,16384,16384,16384,16384,0,},{16384,2,2,2,2,16384,},{16384,2,2,16,16,16384,},{16384,16,16,16,2,16384,},{0,16384,16384,16384,16384,0,},}",
"sprite.uw = {{0,16384,16384,16384,16384,0,},{16384,16,16,2,2,16384,},{16384,16,2,2,2,16384,},{16384,2,2,16,16,16384,},{0,16384,16384,16384,16384,0,},{128,128,256,256,128,128,},{128,256,256,256,256,128,},{128,256,256,256,256,128,},{128,256,256,256,256,128,},{128,256,256,256,256,128,},{128,256,256,256,256,128,},{128,256,256,256,256,128,},{128,256,256,256,256,128,},{128,256,256,256,256,128,},{128,256,256,256,256,128,},{128,256,256,256,256,128,},{128,256,256,256,256,128,},{128,256,256,256,256,128,},{128,256,256,256,256,128,},{128,128,128,128,128,128,},}",
"sprite.guy = {{2,0,8192,32,32,0},{16384,8192,8192,32,2048,32},{2,0,8192,32,32,0}}",
"sprite.guybig = {{},{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,32,32,32,32,32,32,32,32,},{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,32,32,32,32,32,32,32,32,32,32,32,32,32,32,},{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,32,32,32,32,32,32,32,32,32,32768,32768,32,32,32,32,32,32,32,},{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,32,32,32,32,32,32,32,32,32,32,32,32768,8,8,32768,32,32,32,32,32,32,},{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,32,32,32,32,32,32,32,32,32,32,32,0,8,8,8,8,32768,32,32,32,32,0,},{0,0,0,0,0,0,0,0,0,0,0,0,0,0,32,32,32,32,32,32,32,32,32,32,32,32,32,32768,8,8,8,32768,32,32,32,32,32,0,},{0,0,0,0,0,0,0,0,0,0,0,0,0,8192,8192,8192,32,32,32,32,32,32,32,32,32,32,32,32,32768,32768,32768,32,32,32,32,32,0,0,},{0,0,0,0,0,0,0,0,0,0,0,0,0,8192,8192,8192,8192,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,0,0,},{0,0,0,0,0,0,0,0,0,0,0,0,0,8192,8192,8192,8192,8192,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,0,0,0,},{0,0,0,0,0,0,0,0,0,0,0,0,8192,8192,8192,8192,8192,8192,8192,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,0,0,0,0,},{0,0,0,0,0,0,0,0,0,0,0,0,8192,8192,8192,8192,8192,8192,8192,8192,8192,32,32,32,32,32,32,32,32,32,32,32,32,0,0,0,0,0,},{0,0,0,0,0,0,0,0,0,0,0,0,0,8192,8192,8192,8192,8192,8192,8192,8192,8192,8192,8192,8192,32,32,32,32,32,32,32,0,0,0,0,0,0,},{0,0,0,0,0,0,0,0,0,0,0,0,256,256,8192,8192,8192,8192,8192,8192,8192,8192,8192,8192,8192,8192,8192,8192,8192,8192,0,0,0,0,0,0,0,0,},{0,0,0,0,0,0,0,0,0,0,0,256,256,256,256,256,8192,8192,8192,8192,8192,8192,8192,8192,8192,8192,8192,8192,8192,0,0,0,0,0,0,0,0,0,},{0,0,0,0,0,0,0,0,0,0,0,2,2048,256,256,256,256,8192,8192,8192,8192,8192,8192,8192,8192,8192,8192,0,0,0,0,0,0,0,0,0,0,0,},{0,0,0,0,0,0,2,2,2,2,2,2,2048,2048,2048,256,256,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,},{0,0,0,0,2,2,2,2,2,2,16,16,16,16,16,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,},{0,0,0,2,2,2,2,2,2,16,16,16,16,16,2,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,},{0,0,0,0,0,0,2,2,2,2,16,16,16,2,2,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,},{0,0,0,0,0,2,2,2,2,2,2,2,2,2,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,},{0,0,0,0,0,2,0,0,0,2,2,2,2,2,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,},{0,0,0,0,0,0,0,0,0,2,0,2,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,}}",
"sprite.title = {{1,1,1,1,1,0,1,0,0,0,1,0,1,1,1,1,1,0,1,1,1,1,1,0,1,1,1,1,1,0,0,0,0,0,0,0,0,},{1,1,1,1,1,0,1,0,0,0,1,0,1,1,1,1,1,0,1,1,1,1,1,0,1,1,1,1,1,0,0,0,0,0,0,0,0,},{1,0,0,0,0,0,1,0,0,0,1,0,1,0,0,0,1,0,1,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,},{1,1,1,1,1,0,1,0,0,0,1,0,1,1,1,1,1,0,1,1,1,1,0,0,1,1,1,1,1,0,0,0,0,0,0,0,0,},{0,0,0,0,1,0,1,0,0,0,1,0,1,0,0,0,0,0,1,0,0,0,0,0,1,0,1,0,0,0,0,0,0,0,0,0,0,},{0,0,0,0,1,0,1,0,0,0,1,0,1,0,0,0,0,0,1,0,0,0,0,0,1,0,0,1,0,0,0,0,0,0,0,0,0,},{1,1,1,1,1,0,1,1,1,1,1,0,1,0,0,0,0,0,1,1,1,1,1,0,1,0,0,0,1,0,0,0,0,0,0,0,0,},{1,1,1,1,1,0,1,1,1,1,1,0,1,0,0,0,0,0,1,1,1,1,1,0,1,0,0,0,1,0,0,0,0,0,0,0,0,},{},{8,8,8,8,8,0,0,0,0,8,8,8,8,8,0,0,8,8,8,8,8,0,0,0,0,8,8,8,8,0,0,8,8,8,8,8,8,},{8,8,8,8,8,8,0,0,8,8,8,8,8,8,8,0,8,8,8,8,8,8,0,0,8,8,8,8,8,8,0,8,8,8,8,8,8,},{8,8,0,0,8,8,8,0,8,8,0,0,0,8,8,0,8,8,0,0,8,8,8,0,8,8,0,0,8,8,0,8,8,0,0,0,0,},{8,8,0,0,0,8,8,0,8,8,0,0,0,8,8,0,8,8,0,0,0,8,8,0,8,8,0,0,0,0,0,8,8,8,8,8,0,},{8,8,0,0,0,8,8,0,8,8,0,0,0,8,8,0,8,8,0,0,0,8,8,0,8,8,0,8,8,8,0,8,8,0,0,0,0,},{8,8,0,0,8,8,8,0,8,8,0,0,0,8,8,0,8,8,0,0,8,8,8,0,8,8,0,0,8,8,0,8,8,0,0,0,0,},{8,8,8,8,8,8,0,0,8,8,8,8,8,8,8,0,8,8,8,8,8,8,0,0,8,8,8,8,8,8,0,8,8,8,8,8,8,},{8,8,8,8,8,0,0,0,0,8,8,8,8,8,0,0,8,8,8,8,8,0,0,0,0,8,8,8,8,0,0,8,8,8,8,8,8,}}",
"sprite.bg = {{32768,32768,32768,32768,32768,32768,32768,32768,32768,32768,32768,32768,32768,32768,32768,32768,32768,32768},{32768,32768,32768,32768,32768,32768,32768,32768,32768,32768,32768,32768,32768,32768,32768,32768,32768,32768},{4096,32768,32768,32768,32768,32768,32768,32768,32768,4096,4096,4096,4096,4096,4096,4096,4096,4096},{4096,4096,4096,4096,4096,4096,4096,4096,4096,4096,0,0,0,0,0,0,0,0},{},{},{},{},{},{},{},{},{},{},{},{4096,4096,4096,4096,4096,4096,4096,4096,4096,4096,0,0,0,0,0,0,0,0},{4096,32768,32768,32768,32768,32768,32768,32768,32768,4096,4096,4096,4096,4096,4096,4096,4096,4096},{32768,32768,32768,32768,32768,32768,32768,32768,32768,32768,32768,32768,32768,32768,32768,32768,32768,32768},{32768,32768,32768,32768,32768,32768,32768,32768,32768,32768,32768,32768,32768,32768,32768,32768,32768,32768}}",
"",
"local gm = {",
" x = 2,",
" y = math.floor(scr_y/2),",
" score = 0,",
" hiscore = 0,",
" deaths = 0,",
"}",
"local walls = {}",
"",
"local keysDown = {}",
"",
"local inc = function(a)",
" local x,y = term.getCursorPos()",
" term.setCursorPos(x,y+a)",
"end",
"",
"local addWall = function()",
" table.insert(walls,{x=scr_x,y=math.random(4,scr_y-4)})",
"end",
"",
"local moveWalls",
"moveWalls = function()",
" for k,v in pairs(walls) do",
" if walls[k] then",
" walls[k].x = walls[k].x - 1",
" if walls[k].x <= -5 then",
" walls[k] = nil",
" moveWalls()",
" break",
" end",
" end",
" end",
"end",
"",
"local renderBG = function(scroll,bgscroll)",
" local ivl = 5 --interval",
" local skew = 2",
" term.setBackgroundColor(colors.black)",
" term.clear()",
" local pos = (ivl - scroll) + 1",
" while pos <= scr_x do",
" local endpos = ((pos-(scr_x/2))*(skew))+(scr_x/2)",
" local midpos = ((pos-(scr_x/2))*(skew*0.8))+(scr_x/2) -- skew*0.75 is perfect lines",
" paintutils.drawLine(endpos, scr_y, midpos, scr_y*0.75, colors.cyan) --render bottom",
" paintutils.drawLine(midpos, scr_y*0.75, pos , scr_y*0.5, colors.lightBlue) --render bottom",
" paintutils.drawLine(endpos, 1, midpos, scr_y*0.25, colors.cyan) --render top",
" paintutils.drawLine(midpos, scr_y*0.25, pos, scr_y*0.5, colors.lightBlue) --render top",
" pos = pos + ivl",
" end",
" for x = 1-bgscroll, scr_x, 18 do",
" paintutils.drawImage(sprite.bg,x,1)",
" end",
"end",
"local gap = 6",
"local t = term.current().setVisible",
"",
"local checkCollision = function()",
" for k,v in pairs(walls) do",
" if gm.x >= v.x-3 and gm.x <= v.x+3 then --intentionally allowed front and back to touch wall",
" if math.abs((gm.y+1) - v.y) >= (gap/2)-1 then",
" return false",
" end",
" end",
" end",
" return true",
"end",
"",
"local render = function(scroll,bgscroll)",
" if t then t(false) end",
" renderBG(scroll,bgscroll)",
" paintutils.drawImage(sprite.guy,gm.x,gm.y)",
" ",
" for k,v in pairs(walls) do",
" paintutils.drawImage(sprite.uw,v.x,v.y+(gap/2))",
" paintutils.drawImage(sprite.dw,v.x,(v.y-(gap/2))-scr_y)",
" end",
" ",
" term.setCursorPos(2,1)",
" term.setBackgroundColor(colors.black)",
" term.clearLine()",
" write(\"SCORE: \"..gm.score..\" \")",
" if t then t(true) end",
"end",
"",
"local game = function()",
" local scroll = 1",
" local frame = 0",
" local maxframe = 32",
" local bgscroll = 0",
" while true do",
" render(math.floor(scroll),math.floor(bgscroll))",
" scroll = scroll + 0.5",
" frame = frame + 1",
" bgscroll = bgscroll + 2",
" if scroll % 5 == 0 then",
" scroll = 0",
" end",
" if frame == maxframe then",
" addWall()",
" frame = 1",
" end",
" if bgscroll % 18 == 0 then",
" bgscroll = 0",
" end",
" moveWalls()",
" ",
" if keysDown[keys.up] and gm.y > 2 then",
" gm.y = gm.y - 1",
" end",
" if keysDown[keys.down] and gm.y < scr_y-3 then",
" gm.y = gm.y + 1",
" end",
" local isHit = not checkCollision()",
" if isHit then",
" return",
" end",
" gm.score = gm.score + 1",
" if gm.hiscore < gm.score then --conglaturations",
" gm.hiscore = gm.score",
" end",
" sleep(0)",
" end",
"end",
"",
"local getInput = function()",
" while true do",
" local evt, key = os.pullEvent()",
" if evt == \"key\" then",
" keysDown[key] = true",
" elseif evt == \"key_up\" then",
" keysDown[key] = false",
" end",
" if key == keys.q then",
" return",
" end",
" end",
"end",
"",
"local cleanExit = function()",
" term.setBackgroundColor(colors.black)",
" term.setTextColor(colors.white)",
" term.clear()",
" term.setCursorPos(1,1)",
" print(\"Thanks for playing!\")",
" if t then t(true) end",
" sleep(0.05)",
"end",
"",
"local showTitle = function()",
" if gm.deaths == 0 then",
" local x = -38",
" local y = scr_y",
" repeat",
" y = y - 1",
" x = x + 2",
" if t then t(false) end",
" term.setBackgroundColor(colors.black)",
" term.clear()",
" paintutils.drawImage(sprite.guybig,math.floor(x),math.floor(y))",
" if t then t(true) end",
" sleep(0)",
" until y <= -24",
" end",
" term.setBackgroundColor(colors.white)",
" term.clear()",
" sleep(0)",
" term.setBackgroundColor(colors.black)",
" term.clear()",
" paintutils.drawImage(sprite.title,3,2)",
" sleep(0.1)",
" term.setCursorPos(4,scr_y)",
" term.setTextColor(colors.white)",
" term.setBackgroundColor(colors.black)",
" term.write(\"PUSH ANY KEY TO NEXT\")",
" term.setCursorPos(2,1)",
" write(\"TOP: \"..gm.hiscore..\" | LAST: \"..gm.score)",
" os.pullEvent(\"char\")",
"end",
"",
"while true do",
" showTitle()",
" walls = {}",
" gm.y = math.floor(scr_y/2)",
" gm.score = 0",
" keysDown = {}",
" local res = parallel.waitForAny(getInput,game)",
" if res == 2 then",
" gm.deaths = gm.deaths + 1",
" else",
" cleanExit()",
" break",
" end",
"end",
},
[ "/game/data/sprites/stickdude/walkshoot4.nft" ] = {
"ž0€f„e†",
"‹Ÿe“",
"  f0•  fe‚",
"˜‰",
"•˜",
},
[ "/game/data/sprites/megaman/climb2.nft" ] = {
"  bffb",
"bf—fbŸbfŽ3ƒb",
"3f•b”b€33€bb€f‚",
"3Šbšb€3ƒb€3Šf—fb”",
"  f3‹3f‰bŒŒ3b‚f•",
"3fŸƒb3ƒ3fŠf3‹…",
"3Šbƒfb›bf3b‡",
"  bf•fbŸ3Šb‡fb•",
"  bf•b€f•",
"  fb‹…",
},
[ "/game/data/sprites/stickdude/walk4.nft" ] = {
"ž0€f„",
"‹Ÿ",
"  f0•",
"˜‰",
"•˜",
},
[ "/game/data/sprites/megaman/jump.nft" ] = {
"bf‡‹  bf‡ƒf3›„  bf‡‹",
"b‹bfŠ‹3—bb€03fŒfb…bf‡…fb‡",
"  fb‚bff3–0b•0€fŠf0•b3fb",
"  3f”‰0˜f€3f3–",
"  33€€€€",
"  3bb€€3‡b3Ÿ",
"  33€f—  bf”b€f‹",
"  bf‚  fbƒƒ",
"  bf•b€",
},
[ "/toy/nftedemo.lua" ] = {
"local nftePath = \"/nfte\"",
"if not fs.exists(nftePath) then",
" local haych = http.get(\"https://raw.githubusercontent.com/LDDestroier/NFT-Extra/master/nfte.lua\")",
" if haych then",
" local file = fs.open(nftePath, \"w\")",
" file.write(haych.readAll())",
" file.close()",
" else",
" error(\"Can't download NFTE! How can I work as a good demo now!?\")",
" end",
"end",
"",
"nfte = dofile(\"nfte\")",
"",
"local scr_x, scr_y = term.getSize()",
"local mx, my = scr_x / 2, scr_y / 2",
"local x, y = mx, my",
"",
"-- demo image, a creepy face thing",
"local origImage = {",
" {",
" \" \",",
" \" \",",
" \" \",",
" \" \",",
" \" \",",
" \" \",",
" \" \",",
" \" \",",
" \" \",",
" \" \",",
" \" \",",
" \" \",",
" \" \",",
" \" 19x14 \",",
" },",
" {",
" \" fff fff \",",
" \" fffff fffff \",",
" \" fff7f fff7f \",",
" \" fffff fffff \",",
" \" fff fff \",",
" \" ffffff \",",
" \" ffffffffff \",",
" \" fffffffffffffff \",",
" \" f77fffffffffff7f \",",
" \" f77ffffffffff7777f\",",
" \"f77ffffffffff77777f\",",
" \"f77fffffffffff7777f\",",
" \"f77ffffffffffff777f\",",
" \"fffffffffffffffffff\",",
" },",
" {",
" \" 000 000 \",",
" \" 00000 00000 \",",
" \" 000f0 000f0 \",",
" \" 00000 00000 \",",
" \" 000 000 \",",
" \" aaaaaa \",",
" \" aaa22222aa \",",
" \" eeeaaa222222aaa \",",
" \" effaa222222aaafe \",",
" \" effaa222222aaffffe\",",
" \"effaa2222a22afffffe\",",
" \"effa222aa222aaffffe\",",
" \"effa22aa22222aafffe\",",
" \"eeeeeeeeeeeeeeeeeee\",",
" },",
"}",
"local image = origImage",
"",
"local render = function()",
" term.setBackgroundColor(colors.black)",
" while true do",
" term.clear()",
" nfte.drawImageCenter(",
" image,",
" math.floor(x),",
" math.floor(y)",
" )",
" sleep(0.05)",
" end",
"end",
"",
"local demo = function()",
" sleep(0.5)",
" local ox, oy = nfte.getSize(origImage)",
" for i = 0, 10 do",
" image = nfte.stretchImage( origImage, ox + i * 5, oy + i, true )",
" sleep(0.05)",
" end",
" sleep(0.1)",
" for i = 10, -4, -1 do",
" image = nfte.stretchImage( origImage, ox + i * 5, oy + i, true )",
" sleep(0.05)",
" end",
" sleep(0.1)",
" for i = -4, 0 do",
" image = nfte.stretchImage( origImage, ox + i * 5, oy + i, true )",
" sleep(0.05)",
" end",
" sleep(0.1)",
" for i = 0, 360, 2 do",
" image = nfte.rotateImage( origImage, math.rad(i) )",
" sleep(0.05)",
" end",
" image = origImage",
" sleep(0.05)",
" for i = ox, -ox*2, -2 do",
" image = nfte.stretchImage( origImage, i, oy, true )",
" sleep(0.05)",
" end",
" sleep(0.05)",
" for i = oy, -oy*2, -2 do",
" image = nfte.stretchImage( origImage, -ox*2, i, true )",
" sleep(0.05)",
" end",
" sleep(0.05)",
" for i = -ox*2, ox, 2 do",
" image = nfte.stretchImage( origImage, i, -oy*2, true )",
" sleep(0.05)",
" end",
" sleep(0.05)",
" for i = -oy*2, oy, 2 do",
" image = nfte.stretchImage( origImage, ox, i, true )",
" sleep(0.05)",
" end",
" sleep(0.1)",
" for i = 1, 4 do",
" if i % 2 == 0 then",
" image = origImage",
" sleep(0.25)",
" else",
" image = nfte.grayOut(origImage)",
" sleep(0.5)",
" end",
" end",
" sleep(0.2)",
" for i = 0, 2 do",
" image = nfte.lighten(origImage, i)",
" sleep(0.1)",
" end",
" sleep(1)",
" for i = 1, -2, -1 do",
" image = nfte.lighten(origImage, i)",
" sleep(0.1)",
" end",
" sleep(1)",
" for i = -2, 0 do",
" image = nfte.lighten(origImage, i)",
" sleep(0.1)",
" end",
" sleep(0.2)",
" for i = 0, 4 do",
" image = nfte.pixelateImage(origImage, i, i)",
" sleep(0.2)",
" end",
" sleep(0.5)",
" for i = 4, 0, -1 do",
" image = nfte.pixelateImage(origImage, i, i)",
" sleep(0.2)",
" end",
"end",
"",
"-- I use parallel because it's easier, hoh.",
"parallel.waitForAny(render, demo)",
},
[ "/game/data/sprites/stickdude/walk3.nft" ] = {
"ž0€f„",
"‹Ÿ",
"  f0•",
"˜‰",
"0fš  f0‚",
},
[ "/game/data/sprites/stickdude/slide.nft" ] = {
"",
"0f‡ƒf0",
"0ff0„",
"•0fŸf0",
"‰0fŽ",
},
[ "/game/data/sprites/stickdude/stand1.nft" ] = {
"ž0€f„",
"‹Ÿ",
"  f0•",
"˜‰",
"•  f0•",
},
[ "/game/data/sprites/megaman/stand2.nft" ] = {
"  bf‡ƒf3›„",
"  3f—bb€03fŒfb…",
"  f3‚0b•fŒŒˆf0‘",
"  bfƒ33€f‰f0Œ0f™3ƒfb”",
"bf•ˆf33€€€f•bfœb€",
"b‚ƒ3fŸb3b€3ŸbfŠfb‚ƒ",
"  bfb€3‹f‹bƒfŠfb",
"bƒƒƒ  fbƒƒƒ",
},
[ "/game/data/sprites/megaman/slide.nft" ] = {
"",
"  bfŸ3“f3bfŸfb",
"  3fŸbb€€fŠf3Œb–b€f…",
"  f3Š0b—0€fƒb—0•3fŸ",
"  3fŸƒf3›0Ÿƒ‹3fŽ3€bfŠƒfb„",
"  bb€f3ƒ3fƒb3fb•‚",
"bfŸ„Š  f3‚‹b3b—f‚bƒƒb€f‹",
"b‚  fbƒƒ‹",
},
[ "/game/data/sprites/stickdude/shoot.nft" ] = {
"ž0€f„e†",
"‹Ÿe“",
"  f0•  fe‚",
"˜‰",
"•  f0•",
},
[ "/game/data/maps/testmap.nft" ] = {
"  ff",
"  ff",
"  ff",
"  ff  ff  ff  ff  ff",
"  70Ÿ‹08 \\  ff  ff  ff  ff  ff  ff  ff",
"  87  70•€07•8 \\  87  ff  ff  ff  ff  ff",
"  87¨¨¨¨¨¨  07‚‡8   87¨¨¨¨¨¨  ff  ff  ff  ff  ff",
"  87¨¨¨¨¨¨78­  7887¨¨¨¨¨¨  ff  ff  ff  ff  ff  ff",
"  87¨¨¨¨¨¨¨¨¨¨78­  87¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨  ff  ff  ff  ff",
"  87¨¨¨¨¨¨¨¨¨¨¨78­  87¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨  ff  ff  ff  ff  ff  ff",
"  87¨¨¨¨¨¨  878­  87¨¨¨¨¨¨  ff",
"  87¨¨¨¨¨¨  878­  87¨¨¨¨¨¨  ff",
"  87¨¨¨¨¨¨  878­  87¨¨¨¨¨¨  08°°°°°°°  08°°°°°°°°°",
"  87¨¨¨¨¨¨  878­  87¨¨¨¨¨¨  08°°°°°°°°°°°°°°°°°°°°°°°°°°°",
"  87¨¨¨¨¨¨  878­  87¨¨¨¨¨¨  08°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°",
"  87¨¨¨¨¨¨  878­  87¨¨¨¨¨¨  08°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°  08°°°°°°°°°°°°°°°°°°°°  08°°°°°  f7f7You stand at the edge of the world.f7Come on and slam.f7And welcome to the jam.",
"  87¨¨¨¨¨¨  878­  87¨¨¨¨¨¨  08°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°80°°  08°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°",
"  c1  87¨¨¨¨¨¨  878­  87¨¨¨¨¨¨  08°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°80°°°  08°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°",
"  d7   d7   c1  87¨¨¨¨¨¨  878­  87¨¨¨¨¨¨  08°°°°°°°°°°°°°°°°°°°°°°°°°°°°80°°°°°  08°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°",
"d7 8¨¨¨d 8¨¨¨¨¨¨d   c130///c130///7 c130////c130///7 c1  87¨¨¨¨¨¨  878­  87¨¨¨¨¨¨  08°°°°°°°°80°°08°°°°°°°°°°°°80°°°°°°°  08°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°80°",
"87¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨d   c130///c130//7 c130///7 c130///7 c1  87¨¨¨¨¨¨  878­  87¨¨¨¨¨¨  80°°°°°  80°°°°08°°°°80°°°°°°°°  08°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°80°°",
"87¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨d   c130////7 c130///7 c130//7 c130////7 c1  87¨¨¨¨¨¨  878­  87¨¨¨¨¨¨  80°°°°°  08°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°80°°",
"87¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨  c130///7 c130//7 c130//7 c130///7 c1  87¨¨¨¨¨¨78  78­87¨¨¨¨¨¨  08°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°80°°°",
"87¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨  c130//7 c130//7 c130/7 c130///7 c1  87¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨  78­87¨¨¨¨¨¨¨¨¨¨  08°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°80°°°°",
"87¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨  c137 c130/7 c137 c130//7 c1  d7   87¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨  78­87¨¨¨¨¨¨¨¨¨¨¨  08°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°80°°°°°",
"87¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨  c137 c137 c137 c137 c1d7 c³³³³³³³³³³³³³d   87¨¨¨¨¨¨  78­8  87¨¨¨¨¨¨  08°°°°°°°°°°°°°°°°°°°°°°°°°°°°°80°°°°°°°",
"87¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨  c137 c137 c17³³³³³³³³³³³³³³³³³³³³³³³³³³³³³³³³³³³³³  87¨¨¨¨¨¨  78­8  87¨¨¨¨¨¨  80°°°°°°°°08°°°°°°°°°°°°°°°°80°°°°°°",
"87¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨  c1  c17³³³³³³³³³³³³³³³³³³³³³³³³³³³³³³³³³³³³³³  87¨¨¨¨¨¨  78­8  87¨¨¨¨¨¨  80°°°°°°°°°°°°°°°°°°°",
"87¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨  c1  87¨¨¨¨c³³³³³³³³³³³³³³³³³³³³³³³³³³8¨¨¨¨¨¨c³³³  87¨¨¨¨¨¨  78­8  87¨¨¨¨¨¨",
"87¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨  c1  87¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨  87  78­8  87¨¨¨¨¨¨",
"87¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨  c1  87¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨  78­8  87¨¨¨¨¨¨",
"87¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨  87¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨  78­8  87¨¨¨¨¨¨",
"87¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨  87¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨  78­8  87¨¨¨¨¨¨",
"87¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨  87¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨  78­8  87¨¨¨¨¨¨",
"87¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨  87¨¨¨¨fSlide with down+jump7¨¨¨¨  78­8  87¨¨¨¨¨¨",
"87¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨  87¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨  78­8  87¨¨¨¨¨¨",
"87¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨  78  78­8  87¨¨¨¨¨¨",
"87¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨  d5%%%%%%%%%%%%%%%%%%%%%%  78877887¨¨¨¨¨¨",
"87¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨  d5%c7³³³³³³³³³³³³³³³³³³³³³³d5%%  7887¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨",
"87¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨  d5%c7³³³³³³³³³³³³³³³³³³³³³³³³³d5%%%  7887¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨",
"87¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨  d5%c7³³³³0Slopes, up and down!7³³³³³d5%%%%  7887¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨",
"87¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨  d5%c7³³³³³³³³³³³³³³³³³³³³³³³³³³³³³³³³³³d5%%%%%%%%%  d5%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%7887¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨",
"87¨¨¨¨¨¨¨¨¨¨¨¨¨¨f%%%7¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨  d5%c7³³³³³³³³³8¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨c³³³³³³³³³³³³³³³³³d5%%  d5%%c7³³³³³³³³³³³³³³³³³³³³³³³³³³³³³³³³³³³³³³³³³³³³³³³³³³³³³³³³³³³³³³³³³³³³³³³³³³³³³8¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨",
"87¨¨¨¨¨¨¨¨¨¨¨¨¨¨f%%%7¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨d5%%%%%%%%%%%%%%%%%%%%%%%%c7³³³³³³³³8¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨c³³³³³³³³³³³³³³³d5%%%%  d5%%c7³³³³³³³³³³³³³³³³³³³³³³³³³³³³³³³³³³³³³³³³³³³³³³³³³³³³³³³³³³³³³³³³³³³³³³³³³³³³³³³8¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨",
"87¨¨¨¨¨¨¨¨¨¨¨¨f%%%%7¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨c³³³³³³³³³³³³³³³³³³³³³³³³³³³³³³8¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨c³³³³³³³³³³³³³³³³³d5%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%c7³³³³³³³³³³³³³³³³³³³³³³³³³³³³³³³³³³³³³³³³³³³³³³³³³³³³³³³³³³³³³³³³³³³³³³³³³³³³³³³³8¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨",
"87¨¨¨¨¨¨¨¨¨¨¨¨f%%%7¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨c³³³³³³³³³³³³³³³³³³³³³³³³³³³³8¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨c³³³³³³³³³³³³³³³³³³³³³³³³³³³³³³³³³³³³³³³³³³³³³³³³³³³³8¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨c³³³³³³8¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨c³³³³³³³³8¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨",
"87¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨c³³³³³³³³³³³³8¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨f%%%7¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨c³³³³³³³³³³³³³³³³³³³³³³³³³³³³³³³³³³³³³³³³8¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨",
"87¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨f%%%%7¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨",
"87¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨f%%%%%7¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨c187¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨",
"87¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨f%%7¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨c187¨¨¨¨¨¨c187¨¨¨¨¨¨¨c187¨¨¨c187¨¨¨¨c187¨¨¨¨c187¨¨¨¨¨c187¨¨¨c187¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨",
"87¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨c187¨¨¨¨c187¨¨¨¨¨¨¨¨¨¨c18c187¨¨¨¨¨¨¨c187¨¨c187¨¨¨¨¨¨¨¨c187¨¨c187¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨",
"87¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨c18c187¨¨¨¨¨¨¨¨¨¨¨¨c187¨¨¨¨¨¨¨¨¨c187¨¨¨¨¨¨¨¨¨¨c187¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨",
"87¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨07¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨c187¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨",
"87¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨0_±±±±_\\/7¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨",
"87¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨0/\\7¨¨¨¨0/\\7¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨",
"87¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨0/7¨¨0\\7¨¨0/7¨¨0\\7¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨",
"87¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨",
"87¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨",
"87¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨",
"87¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨",
"87¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨",
"87¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨",
},
[ "/game/data/sprites/stickdude/jumpshoot.nft" ] = {
"ž0€f„e†",
"‹Ÿe“",
"0fŸš  fe‚",
"•  f0•",
"‰‚",
},
}