Kodos

[OC] nanohack.lua

Dec 10th, 2014
299
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 21.56 KB | None | 0 0
  1. -- Controls
  2. -- Upon starting the game, you will be asked to name your adventurer. After this, you descend into the first level of the dungeon -- and begin your adventure.
  3. -- The following commands are available:
  4. -- n, s, e, w: Go north, south, east, or west (if possible)
  5. -- u, d: Go up, down (if possible)
  6. -- a: Attack
  7. -- p: Pick up items
  8. -- x: Wait one turn
  9. -- q: Quit
  10. -- You regain one hitpoint for every turn you wait, but your final score is affected by how many turns you took.
  11.  
  12.  
  13. -- nanohack
  14. --
  15. -- A tiny RPG/roguelike
  16.  
  17. -- TODO enemy following
  18. -- TODO kill scoring
  19. -- TODO spawn weapons, make them equippable
  20. -- TODO add more enemies
  21.  
  22. -- roll is the die roll generator. It takes three arguments, in D&D
  23. -- format: the number of rolls to make, the die to be rolled, and the
  24. -- roll modifier.
  25. --
  26. -- 2d8   -> roll(2, 8)
  27. -- 1d4+1 -> roll(1, 4, 1)
  28.  
  29.  
  30. function roll(spec)
  31.    rolls, die, mod = table.unpack(spec)
  32.    total = 0
  33.    for x = 1, rolls do
  34.       total = total + math.random(1, die)
  35.    end
  36.    total = total + mod
  37.    return total
  38. end
  39.  
  40.  
  41.  
  42. -- -------------------------------------------------- Player
  43.  
  44. -- The player has the following attributes:
  45. --
  46. --     name    Character name
  47. --     hp      Hit points
  48. --     hpmax   Maximum HP
  49. --     hpinit  Initial HP (for scaling score)
  50. --     xp      Experience points
  51. --     lvl     Character level (max: 9)
  52. --     gp      Treasure
  53. --     weapon  Current weapon
  54. --     amulet  Whether the player has the amulet or not
  55. --
  56. -- The player initially has 1d8 HP. This goes up by 1d4 every level.
  57. player = { name = "", xp=0, lvl=1, gp=0, weapon=1, amulet=false }
  58.  
  59. function playergen()
  60.    player.hp     = roll({1, 8, 0})
  61.    player.hpmax  = player.hp
  62.    player.hpinit = player.hp
  63. end
  64.  
  65.  
  66.  
  67. -- -------------------------------------------------- Weapons
  68.  
  69. -- The weapons table describes the available weapons:
  70. --
  71. --    name
  72. --    dmgdice  How much damage the weapon can do
  73. --    tohit    Chance to hit (modified by charlvl / 3)
  74. --             So the max is 6, to produce a 90% hit chance
  75. weapons = {
  76.    { name = "Fists", dmgdice = {1, 2, 0}, tohit = 4 },
  77.    { name = "Dagger", dmgdice = {1, 6, 0}, tohit = 4 },
  78.    { name = "Longsword", dmgdice = {1, 8, 0}, tohit = 5 },
  79.    { name = "Broadsword", dmgdice = {2, 4, 2}, tohit = 5 }
  80. }
  81.  
  82.  
  83.  
  84. -- -------------------------------------------------- Monsters
  85.  
  86. -- The monster_type table defines the various monsters which may be
  87. -- found in the dungeon. Its fields are:
  88. --
  89. --    name     The monster's name
  90. --    hitdice  How many hitpoints it starts with
  91. --    dmgdice  How much damage it does
  92. --    tohit    What the monster has to roll to hit the player
  93. --    alert    The chance a monster will notice the player
  94. --    floor    The highest dungeon floor a monster can spawn on
  95. --    maxgp    How many gp a monster may have
  96. --
  97. -- Monsters are generated when rooms are entered for the first time.
  98. monster_type = {
  99.    { name = "Skeleton", hitdice = {1, 4, 0}, dmgdice = {1, 3, 0}, tohit = 3, floor = 1,
  100.      alert = 3, treasure = {1, 3, 0}, move=true},
  101.    { name = "Big Skelly", hitdice = {2, 2, 2}, dmgdice = {1, 4, 0}, tohit = 3, floor = 3,
  102.      alert = 3, treasure = {2, 4, 0}, move=true },
  103.    { name = "Bugbear", hitdice = {2, 4, 1}, dmgdice = {2, 4, 1}, tohit = 4, floor = 5,
  104.      alert = 4, treasure = {2, 5, 1}, move=true }
  105. }
  106.  
  107. -- The monsters table holds the generated monsters. Its fields are:
  108. --
  109. --     type  The index of the monster_type field corresponding to this monster
  110. --     hp    The monster's current HP
  111. --     gp    How much treasure the monster has
  112. --     seen  Whether the monster has noticed the player
  113. monsters = {}
  114.  
  115. function monsters_attack(floor, room, list)
  116.    for i, m in ipairs(list) do
  117.       if monsters[m].seen == true then
  118.          local name = monster_type[monsters[m].type].name
  119.          if math.random(1,10) <= monster_type[monsters[m].type].tohit then
  120.             local dmg = roll(monster_type[monsters[m].type].dmgdice)
  121.             player.hp = player.hp - dmg
  122.             table.insert(msgs, string.format("The %s attacks and hits for %dHP!", name, dmg))
  123.          else
  124.             table.insert(msgs, string.format("The %s attacks and misses.", name))
  125.          end
  126.       end
  127.    end
  128. end
  129.  
  130. function monsters_opportunity(floor, room)
  131.    thisroom = floors[floor].rooms[room]
  132.    if #thisroom.monsters == 0 then return end
  133.    live = {}
  134.    for i, m in ipairs(thisroom.monsters) do
  135.       if monsters[m].hp > 0 then table.insert(live, m) end
  136.    end
  137.    for i, m in ipairs(live) do
  138.       if monsters[m].seen == false then
  139.          if math.random(1,10) <= monster_type[monsters[m].type].alert then
  140.             monsters[m].seen = true
  141.             table.insert(msgs, string.format("The %s notices you and moves to attack!", monster_type[monsters[m].type].name))
  142.          end
  143.       end
  144.    end
  145.    monsters_attack(floor, room, live)
  146. end
  147.  
  148.  
  149. -- --------------------------------------------------Dungeon
  150.  
  151. -- Floors of the dungeon are a 3x3 grid of rooms.
  152. --
  153. --     1 2 3
  154. --     4 5 6
  155. --     7 8 9
  156. --
  157. -- One room per floor will be randomly selected to have the down
  158. -- staircase (which automatically sets the up staircase of the next
  159. -- floor. The same room can't have both an up and down staircase.
  160. --
  161. -- Each room has the following attributes:
  162. --
  163. --    monsters  Which monsters (if any) are in the room
  164. --    exits     List of avialable exits
  165. floormap = { {e=2, s=4},      {w=1, s=5, e=3},      {w=2, s=6},
  166.              {n=1, e=5, s=7}, {n=2, w=4, e=6, s=8}, {n=3, w=5, s=9},
  167.              {n=4, e=8},      {w=7, n=5, e=9},      {w=8, n=6} }
  168. dirname  = { n = "north", s = "south", e = "east", w = "west" }
  169. otherdir = { n="s", s="n", e="w", w="e" }
  170. floors = {}
  171. maxfloors = 9
  172.  
  173. function dungeongen()
  174.    while #floors <= maxfloors do
  175.       -- randomize random
  176.       -- make a new floor table
  177.       thisfloor = { rooms = {} }
  178.       for i = 1,9 do thisfloor.rooms[i] = {monsters = {}, exits = {}, visited = false} end
  179.       -- set location of up staircase
  180.       if #floors == 0 then
  181.          thisfloor.upstairs = math.random(1, 9)
  182.       else
  183.          thisfloor.upstairs = floors[#floors].downstairs
  184.       end
  185.       -- set location of down staircase
  186.       if #floors < maxfloors then
  187.          repeat
  188.             thisfloor.downstairs = math.random(1, 9)
  189.          until thisfloor.downstairs ~= thisfloor.upstairs
  190.       end
  191.       -- build connections between rooms
  192.       dungeon_mapgen(thisfloor)
  193.       -- stow the finished floor
  194.       table.insert(floors, thisfloor)
  195.    end
  196. end
  197.  
  198. function dungeon_mapgen(floor)
  199.    -- initialize list of rooms (true == accessible; false == not)
  200.    local accessiblerooms = { false, false, false, false, false, false, false, false, false, false }
  201.    local closedneighbors = {}
  202.    -- start in room with up staircase
  203.    curroom = floor.upstairs
  204.    accessiblerooms[curroom] = true
  205.    local accessible = 1
  206.    -- pick a random legal room to build an exit to
  207.    while accessible < 9 do
  208.       -- find neighbors of this room without access. if this room has
  209.       -- no such neighbors, pick a random accessible room until one
  210.       -- with inaccessible neighbors is found
  211.       repeat
  212.          closedneighbors = {}
  213.          for k, v in pairs(floormap[curroom]) do
  214.             if accessiblerooms[v] == false then table.insert(closedneighbors, k) end
  215.          end
  216.          if #closedneighbors == 0 then
  217.             repeat
  218.                curroom = math.random(1, #accessiblerooms)
  219.             until accessiblerooms[curroom]
  220.          end
  221.       until #closedneighbors > 0
  222.       -- now that we have a list of rooms to move to, pick one at random
  223.       local exitdir = closedneighbors[math.random(1, #closedneighbors)]
  224.       -- and add it to the current room
  225.       floor.rooms[curroom].exits[exitdir] = true
  226.       -- then lookup the number of the room we've added an exit to,
  227.       -- mark it as accessible, make it the current room, and add a
  228.       -- reciprocal exit
  229.       curroom = floormap[curroom][exitdir]
  230.       accessiblerooms[curroom] = true
  231.       floor.rooms[curroom].exits[otherdir[exitdir]] = true
  232.       -- increment accessible room count
  233.       accessible = accessible + 1
  234.    end
  235. end
  236.  
  237. function populate_room(floor, room)
  238.    -- see if we have monsters
  239.    if math.random(1, 100) <= 30 + (4 * floor - 1) then
  240.       -- ok, how many?
  241.       local num = 1
  242.       local monster_roll = math.random(1, 100)
  243.       if monster_roll >= 97 then
  244.          num = 3
  245.       elseif monster_roll >= 75 then
  246.          num = 2
  247.       end
  248.       -- generate them
  249.       for x = 1, num do
  250.          repeat
  251.             -- make sure we have a floor-appropriate monster
  252.             mid = math.random(1, #monster_type)
  253.          until floor >= monster_type[mid].floor
  254.          monster = {type=mid, seen=false}
  255.          table.insert(monsters, monster)
  256.          -- now gen its stats
  257.          print(string.format("mid = '%d'", mid))
  258.          monster.hp = roll(monster_type[mid].hitdice)
  259.          monster.gp = roll(monster_type[mid].treasure)
  260.          -- and put it in its room
  261.          table.insert(floors[floor].rooms[room].monsters, #monsters)
  262.       end
  263.    end
  264.    -- if we're on floor, 3, 5, or 7, see if a weapon spawns here
  265.    -- if we're on floor 9, see if the amulet is here
  266.    if floor == 9 then
  267.       if math.random(1,10) <= amuletchance then
  268.          floors[floor].rooms[room].amulet = true
  269.          amuletchance = 0
  270.       else
  271.          amuletchance = amuletchance + 1
  272.       end
  273.    end
  274.    -- finally, set the visited flag
  275.    floors[floor].rooms[room].visited = true
  276. end
  277.  
  278. -- -------------------------------------------------- Output utility functions
  279.  
  280. function show_screen(floor, room)
  281.    io.write("\027[2J\027[H")
  282.    show_map(floor, room)
  283.    show_status(floor, room)
  284.    describe_room(floor, room)
  285.    describe_combat()
  286.    describe_monsters(floor, room)
  287. end
  288.  
  289. function show_status()
  290.    print()
  291.    io.write("[ ", player.name," | HP ", player.hp)
  292.    if player.hp == player.hpmax then io.write(" (max)") end
  293.    io.write(" | Lvl ", player.lvl, " | ", weapons[player.weapon].name)
  294.    io.write(" | Gold ", player.gp, " | Floor ", curfloor, " | Turn ", turn, " ]\n\n")
  295. end
  296.  
  297. function describe_room(floor, room)
  298.    if room == floors[floor].upstairs then io.write("There is a staircase leading up here.") end
  299.    if room == floors[floor].downstairs then io.write("There is a staircase leading down here.") end
  300.    if floors[floor].rooms[room].amulet == true then
  301.       print("The amulet is here, gleaming in the torchlight!")
  302.    end
  303.    print()
  304.    show_room_exits(floor, room)
  305. end
  306.  
  307. function describe_monsters(floor, room)
  308.    thisroom = floors[floor].rooms[room]
  309.    -- tell the player about any live monsters
  310.    for i, mid in ipairs(thisroom.monsters) do
  311.       if monsters[mid].hp > 0 then
  312.          io.write("There is a ", monster_type[monsters[mid].type].name, " here. ")
  313.          io.write("It has ", monsters[mid].hp, "HP\n")
  314.       else
  315.          io.write("There is a dead ", monster_type[monsters[mid].type].name, " here.\n")
  316.       end
  317.    end
  318. end
  319.  
  320. function describe_combat()
  321.    for i, line in pairs(msgs) do
  322.       print(line)
  323.    end
  324.    print()
  325. end
  326.  
  327. function show_room_exits(floor, room)
  328.    io.write("\nExits: ")
  329.    for k,v in pairs(floors[floor].rooms[room].exits) do
  330.       io.write(k)
  331.       io.write(" ")
  332.    end
  333.    if room == floors[floor].upstairs then io.write("u") end
  334.    if room == floors[floor].downstairs then io.write("d") end
  335.    io.write("\n")
  336.    print()
  337. end
  338.  
  339. function show_map(floor, room)
  340.    map = { {'','','','',''}, {'','','','',''}, {'','','','',''} }
  341.    for r = 1,9 do
  342.       thisroom = floors[floor].rooms[r]
  343.       if r < 4 then i = 1 elseif r < 7 then i = 2 else i = 3 end
  344.       if thisroom.visited then
  345.          -- north wall
  346.          if thisroom.exits["n"] then map[i][1] = map[i][1] .. "-- --"
  347.          else map[i][1] = map[i][1] .. "-----" end
  348.          -- south wall
  349.          if thisroom.exits["s"] then map[i][5] = map[i][5] .. "-- --"
  350.          else map[i][5] = map[i][5] .. "-----" end
  351.          -- west wall
  352.          if thisroom.exits["w"] then map[i][3] = map[i][3] .. " "
  353.          else map[i][3] = map[i][3] .. "|" end
  354.          -- upstairs/downstairs
  355.          if floors[floor].upstairs == r or floors[floor].downstairs == r then
  356.             if floors[floor].upstairs == r then map[i][3] = map[i][3] .. "<"
  357.             else map[i][3] = map[i][3] .. ">" end
  358.          else map[i][3] = map[i][3] .. " " end
  359.          -- player
  360.          if r == room then map[i][3] = map[i][3] .. "@"
  361.          else map[i][3] = map[i][3] .. " " end
  362.          -- monsters
  363.          if #thisroom.monsters > 0 then map[i][3] = map[i][3] .. "m"
  364.          else map[i][3] = map[i][3] .. " " end
  365.          -- east wall
  366.          if thisroom.exits["e"] then map[i][3] = map[i][3] .. " "
  367.          else map[i][3] = map[i][3] .. "|" end
  368.          -- lines 2, 4
  369.          map[i][2] = map[i][2] .. "|   |"
  370.          if thisroom.amulet == true then
  371.             map[i][4] = map[i][4] .. "| A |"
  372.          else
  373.             map[i][4] = map[i][4] .. "|   |"
  374.          end
  375.       else
  376.          for j = 1, 5 do
  377.             map[i][j] = map[i][j] .. "     "
  378.          end
  379.       end
  380.    end
  381.    for i = 1, 3 do
  382.       for j = 1, 5 do
  383.          print(map[i][j])
  384.       end
  385.    end
  386. end
  387.  
  388. function show_score()
  389.    print("\n\n------------------------------------------ FINAL SCORE")
  390.    score = 0
  391.    -- 10 points for each level over 1
  392.    lvlscore = 10 * (player.lvl - 1)
  393.    io.write(lvlscore, " points for reaching level ", player.lvl, "\n")
  394.    score = score + lvlscore
  395.    io.write(player.gp, " points for your hoard of treasure\n")
  396.    score = score + player.gp
  397.    -- The monsters minimum floor# points for each kill
  398.    -- 50 points for finding the amulet
  399.    if player.amulet then
  400.       print("50 points for looting the amulet!")
  401.       score = score + 50
  402.    end
  403.    -- scale score up by initial HP (difficulty)
  404.    scale = 8 / player.hpinit
  405.    if scale > 1 and player.lvl > 1 then
  406.       str = string.format("Your starting HP was %d, giving a difficulty multiplier of %5.2f", player.hpinit, scale)
  407.       print(str)
  408.       score = score * scale
  409.    end
  410.    -- scale score by turns taken
  411.    if turn > 2 and score > 0 then
  412.       scale = math.log(turn)
  413.       str = string.format("Finally, your elapsed turns score divisor is %5.2f", scale)
  414.       print(str)
  415.       score = score / scale
  416.    end
  417.    str = string.format("YOUR SCORE: %7.2f\n", score)
  418.    print(str)
  419.    os.exit(0)
  420. end
  421.  
  422. -- ---------------------------------------------------------- Command routines
  423.  
  424. function player_nsew(floor, room, dir)
  425.    if floors[floor].rooms[room].exits[dir] == true then
  426.       monsters_opportunity(floor, room)
  427.       if player.hp < 1 then return end
  428.       table.insert(msgs, string.format("You move to the %s", dirname[dir]))
  429.       curroom = floormap[room][dir]
  430.       if floors[floor].rooms[curroom].visited == false then populate_room(floor, curroom) end
  431.       monsters_opportunity(floor, curroom)
  432.    else
  433.       table.insert(msgs, string.format("There is no exit to the %s from here.",  dirname[dir]))
  434.    end
  435. end
  436.  
  437. function player_ud(floor, room, dir)
  438.    if dir == "u" then
  439.       if floors[floor].upstairs == room then
  440.          monsters_opportunity(floor, room)
  441.          if player.hp < 1 then return end
  442.          if floor == 1 then
  443.             print("\nYou climb the stairs and leave the dungeon, alive if not victorious.")
  444.             show_score()
  445.          else
  446.             table.insert(msgs, "You climb the stairs to the previous floor.")
  447.             curfloor = floor - 1
  448.             curroom = floors[curfloor].downstairs
  449.             monsters_opportunity(curfloor, curroom)
  450.          end
  451.       else
  452.          table.insert(msgs, "There is no up staircase here.")
  453.       end
  454.    else
  455.       if floors[floor].downstairs == room then
  456.          monsters_opportunity(floor, room)
  457.          if player.hp < 1 then return end
  458.          table.insert(msgs, "You descend to the next floor.")
  459.          curfloor = floor + 1
  460.          curroom = floors[curfloor].upstairs
  461.          if floors[curfloor].rooms[curroom].visited == false then populate_room(curfloor, curroom) end
  462.          monsters_opportunity(curfloor, curroom)
  463.       else
  464.          table.insert(msgs, "There is no down staircase here.")
  465.       end
  466.    end
  467. end
  468.  
  469. function player_attack(floor, room)
  470.    thisroom = floors[floor].rooms[room]
  471.    if #thisroom.monsters == 0 then
  472.       table.insert(msgs, "There's nothing to attack.")
  473.       return
  474.    end
  475.    live = {}
  476.    local mid = 999
  477.    for i, m in ipairs(thisroom.monsters) do
  478.       if monsters[m].hp > 0 then table.insert(live, m) end
  479.    end
  480.    if #live == 0 then
  481.       table.insert(msgs, "Everything here is dead.")
  482.       return
  483.    elseif #live == 1 then
  484.       mid = live[1]
  485.    else
  486.       for i, m in pairs(live) do
  487.          local name = monster_type[monsters[m].type].name
  488.          if monsters[m].seen == true then
  489.             print(string.format("%d - %s, %dHP (attacking)", i, name, monsters[m].hp))
  490.          else
  491.             print(string.format("%d - %s, %dHP", i, name, monsters[m].hp))
  492.          end
  493.       end
  494.       repeat
  495.          io.write("\nWhich monster to attack? ")
  496.          mid = io.read()
  497.          mid = tonumber(mid)
  498.       until type(mid) == "number" and mid <= #live
  499.       mid = live[mid]
  500.    end
  501.    -- combat is simultaneous, but we let the monsters go "first"
  502.    -- if you hit a monster, it's going to fight you back
  503.    if monsters[mid].seen == false then
  504.       monsters[mid].seen = true
  505.       table.insert(msgs, string.format("The %s fights back!", monster_type[monsters[mid].type].name))
  506.    end
  507.    monsters_opportunity(floor, room)
  508.    -- now carry on with player attacks and resolution
  509.    local dmg = 0
  510.    if player.weapon == 1 then
  511.       for x = 1,2 do
  512.          if weapons[1].tohit <= math.random(1,10) then
  513.             hit = roll(weapons[1].dmgdice)
  514.             table.insert(msgs, string.format("You swing and... HIT, dealing %dHP of damage", hit))
  515.             dmg = dmg + hit
  516.          else
  517.             table.insert(msgs, "You swing and... MISS!")
  518.          end
  519.       end
  520.    else
  521.       if weapons[player.weapon].tohit <= math.random(1,10) then
  522.          dmg = dmg + roll(weapons[player.weapon].dmgdice)
  523.          table.insert(msgs, string.format("You attack with the %s and... HIT, dealing %dHP of damage", weapons[player.weapon].name, hit))
  524.       else
  525.          table.insert(msgs, "You swing and... MISS!")
  526.       end
  527.    end
  528.    if dmg > 0 then
  529.       -- now handle the bookkeeping
  530.       monsters[mid].hp = monsters[mid].hp - dmg
  531.       if monsters[mid].hp <= 0 then
  532.          table.insert(msgs, string.format("The %s is killed.", monster_type[monsters[mid].type].name))
  533.          player.xp = player.xp + 1
  534.          player.gp = player.gp + monsters[mid].gp
  535.          table.insert(msgs, string.format("You get 1XP and %dGP", monsters[mid].gp))
  536.       end
  537.       if player.xp >= player.lvl then
  538.          player.lvl = player.lvl + 1
  539.          player.xp = 0
  540.          table.insert(msgs, "")
  541.          table.insert(msgs, string.format("You have gained a level! You are now level %i", player.lvl))
  542.          if player.hp > 0 then
  543.             local hpup = roll({1, 4, 0})
  544.             player.hpmax = player.hpmax + hpup
  545.             table.insert(msgs, string.format("Your max HP goes up by %d (new max: %d)", hpup, player.hpmax))
  546.          end
  547.       end
  548.    end
  549. end
  550.  
  551. function player_wait(floor, room)
  552.    table.insert(msgs, "You rest for a moment.")
  553.    if player.hp < player.hpmax then
  554.       player.hp = player.hp + 1
  555.       table.insert(msgs, "You regain 1 hitpoint.")
  556.    end
  557.    monsters_opportunity(floor, room)
  558. end
  559.  
  560. function pickup_item(floor, room)
  561.    thisroom = floors[floor].rooms[room]
  562.    if thisroom.amulet == true then
  563.       player.amulet = true
  564.       print("\nYou pick up the gleaming amulet and power surges through you!")
  565.       print("WINNERS DON'T DO DRUGS!!!")
  566.       show_score()
  567.    end
  568.    monsters_opportunity(floor, room)
  569. end
  570.  
  571. function get_player_input()
  572.    cmd = nil
  573.    repeat
  574.       io.write("Command? ")
  575.       cmd = io.read()
  576.       if cmd == "q" then os.exit(0) end
  577.       if cmds[cmd] == nil then
  578.          print("Invalid command")
  579.       else
  580.          return cmd
  581.       end
  582.    until cmds[cmd] ~= nil
  583. end
  584.  
  585. -- -------------------------------------------------------------- Main routine
  586.  
  587. -- When a player leaves the room, all monsters in combat (seen ==
  588. -- true) with the character roll to see if they follow; the chance
  589. -- that they do is the percentage of HP they have remaining. Monsters
  590. -- NOT in combat make a notice roll and automatically follow if they
  591. -- succeed.
  592.  
  593. -- dispatch table
  594. cmds = { n = player_nsew, s = player_nsew, e = player_nsew, w = player_nsew,
  595.          u = player_ud, d = player_ud, x = player_wait, a = player_attack,
  596.          p = pickup_item }
  597.  
  598. -- misc vars
  599. turn = 1
  600. curfloor = 1
  601. amuletchance = 2
  602. msgs = {}
  603.  
  604. math.randomseed( tonumber(tostring(os.time()):reverse():sub(1,6)) )
  605. print("\nNANOHACK VERSION 1.1.0")
  606. io.write("\nWelcome, brave explorer! What is your name? ")
  607. player.name = io.read()
  608. print("\nHail, ".. player.name .. "! May Kodos bless your quest!\n")
  609. playergen()
  610. dungeongen()
  611. print("You open the trapdoor in the back room of the tavern and descend into")
  612. print("  the darkness below. There's some kind of amulet down there, and")
  613. print("  you totally win if you find it!")
  614. io.write("\n\nPress [Enter] to begin...")
  615. io.read()
  616.  
  617. curroom  = floors[curfloor].upstairs
  618. floors[curfloor].rooms[curroom].visited = true
  619.  
  620. while true do
  621.    show_screen(curfloor, curroom)
  622.    if player.hp < 1 then
  623.       print("\nYou have been slain!")
  624.       show_score()
  625.    end
  626.    cmd = get_player_input()
  627.    msgs = {}
  628.    turn = turn + 1
  629.    cmds[cmd](curfloor, curroom, cmd)
  630. end
Add Comment
Please, Sign In to add comment