Tatantyler

Nethack-Style File RPG

Nov 7th, 2012
516
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 9.31 KB | None | 0 0
  1. local appearanceToFile = {}
  2. local fileToAppearance = {}
  3. local nounToFile = {}
  4. local fileToNoun = {}
  5. local dirObjects = {}
  6.  
  7. math.randomseed(os.clock())
  8.  
  9. local executableObjects = {
  10.     "lever",
  11.     "screen",
  12.     "button",
  13.     "console",
  14.     "terminal",
  15.     "dial",
  16.     "switch",
  17.     "keyboard",
  18.     "mouse",
  19.     "joystick",
  20.     "machine",
  21.     "radio",
  22.     "printer",
  23.     "drive",
  24.     "computer",
  25.     "modem",
  26.     "screen",
  27.     "TARDIS",
  28.     "compiler",
  29.     "robot",
  30.     "spaceship",
  31.     "turtle",
  32.     "cyborg",
  33.     "car",
  34.     "microphone",
  35.     "teleporter",
  36.     --"pirate ninja zombie robot assassin",
  37.     "laser",
  38. }
  39.  
  40. local nonexecutableObjects = {
  41.     "box",
  42.     "ball",
  43.     "block",
  44.     "drawer",
  45.     "chest",
  46.     "wire",
  47.     "sword",
  48.     "shovel",
  49.     "pick",
  50.     "axe",
  51.     "table",
  52.     "bed",
  53.     "bookshelf",
  54.     "cabinet",
  55.     "picture",
  56.     "antenna",
  57.     "boiler",
  58.     "furnace",
  59.     "table",
  60.     "sheep",
  61.     "flashdrive",
  62.     "pirate",
  63.     "ninja",
  64.     "zombie",
  65.     "cat",
  66.     "sandwich",
  67.     "bukkit",
  68.     "bucket",
  69.     "wrench",
  70.     "shoe",
  71.     "cow",
  72.     "shark",
  73.     "kidney",
  74.     "bean",
  75.     "dictionary",
  76.     "scripter",
  77.     "lunatic",
  78.     "girl",
  79.     "boy",
  80.     "man",
  81.     "woman",
  82.     "dwarf",
  83.     "elf",
  84.     "concept",
  85. }
  86.  
  87. local adjectives = {
  88.     "wonderous",
  89.     "milky",
  90.     "translucent",
  91.     "mysterious",
  92.     "brilliant",
  93.     "fiery",
  94.     "burning",
  95.     "icy",
  96.     "frozen",
  97.     "old",
  98.     "ancient",
  99.     "sandy",
  100.     "monochrome",
  101.     "clear",
  102.     "distorted",
  103.     "shifting",
  104.     "talking",
  105.     "purple",
  106.     "chartreuse",
  107.     "murderous",
  108.     "menacing",
  109.     "sapphire",
  110.     "violet",
  111.     "light blue",
  112.     "red",
  113.     "green",
  114.     "blue",
  115.     "grey",
  116.     "gold",
  117.     "Advanced",
  118. }
  119.  
  120. local function generateAppearance(dir, appearance, executable)
  121.     local descStr = ""
  122.     local object = "object"
  123.     math.randomseed(os.clock()+math.random(1,1000))
  124.     local scpRand = math.random(1, 100)
  125.     math.randomseed(os.clock()+math.random(1,1000))
  126.     if executable then
  127.         object = executableObjects[math.random(1,#executableObjects)]
  128.     else
  129.         object = nonexecutableObjects[math.random(1,#nonexecutableObjects)]
  130.     end
  131.     math.randomseed(os.clock()+math.random(1,1000))
  132.     local adjective = adjectives[math.random(1,#adjectives)]
  133.     if scpRand == 52 then
  134.         object = "[DATA EXPUNGED]"
  135.     end
  136.     descStr = appearance..adjective.." "..object
  137.     if appearanceToFile[dir][descStr] or nounToFile[dir][object] then
  138.         return generateAppearance(dir,appearance,executable)
  139.     else
  140.         return descStr, object
  141.     end
  142. end
  143.  
  144. local function generateObject(base, name)
  145.     local file = fs.combine(base, name)
  146.     local size = fs.getSize(file)
  147.     local func, err = loadfile(file)
  148.     local executable = false
  149.     local appearance = ""
  150.     if func then
  151.         executable = true
  152.     end
  153.     if size > 10240 then -- 10 kb
  154.         appearance = "a colossal "
  155.     elseif size >= 9216 and size < 10240 then
  156.         appearance = "a huge "
  157.     elseif size >= 8192 and size < 9216 then
  158.         appearance = "a bulky "
  159.     elseif size >= 7168 and size < 8192 then
  160.         appearance = "a large "
  161.     elseif size >= 2048 and size < 7168 then
  162.         appearance = "a medium-sized "
  163.     elseif size >= 1024 and size < 2048 then
  164.         appearance = "a small "
  165.     elseif size < 1024 then
  166.         appearance = "a tiny "
  167.     else
  168.         appearance = ""
  169.     end
  170.     appearance, noun = generateAppearance(base, appearance, executable)
  171.    
  172.     if dirObjects[base] then
  173.         dirObjects[base][file] = appearance
  174.         dirObjects[base][appearance] = file
  175.     else
  176.         dirObjects[base] = {[file] = appearance, [appearance] = file}
  177.     end
  178.    
  179.     if fileToAppearance[base] then
  180.         fileToAppearance[base][file] = appearance
  181.     else
  182.         fileToAppearance[base] = {[file] = appearance}
  183.     end
  184.    
  185.     if appearanceToFile[base] then
  186.         appearanceToFile[base][appearance] = file
  187.     else
  188.         appearanceToFile[base] = {[appearance] = file}
  189.     end
  190.    
  191.     if nounToFile[base] then
  192.         nounToFile[base][noun] = file
  193.     else
  194.         nounToFile[base] = {[noun] = file}
  195.     end
  196.    
  197.     if fileToNoun[base] then
  198.         fileToNoun[base][file] = noun
  199.     else
  200.         fileToNoun[base] = {[file] = noun}
  201.     end
  202. end
  203.  
  204. local function generateRoom(dir, showFileNames)
  205.     term.clear()
  206.     term.setCursorPos(1,1)
  207.     print("You see:")
  208.     local files = fs.list(dir)
  209.     local newGen = (dirObjects[dir] == nil)
  210.     if newGen then
  211.         dirObjects[dir] = {}
  212.         appearanceToFile[dir] = {}
  213.         fileToAppearance[dir] = {}
  214.         nounToFile[dir] = {}
  215.         fileToNoun[dir] = {}
  216.     end
  217.     local filesInDir = {}
  218.     for i,v in ipairs(files) do
  219.         filesInDir[fs.combine(dir, v)] = true
  220.     end
  221.     for i,v in ipairs(files) do
  222.         if dirObjects[dir][fs.combine(dir, v)] == nil then
  223.             if not fs.isDir(fs.combine(dir, v)) then
  224.                 generateObject(dir, v)
  225.             else
  226.                 if v == "underworld" then
  227.                     fileToAppearance[dir][fs.combine(dir, v)] = "a door to the land of dead files"
  228.                     appearanceToFile[dir]["a door to the land of dead files"] = fs.combine(dir, v)
  229.                 elseif v == "rom" then
  230.                     fileToAppearance[dir][fs.combine(dir, v)] = "a door to the land of unchanging files"
  231.                     appearanceToFile[dir]["a door to the land of unchanging files"] = fs.combine(dir, v)
  232.                 else
  233.                     fileToAppearance[dir][fs.combine(dir, v)] = "a door labeled \""..v.."\""
  234.                     appearanceToFile[dir]["a door labeled \""..v.."\""] = fs.combine(dir, v)
  235.                 end
  236.                 nounToFile[dir][v] = fs.combine(dir, v)
  237.                 fileToNoun[dir][fs.combine(dir, v)] = v
  238.             end
  239.         end
  240.     end
  241.     if not newGen then
  242.         local oldObjects = fileToAppearance[dir]
  243.         for i,v in pairs(oldObjects) do
  244.             if not filesInDir[i] then
  245.                 dirObjects[dir][i] = nil
  246.             end
  247.         end
  248.         for i,v in pairs(oldObjects) do
  249.             if not filesInDir[i] then
  250.                 appearanceToFile[dir][fileToAppearance[dir][i]] = nil
  251.                 fileToAppearance[dir][i] = nil
  252.             end
  253.         end
  254.         local oldNouns = fileToNoun[dir]
  255.         for i,v in pairs(oldNouns) do
  256.             if not filesInDir[i] then
  257.                 nounToFile[dir][fileToNoun[dir][i]] = nil
  258.                 fileToNoun[dir][i] = nil
  259.             end
  260.         end
  261.     end
  262.     for i,v in pairs(fileToAppearance[dir]) do
  263.         if showFileNames then
  264.             print(i..": "..v)
  265.         else
  266.             print(v)
  267.         end
  268.     end
  269. end
  270.  
  271. local function parseCommand(cmd)
  272.     local words = {}
  273.     for word in string.gmatch(cmd, "%S+") do
  274.         table.insert(words, word)
  275.     end
  276.     if words[1] == nil then
  277.         words[1] = "help"
  278.     end
  279.     if words[2] == nil then
  280.         words[2] = "me"
  281.     end
  282.     local verb = string.lower(words[1])
  283.     local target = words[2]
  284.     for i=3, #words do
  285.         target = target.." "..words[i]
  286.     end
  287.     if verb == "slay" or verb == "destroy" or verb == "kill" then
  288.         print("Before "..verb.."ing this poor "..target..", maybe you should think if this is a wise option.")
  289.         write("Do you want to do this? >")
  290.         local yn = string.lower(string.sub(read(), 1,1))
  291.         if yn == "y" then
  292.             if not fs.exists("underworld") then
  293.                 fs.makeDir("underworld")
  294.             end
  295.             fs.move(nounToFile[shell.dir()][target], fs.combine("underworld", nounToFile[shell.dir()][target]))
  296.         else
  297.             print("After thinking carefully, you lower your weapon.")
  298.         end
  299.     elseif verb == "use" then
  300.         local programArgs = {}
  301.         print("How do you want to use this "..target.."?")
  302.         print("(OOC): program parameters, please:")
  303.         local argStr = read()
  304.         for word in string.gmatch(argStr, "%S+") do
  305.             table.insert(programArgs, word)
  306.         end
  307.         print("You hear the whirrr of unknown machinery in the distance...")
  308.         os.sleep(2)
  309.         term.clear()
  310.         term.setCursorPos(1,1)
  311.         shell.run(nounToFile[shell.dir()][target], unpack(programArgs))
  312.     elseif verb == "copy" or verb == "duplicate" then
  313.         print("What should the duplication look like?")
  314.         print("(OOC): filename, please:")
  315.         local fileName = read()
  316.         fs.copy(nounToFile[shell.dir()][target], fs.combine(shell.dir(), fileName))
  317.     elseif verb == "move" or verb == "transmute" then
  318.         print("What should you transmute this to?")
  319.         print("(OOC): filename, please:")
  320.         local fileName = read()
  321.         fs.move(nounToFile[shell.dir()][target], fs.combine(shell.dir(), fileName))
  322.     elseif verb == "exit" then
  323.         shell.setDir("")
  324.         error("Suddenly, the dungeon collapses!")
  325.     elseif verb == "walk" or verb == "run" then
  326.         if target == "back" then
  327.             shell.setDir("/")
  328.             print("You quickly "..verb.." back to where you started.")
  329.             return
  330.         end
  331.         if fs.isDir(nounToFile[shell.dir()][target]) then
  332.             shell.setDir(fs.combine(shell.dir(), nounToFile[shell.dir()][target]))
  333.             print("You walk through the door...")
  334.         else
  335.             print("You walk straight into the "..target..".")
  336.         end
  337.     elseif verb == "examine" or verb == "look" then
  338.         if target == nil then
  339.             print("This room looks familiar.")
  340.             print("You decide to call it: "..fs.getName(shell.dir()))
  341.         else
  342.             print("When you think about it, this looks familiar.")
  343.             print("You decide to call it "..nounToFile[shell.dir()][target]..".")
  344.         end
  345.     else
  346.         term.clear()
  347.         term.setCursorPos(1,1)
  348.         print("Commands:")
  349.         print("slay/destroy/kill: delete")
  350.         print("use: run")
  351.         print("move/transmute: move")
  352.         print("walk/run: change directory")
  353.         print("copy/duplicate: copy")
  354.         print("examine/look: Find an object's filename")
  355.         print("exit: self-explanatory")
  356.         print("of note are the walk/run commands; instead of taking a noun as a parameter, they take a folder name.")
  357.         print("you can also \"run back\", which is the same as \"cd \\\".")
  358.         print("Files are objects; folders are doors.")
  359.         print("A machine is an executable file; anything else (besides a \"door\") is a data (non-executable) file.")
  360.     end
  361. end
  362.  
  363. shell.setDir("/")
  364.  
  365. local args = {...}
  366. local fNames = true
  367.  
  368. if args[1] == "--no-file-names" then
  369.     fNames = false
  370. end
  371.  
  372. while true do
  373.     generateRoom(shell.dir(), fNames)
  374.     write("What do you do? >")
  375.     parseCommand(read())
  376.     while true do
  377.         local event, key = os.pullEvent("key")
  378.         if key ~= 1 then
  379.             break
  380.         end
  381.     end
  382. end
Add Comment
Please, Sign In to add comment