local tArg = {...} local selfDelete = false -- if true, deletes extractor after running local file local outputPath = "gametest" local safeColorList = {[colors.white] = true,[colors.lightGray] = true,[colors.gray] = true,[colors.black] = true} local stc = function(color) if (term.isColor() or safeColorList[color]) then term.setTextColor(color) end end local choice = function() local input = "yn" write("[") for a = 1, #input do write(input:sub(a,a):upper()) if a < #input then write(",") end end print("]?") 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 archive = textutils.unserialize("{\ mainFile = \"game.lua\",\ compressed = false,\ data = {\ [ \".game/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/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/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/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/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/sprites/megaman/teleport2.nft\" ] = \"\\\ \\\ \\\ \\\ \\\ \\\ \\\   bfŸ3ƒƒ‹\\\ b‹bf3b…b33bŸ”ŠfŸ‡\\\   3bœb3‹…3bb3Š“\\\   fb‚ƒƒƒƒƒ3ƒb\",\ [ \".game/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‚ƒƒƒ\",\ [ \".game/sprites/megaman/buster2-1.nft\" ] = \"  4f\\\ 4fŸ‡040€€4‚f”\\\ 4‚‹00€€4Ÿf4…\\\   f4ƒƒ\",\ [ \".game/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€\",\ [ \".game/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/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‹ƒ\",\ [ \".game/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/sprites/megaman/buster1.nft\" ] = \"f€4f€\\\ 4Š4€0‹f4…\",\ [ \".game/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/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/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/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/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/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/maps/testmap.nft\" ] = \"  47 \\\   07   07   47 \\\ 07   47 3 4 3 4 3 4 3 4 \\\ 07   47 3 4 3 4 3 4 3 4 \\\ 07   47 3 4 3 4 3 4 3 4   07   07 \\\ 07   47 3 4 3 4 3 4 3 4   07 \\\ 07   47 3 4 3 4 3 4 3 4   07 \\\ 07   47 3 4 3 4 3 4 3 4   07   07 \\\ 07   47 3 4 3 4 3 4 3 4 0   07 \\\ 07   47 3 4 3 4 0   07 \\\ 07   47   47 0   07 \\\ 07   47 You can hit your   07   07 \\\ 07   47 head on the roof!   07   07 \\\ 07   47   07   07 \\\ 07   07 Sliding!   07 \\\ 07   07 (Down and Jump)   07 \\\ 07   07   07 \\\ 07   07   07 \\\ 07   07   07 \\\ 07   07   07 \\\ 07   07   07   07 \\\ 07   07 Slopes!   07   07 \\\ 07   07   07   07 \\\ 07   07   07   07 e 0 \\\ 07   07 Look at my engine!   07   07 e 0 \\\ 07   07 I spent too much   07   07 e 0 \\\ 07 time on this   07 Pits!   07 e 0 \\\ 07   07 e 0 \\\ 07   07 Scrolling!   07   e7 \\\   07   07   e7 0   e7 \\\   07   c7   c7   c7   c7   c7   c7   c7   e7   e7 Q to \\\   07   c7   c7   c7   c7   c7   c7   c7   c7   e7   e7 \\\   07   c7   c7   c7   c7   c7   c7   c7   c7   e7   e7 quit \\\   07   c7   c7   c7   c7   c7   c7   c7   c7   e7   e7 \\\   c7   c7   c7   c7   c7   e7   e7 \\\   c7   e7   e7 \\\   e7   e7 \\\   e7   e7 \\\   e7   e7 \",\ [ \".game/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/sprites/megaman/buster3-4.nft\" ] = \"\\\ \\\   4fŸ0‡ƒƒf4\\\ 4Š40Ÿ0€€€f•\\\   f4‚0ƒ4ƒ\",\ [ \".game/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.lua\" ] = \"local game = {}\\\ game.path = fs.combine(fs.getDir(shell.getRunningProgram()),\\\".game\\\")\\\ 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\\\")\\\ game.configPath = fs.combine(game.path, \\\"config.cfg\\\")\\\ \\\ 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 = 10, -- hitbox x size\\\ ysize = 8, -- 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 = 3, -- 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\\\ 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\\\ \\\ 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],\\\ shoot = keyList[keys.z]\\\ }\\\ end\\\ \\\ -- 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\\\ end\\\ end\\\ return false\\\ end\\\ \\\ you = 1\\\ players[you] = newPlayer(\\\"LDD\\\", \\\"megaman\\\", 40, 8)\\\ \\\ 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\\\ grounded = true\\\ else\\\ player.xvel = 0\\\ break\\\ end\\\ else\\\ 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 = 32,\\\ cycle = 0,\\\ phaze = false,\\\ }\\\ 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 player.control.down and player.cycle.slide == 0 then\\\ player.cycle.slide = 6\\\ elseif 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\\\ \\\ -- 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 + 2,\\\ 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),\\\ player.y,\\\ 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)\\\ \\\ 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)\\\ \\\ -- projectile management\\\ \\\ 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\\\ table.remove(projectiles, i)\\\ player.shots = player.shots - 1\\\ end\\\ end\\\ \\\ end\\\ end\\\ \\\ local render = function()\\\ tsv(false)\\\ term.clear()\\\ nfte.drawImage(maps[mapname], -scrollX + 1, -scrollY + 1)\\\ for num,player in pairs(players) do\\\ term.setCursorPos(1,num)\\\ print(\\\"(\\\" .. player.x .. \\\", \\\" .. player.y .. \\\", \\\" .. tostring(player.shots) .. \\\")\\\")\\\ 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\\\ \\\ -- 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 = -5\\\ 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 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()\\\ players[you].sprite = determineSprite(players[you])\\\ 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/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‚ƒ\",\ [ \".game/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/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ƒƒ\",\ [ \".game/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/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 text, back = \\\" \\\", background or \\\" \\\"\\\ 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 = \\\" \\\", background or \\\" \\\"\\\ 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 = {\\\ [\\\"\\\\129\\\"] = \\\"\\\\130\\\",\\\ [\\\"\\\\131\\\"] = \\\"\\\\131\\\",\\\ [\\\"\\\\132\\\"] = \\\"\\\\136\\\",\\\ [\\\"\\\\133\\\"] = \\\"\\\\138\\\",\\\ [\\\"\\\\134\\\"] = \\\"\\\\137\\\",\\\ [\\\"\\\\135\\\"] = \\\"\\\\139\\\",\\\ [\\\"\\\\140\\\"] = \\\"\\\\140\\\",\\\ [\\\"\\\\141\\\"] = \\\"\\\\142\\\",\\\ [\\\"\\\\143\\\"] = \\\"\\\\143\\\",\\\ }\\\ local xinvertable = {\\\ [\\\"\\\\144\\\"] = \\\"\\\\159\\\",\\\ [\\\"\\\\145\\\"] = \\\"\\\\157\\\",\\\ [\\\"\\\\146\\\"] = \\\"\\\\158\\\",\\\ [\\\"\\\\147\\\"] = \\\"\\\\156\\\",\\\ [\\\"\\\\148\\\"] = \\\"\\\\151\\\",\\\ [\\\"\\\\152\\\"] = \\\"\\\\155\\\"\\\ }\\\ 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\",\ [ \".game/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/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ƒƒƒ\",\ [ \".game/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/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/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/sprites/megaman/buster2-2.nft\" ] = \"\\\ 4fŸ0‡0€4‚f”\\\ 4‚0‹4Ÿ0€4Ÿf4…\",\ },\ }") if fs.isReadOnly(outputPath) then error("Output path is read-only. Abort.") elseif fs.getFreeSpace(outputPath) <= #archive then error("Insufficient space. Abort.") end if fs.exists(outputPath) and fs.combine("", outputPath) ~= "" then print("File/folder already exists! Overwrite?") stc(colors.lightGray) print("(Use -o when making the extractor to always overwrite.)") stc(colors.white) if choice() ~= 1 then error("Chose not to overwrite. Abort.") else fs.delete(outputPath) end end if selfDelete or (fs.combine("", outputPath) == shell.getRunningProgram()) then fs.delete(shell.getRunningProgram()) end for name, contents in pairs(archive.data) do stc(colors.lightGray) write("'" .. name .. "'...") if contents == true then -- indicates empty directory fs.makeDir(fs.combine(outputPath, name)) else file = fs.open(fs.combine(outputPath, name), "w") if file then file.write(contents) file.close() end end if file then stc(colors.green) print("good") else stc(colors.red) print("fail") end end stc(colors.white) write("Unpacked to '") stc(colors.yellow) write(outputPath .. "/") stc(colors.white) print("'.") sleep(0.25) shell.run("/gametest/game.lua")