Advertisement
nitrogenfingers

loderunner

Jun 4th, 2013
256
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 21.22 KB | None | 0 0
  1. --[[
  2.         Code Runner
  3.         Inspired by the game by Doug
  4.  
  5.         Written by: Nitrogen Fingers
  6. ]]--
  7.  
  8. running = true
  9. started = false
  10. nextLevel = false
  11.  
  12. local drawOffsetX = 1
  13. local drawOffsetY = 0
  14.  
  15. local map = {}
  16. local goldMap = {}
  17. local blockTimers = {}
  18. local blockIntv = 5
  19.  
  20. local monks = {}
  21. local monkTimer = -1
  22. local monkSpawnIntv = 3
  23. local monkTrapIntv = blockIntv/2
  24.  
  25. local goldCount = 0
  26. local maxGoldCount = 0
  27. local playerLives = 3
  28. local playerScore = 0
  29. local plspawnX = 0
  30. local plspawnY = 0
  31.  
  32. local plX = 0
  33. local plY = 0
  34. local pfalling = false
  35. local moveTimer = -1
  36. local shootTimer = -1
  37. local spawnTimer = -1
  38. local moveIntv = 0.15
  39.  
  40. local exX = 0
  41. local exY = 0
  42.  
  43. local levelList = {}
  44. local currentLevel = 1
  45.  
  46. local function loadMap(_sPath)
  47.   if not fs.exists(_sPath) then return end
  48.   map = {}
  49.   goldMap = {}
  50.   monks = {}
  51.   goldCount = 0
  52.    
  53.   local file = fs.open(_sPath, "r")
  54.   local line = file:readLine()
  55.   while line do
  56.     goldMap[#map+1] = {}
  57.     map[#map+1] = {}
  58.     for i=1,math.min(#line,49) do
  59.       local lchar = string.sub(line,i,i)
  60.       if tonumber(lchar, 16) then
  61.         lchar = math.pow(2, tonumber(lchar,16))
  62.        
  63.         if lchar == colours.blue then
  64.           map[#map][i] = 0
  65.         elseif lchar == colours.brown then
  66.           map[#map][i] = 'H'
  67.         elseif lchar == colours.yellow then
  68.           goldMap[#map][i] = 1
  69.           goldCount = goldCount + 1
  70.         elseif lchar == colours.orange then
  71.           map[#map][i] = 0
  72.           goldMap[#map][i] = 1
  73.           goldCount = goldCount + 1
  74.         elseif lchar == colours.green then
  75.           map[#map][i] = '-'
  76.         elseif lchar == colours.lightGrey then
  77.           map[#map][i] = 'h'
  78.         elseif lchar == colours.grey then
  79.           map[#map][i] = '#'
  80.         elseif lchar == colours.white then
  81.           plX = i
  82.           plspawnX = i
  83.           plY = #map
  84.           plspawnY = #map
  85.         elseif lchar == colours.lime then
  86.           exX = i
  87.           exY = #map
  88.         elseif lchar == colours.red then
  89.           table.insert(monks, {
  90.             --X and Y, clear enough
  91.             x = i, y = #map;
  92.             --Where they spawn when they die
  93.             spawnX = i, spawnY = #map;
  94.             -- Any gold they're carring- it's a 1 in 5
  95.             gold = false;
  96.             -- Whether or not they're falling
  97.             falling = false;
  98.             -- Timer if they're dead to respawn
  99.             dead = nil;
  100.             --Whether or not the monk has just spawned
  101.             justSpawned = true;
  102.             --Whether or not the monk has just escaped
  103.             justEscaped = false;
  104.             -- Current aim- it's "up", "down", "across" or "none"
  105.             behaviour = "none";
  106.             -- The desired x position to travel to, when one is necessary.
  107.             desX = nil;
  108.             -- The escape timer
  109.             trapped = nil;
  110.           })
  111.         end
  112.       end
  113.     end
  114.     if #map == 18 then break end
  115.     line = file:readLine()
  116.   end
  117.   file:close()
  118.   maxGoldCount = goldCount
  119.   return true
  120. end
  121.  
  122. --When something moves or something needs to be drawn, we
  123. --just change the appropriate tile with this method.
  124. local function updateMap(x,y)
  125.     term.setCursorPos(x + drawOffsetX, y + drawOffsetY)
  126.     term.setBackgroundColour(colours.black)
  127.     if plX == x and plY == y and map[y][x] ~= 0 then
  128.       term.setTextColour(colours.white)
  129.       if map[y][x] == 1 then term.setBackgroundColour(colours.lightBlue) end
  130.       term.write("&")
  131.     elseif map[y][x] == 'H' or (map[y][x] == 'h' and
  132.         goldCount == 0) then
  133.       term.setTextColour(colours.brown)
  134.       term.write("H")
  135.     elseif map[y][x] == '-' then
  136.       term.setTextColour(colours.brown)
  137.       term.write(map[y][x])
  138.     elseif map[y][x] == '#' then
  139.       term.setBackgroundColour(colours.grey)
  140.       term.write(" ")
  141.     elseif type(map[y][x]) == "number" then
  142.       local uchar = ' '
  143.       if map[y][x] == 3 then
  144.         term.setBackgroundColour(colours.lightBlue)
  145.       elseif map[y][x] == 2 and goldMap[y][x] == 1 then
  146.         term.setTextColour(colours.yellow)
  147.         uchar = '$'
  148.       elseif map[y][x] == 1 then
  149.         term.setBackgroundColour(colours.lightBlue)
  150.       elseif map[y][x] == 0 then
  151.         term.setBackgroundColour(colours.blue)
  152.       end
  153.       term.write(uchar)
  154.     elseif goldMap[y][x] == 1 then
  155.       term.setTextColour(colours.yellow)
  156.       term.write('$')
  157.     elseif exX == x and exY == y and goldCount == 0 then
  158.       term.setTextColour(colours.lime)
  159.       term.write("@")
  160.     else
  161.       term.write(" ")
  162.     end
  163. end
  164.  
  165. --It's silly to iterate through all monks when drawing tiles, so
  166. --we do it separately.
  167. local function drawMonk(monk)
  168.     term.setCursorPos(monk.x + drawOffsetX, monk.y + drawOffsetY)
  169.     if monk.justSpawned then term.setTextColour(colours.pink)
  170.     else term.setTextColour(colours.red) end
  171.     if map[monk.y][monk.x] == 1 then term.setBackgroundColour(colours.lightBlue)
  172.     else term.setBackgroundColour(colours.black) end
  173.     term.write("&")
  174. end
  175.  
  176. --Draws the map for the first time. It barely changes, so we really
  177. --only call this the once.
  178. local function drawMap()
  179.   for y=1,#map do
  180.     for x=1,49 do
  181.       updateMap(x,y)
  182.     end
  183.   end
  184.   for _,monk in pairs(monks) do drawMonk(monk)end
  185. end
  186.  
  187. --When all coins have been collected, we add in invisble ladders and
  188. --the end game portal.
  189. local function drawEndgameMap()
  190.   for y=1,#map do
  191.     for x=1,49 do
  192.       if map[y][x] == 'h' or (exX == x and exY == y) then
  193.         updateMap(x,y)
  194.       end
  195.     end
  196.   end
  197. end
  198.  
  199. --Sets the map back to defaults, so we can start afresh
  200. local function resetMap()
  201.     goldCount = maxGoldCount
  202.     for i=1,#goldMap do
  203.         for j=1,49 do
  204.             if goldMap[i][j] == 0 then goldMap[i][j] = 1 end
  205.         end
  206.     end
  207.     for _,monk in pairs(monks) do
  208.         monk.justSpawned = true
  209.         monk.dead = nil
  210.         monk.trapped = nil
  211.         monk.justEscaped = false
  212.         monk.falling = false
  213.         monk.behaviour = "none"
  214.         monk.x = monk.spawnX
  215.         monk.y = monk.spawnY
  216.     end
  217.    
  218.     for _,timer in pairs(blockTimers) do
  219.         map[timer.y][timer.x] = 0
  220.     end
  221.     blockTimers = {}
  222.     plX = plspawnX
  223.     plY = plspawnY
  224.    
  225.     moveTimer = -1
  226.     shootTimer = -1
  227.     spawnTimer = -1
  228.     monkTimer = -1
  229.     pfalling = false
  230. end
  231.  
  232. --Draws the HUD. This also rarely changes, so we update it when something happens.
  233. local function drawHUD()
  234.   term.setCursorPos(2,19)
  235.   term.setBackgroundColour(colours.black)
  236.   term.clearLine()
  237.   term.setTextColour(colours.blue)
  238.   term.write("Score: ")
  239.   term.setTextColour(colours.yellow)
  240.   term.write(string.rep("0", 5-math.floor(math.log10(playerScore + 1)))
  241.     ..playerScore)
  242.   term.setTextColour(colours.yellow)
  243.   term.setCursorPos(25 - #levelList[currentLevel]/2, 19)
  244.   term.write(levelList[currentLevel])
  245.   local lstr = "Men: "
  246.   term.setCursorPos(50 - #lstr - math.floor(math.log10(playerLives)), 19)
  247.   term.setTextColour(colours.blue)
  248.   term.write(lstr)
  249.   term.setTextColour(colours.yellow)
  250.   term.write(playerLives.."")
  251. end
  252.  
  253. --Checks to see if any given desired move is legal. Monks and players both use this.
  254. local function isLegalMove(initX,initY,finX,finY)
  255.     if map[finY][finX] ~= 0 and map[finY][finX] ~= '#' then
  256.         --This reports 'self moves' as being illegal, but that's fine
  257.         for _,monk in pairs(monks) do
  258.             if monk.x == finX and monk.y == finY then return false end
  259.         end
  260.  
  261.         if finY == initY-1 and (map[initY][initX] == "H" or (map[initY][initX] == "h" and goldCount == 0))
  262.             then return true
  263.         elseif finY == initY+1 and (map[finY][finX] == "H" or (map[finY][finX] == "h" and goldCount == 0)
  264.                 or (type(map[finY][finX]) == "number" and map[finY][finX] > 0) or map[finY][finX] == nil or
  265.                 map[finY][finX] == "-")
  266.             then return true
  267.         elseif finX == initX-1 or finX == initX+1 then return true
  268.         end
  269.     end
  270. end
  271.  
  272. --Moves the player to a given step.
  273. local function movePlayer(x,y,ignoreLegal)
  274.     if not ignoreLegal and not isLegalMove(plX,plY,x,y) then return false end
  275.    
  276.     local ox = plX
  277.     local oy = plY
  278.     plX = x
  279.     plY = y
  280.    
  281.     updateMap(ox,oy)
  282.     updateMap(x,y)
  283.     if goldMap[y][x] == 1 then
  284.         goldMap[y][x] = 0
  285.         goldCount = goldCount - 1
  286.         playerScore = playerScore + 5
  287.         if playerScore % 200 == 0 then playerLives = playerLives + 1 end
  288.         drawHUD()
  289.         if (goldCount == 0) then
  290.             drawEndgameMap()
  291.         end
  292.     elseif exX == plX and exY == plY and goldCount == 0 then
  293.         started = false
  294.         nextLevel = true
  295.     end
  296.    
  297.     pfalling = (y < #map and map[y][x] ~= '-' and map[y][x] ~= 'H' and not (map[y][x] == 'h' and goldCount == 0)
  298.         and (map[y+1][x] == nil or map[y+1][x] == 2 or map[y+1][x] == '-'))
  299.     for _,monk in pairs(monks) do
  300.         if monk.x == plX and monk.y == plY + 1 then pfalling = false break end
  301.     end
  302.     return true
  303. end
  304.  
  305. local function updateMonks()
  306.     for _,monk in pairs(monks) do
  307.         --Absolute first step- if he's trapped or dead, he's going nowhere
  308.         if monk.trapped or monk.dead then
  309.         --If he's just spawned he takes a second to orient himself
  310.         elseif monk.justSpawned then
  311.             monk.justSpawned = false
  312.             --We evaluate their falling behaviour here (as freed monks CAN stand on air)
  313.             monk.falling = (monk.y < #map and map[monk.y][monk.x] ~= '-' and (map[monk.y+1][monk.x] == nil or
  314.                 map[monk.y+1][monk.x] == 2 or map[monk.y+1][monk.x] == '-') and type(map[monk.y][monk.x] ~= "number"))
  315.             for _,omonk in pairs(monks) do
  316.                 if omonk.x == monk.x and omonk.y == monk.y + 1 then monk.falling = false break end
  317.             end
  318.             if monk.x == plX and monk.y == plY + 1 then monk.falling = false end
  319.         --Then we consider if he's just gotten out of a hole
  320.         elseif monk.justEscaped then
  321.             monk.justEscaped = false
  322.             --He tries the player side first
  323.             local playerSide = (plX-monk.x) / math.abs(plX-monk.x)
  324.             if isLegalMove(monk.x, monk.y, monk.x + playerSide, monk.y) then
  325.                 monk.x = monk.x + playerSide
  326.                 updateMap(monk.x - playerSide, monk.y)
  327.             elseif isLegalMove(monk.x, monk.y, monk.x - playerSide, monk.y) then
  328.                 monk.x = monk.x - playerSide
  329.                 updateMap(monk.x + playerSide, monk.y)
  330.             end
  331.             drawMonk(monk)
  332.         --Then we evaluate falling
  333.         elseif monk.falling then
  334.             monk.behaviour = "none"
  335.             monk.y = monk.y + 1
  336.             updateMap(monk.x, monk.y-1)
  337.             drawMonk(monk)
  338.             monk.desX = nil
  339.             if type(map[monk.y][monk.x]) == "number" then
  340.                 monk.trapped = os.startTimer(monkTrapIntv)
  341.                 monk.falling = false
  342.             else
  343.                 monk.falling = (monk.y < #map and map[monk.y][monk.x] ~= '-' and (map[monk.y+1][monk.x] == nil or
  344.                     map[monk.y+1][monk.x] == 2 or map[monk.y+1][monk.x] == '-') and type(map[monk.y][monk.x] ~= "number"))
  345.                 for _,omonk in pairs(monks) do
  346.                     if omonk.x == monk.x and omonk.y == monk.y + 1 then monk.falling = false break end
  347.                 end
  348.                 if monk.x == plX and monk.y == plY + 1 then monk.falling = false end
  349.                 if monk.justEscaped then monk.falling = false end
  350.             end
  351.         --If he's on his feet and not trapped, he's allowed to think about where to move
  352.         elseif monk.y == plY then
  353.             --Is the monk on the same level as the player? How lucky! They'll just walk towards him
  354.             monk.desX = plX
  355.             monk.behaviour = "across"
  356.         --Y difference takes precedence over X (as in the original, makes them a bit smarter)
  357.         elseif monk.y < plY then
  358.             --If they can move up, they will
  359.             if isLegalMove(monk.x,monk.y,monk.x,monk.y+1) and not monk.justEscaped then
  360.                 monk.y = monk.y+1
  361.                 updateMap(monk.x, monk.y-1)
  362.                 drawMonk(monk)
  363.                 monk.desX = nil
  364.                 --A down move can lead to a fall, so we check if they're now falling.
  365.                 monk.falling = (monk.y < #map and map[monk.y][monk.x] ~= '-' and (map[monk.y+1][monk.x] == nil or
  366.                     map[monk.y+1][monk.x] == 2 or map[monk.y+1][monk.x] == '-') and type(map[monk.y][monk.x] ~= "number"))
  367.                 monk.falling = (monk.y < #map and map[monk.y][monk.x] ~= '-' and (map[monk.y+1][monk.x] == nil or
  368.                     map[monk.y+1][monk.x] == 2 or map[monk.y+1][monk.x] == '-') and type(map[monk.y][monk.x] ~= "number"))
  369.                 for _,omonk in pairs(monks) do
  370.                     if omonk.x == monk.x and omonk.y == monk.y + 1 then monk.falling = false break end
  371.                 end
  372.                 if monk.x == plX and monk.y == plY + 1 then monk.falling = false end
  373.             --Otherwise, it's off to the nearest ladder, monkey bars or perilous ledge to jump off
  374.             --assuming they haven't found one already
  375.             elseif monk.desX == nil then
  376.                 if monk.behaviour ~= "down" then monk.desX = nil end
  377.                 monk.behaviour = "down"
  378.                 monk.desX = nil
  379.                 local cmLeft = true
  380.                 local cmRight = true
  381.                 --We try to find the nearest by searching alternate left and right at variable distance
  382.                 for i=1,math.max(monk.x - 1, 49 - monk.x) do
  383.                     if monk.x-i > 0 and cmLeft then
  384.                         --If a wall blocks the monks path, they can't keep going left or right
  385.                         cmLeft = map[monk.y][monk.x-i] ~= 0
  386.                         --But if it's all clear, they look for something to climb/jump down
  387.                         if cmLeft and (map[monk.y+1][monk.x-i] == "H" or (map[monk.y+1][monk.x-i] == 'h' and goldCount == 0)
  388.                             or map[monk.y+1][monk.x-i] == nil or map[monk.y][monk.x-i] == '-') then
  389.                             monk.desX = monk.x-i
  390.                             break
  391.                         end
  392.                     end
  393.                     if monk.x+i < 50 and cmRight then
  394.                         --If a wall blocks the monks path, they can't keep going left or right
  395.                         cmRight = map[monk.y][monk.x+i] ~= 0
  396.                         --But if it's all clear, they look for something to climb/jump down
  397.                         if cmRight and (map[monk.y+1][monk.x+i] == "H" or (map[monk.y+1][monk.x+i] == 'h' and goldCount == 0)
  398.                             or map[monk.y+1][monk.x+i] == nil or map[monk.y][monk.x+i] == '-') then
  399.                             monk.desX = monk.x+i
  400.                             break
  401.                         end
  402.                     end
  403.                 end
  404.             end
  405.         elseif monk.y > plY then
  406.             if monk.behaviour ~= "up" then monk.desX = nil end
  407.             monk.behaviour = "up"
  408.             --Same deal again- try moving up first
  409.             if isLegalMove(monk.x,monk.y,monk.x,monk.y-1) then
  410.                 monk.y = monk.y-1
  411.                 updateMap(monk.x, monk.y+1)
  412.                 drawMonk(monk)
  413.                 monk.desX = nil
  414.                 --You can never move up and start falling, so we don't bother to check
  415.             --Otherwise they need ladders to climb up
  416.             elseif monk.desX == nil then
  417.                 monk.behaviour = "up"
  418.                 monk.desX = nil
  419.                 local cmLeft = true
  420.                 local cmRight = true
  421.                 --We try to find the nearest by searching alternate left and right at variable distance
  422.                 for i=1,math.max(monk.x - 1, 49 - monk.x) do
  423.                     if monk.x-i > 0 and cmLeft then
  424.                         --If a wall blocks the monks path or a pit is in the way, they can't keep going left or right
  425.                         cmLeft = map[monk.y][monk.x-i] ~= 0 and (monk.y == #map or map[monk.y+1][monk.x-i] ~= nil
  426.                                 or map[monk.y][monk.x-i] == '-')
  427.                         --But if it's all clear, they look for a ladder
  428.                         if cmLeft and (map[monk.y][monk.x-i] == "H" or (map[monk.y][monk.x-i] == 'h' and goldCount == 0)) then
  429.                             monk.desX = monk.x-i
  430.                             break
  431.                         end
  432.                     end
  433.                     if monk.x+i < 50 and cmRight then
  434.                         cmRight = map[monk.y][monk.x+i] ~= 0 and (monk.y == #map or map[monk.y+1][monk.x+i] ~= nil
  435.                                 or map[monk.y][monk.x+i] == '-')
  436.                         if cmRight and (map[monk.y][monk.x+i] == "H" or (map[monk.y][monk.x+i] == 'h' and goldCount == 0)) then
  437.                             monk.desX = monk.x+i
  438.                             break
  439.                         end
  440.                     end
  441.                 end
  442.             end
  443.         end
  444.        
  445.         if not (monk.trapped or monk.dead) then
  446.             --Has the monk decided on moving left or right? If so we try to move him
  447.             if monk.desX and not monk.falling then
  448.                 local mdir = monk.desX - monk.x
  449.                 local mdir = mdir / math.abs(mdir)
  450.                 if isLegalMove(monk.x,monk.y,monk.x+mdir,monk.y) then
  451.                     monk.x = monk.x + mdir
  452.                     updateMap(monk.x - mdir, monk.y)
  453.                     drawMonk(monk)
  454.                 else
  455.                     --This allows re-evaluations if they get stuck- not ideal but good enough
  456.                     monk.desX = nil
  457.                 end
  458.             end
  459.             monk.falling = (monk.y < #map and map[monk.y][monk.x] ~= '-' and (map[monk.y+1][monk.x] == nil or
  460.                 map[monk.y+1][monk.x] == 2 or map[monk.y+1][monk.x] == '-') and type(map[monk.y][monk.x] ~= "number"))
  461.             for _,omonk in pairs(monks) do
  462.                 if omonk.x == monk.x and omonk.y == monk.y + 1 then monk.falling = false break end
  463.             end
  464.             if monk.x == plX and monk.y == plY + 1 then monk.falling = false end
  465.             --We have caught and killed the player
  466.             if monk.x == plX and monk.y == plY and spawnTimer == -1 then
  467.                 spawnTimer = os.startTimer(2)
  468.             end
  469.         end
  470.     end
  471. end
  472.  
  473. local function updateBlockTimer(tid)
  474.     local remAt = nil
  475.     for i,v in ipairs(blockTimers) do
  476.         if v.timer == tid then
  477.             if map[v.y][v.x] == 3 then
  478.                 map[v.y][v.x] = 2
  479.                 v.timer = os.startTimer(blockIntv)
  480.             elseif map[v.y][v.x] == 2 then
  481.                 map[v.y][v.x] = 1
  482.                 v.timer = os.startTimer(0.1)
  483.             elseif map[v.y][v.x] == 1 then
  484.                 map[v.y][v.x] = 0
  485.                 --If the player is caught in a block, he dies
  486.                 if v.y == plY and v.x == plX then
  487.                     spawnTimer = os.startTimer(2)
  488.                 end
  489.                 for _,monk in pairs(monks) do
  490.                     if monk.x == v.x and monk.y == v.y then
  491.                         monk.dead = os.startTimer(monkSpawnIntv)
  492.                         --Easiest way to get them out of the way rather than evaluation
  493.                         monk.x = -1
  494.                         monk.y = -1
  495.                         monk.trapped = nil
  496.                     end
  497.                 end
  498.                 remAt = i
  499.             end
  500.             updateMap(v.x,v.y)
  501.             break
  502.         end
  503.     end
  504.     if remAt then table.remove(blockTimers,remAt) end
  505. end
  506.  
  507. local function shootBlock(x,y)
  508.     if y <= #map and map[y][x] == 0 and (map[y-1][x] == nil
  509.             or map[y-1][x] == 2 or (map[y-1][x] == 'h' and goldCount > 0)) then
  510.         map[y][x] = 3
  511.         table.insert(blockTimers, {x = x; y = y; timer = os.startTimer(0.1);} )
  512.         updateMap(x,y)
  513.     end
  514. end
  515.  
  516. local function handleEvents()
  517.     local id,p1,p2,p3 = os.pullEvent()
  518.    
  519.     if id == "key" then
  520.         if p1 == keys.a and moveTimer == -1 and spawnTimer == -1 then
  521.             movePlayer(plX-1,plY)
  522.             moveTimer = os.startTimer(moveIntv)
  523.         elseif p1 == keys.d and moveTimer == -1 and spawnTimer == -1 then
  524.             movePlayer(plX+1,plY)
  525.             moveTimer = os.startTimer(moveIntv)
  526.         elseif p1 == keys.w and moveTimer == -1 and spawnTimer == -1 then
  527.             movePlayer(plX,plY-1)
  528.             moveTimer = os.startTimer(moveIntv)
  529.         elseif p1 == keys.s and moveTimer == -1 and spawnTimer == -1 then
  530.             movePlayer(plX,plY+1)
  531.             moveTimer = os.startTimer(moveIntv)
  532.         elseif p1 == keys.q and shootTimer == -1 and not pfalling and spawnTimer == -1 then
  533.             shootBlock(plX-1,plY+1)
  534.             shootTimer = os.startTimer(moveIntv)
  535.         elseif p1 == keys.e and shootTimer == -1 and not pfalling and spawnTimer == -1 then
  536.             shootBlock(plX+1,plY+1)
  537.             shootTimer = os.startTimer(moveIntv)
  538.         elseif p1 == keys.enter then
  539.             started = false
  540.         elseif p1 == keys.t then
  541.             started = false
  542.             running = false
  543.         end
  544.     elseif id == "timer" then
  545.         if p1 == shootTimer then shootTimer = -1
  546.         elseif p1 == spawnTimer then
  547.             started = false
  548.         elseif p1 == moveTimer then
  549.             if pfalling then
  550.                 movePlayer(plX,plY+1)
  551.                 moveTimer = os.startTimer(moveIntv)
  552.             else
  553.                 moveTimer = -1
  554.             end
  555.         elseif p1 == monkTimer then
  556.             updateMonks()
  557.             monkTimer = os.startTimer(moveIntv * 2)
  558.         elseif updateBlockTimer(p1) then
  559.         else
  560.             for _,monk in pairs(monks) do
  561.                 if p1 == monk.trapped then
  562.                     --You can stand on a monk to force them to be killed- so we check for that
  563.                     --along with being buried in tunnels, etc.
  564.                     local stillTrapped = map[monk.y-1][monk.x] == 0 or (plX == monk.x and plY == monk.y-1)
  565.                     for _,omonk in pairs(monks) do
  566.                         if omonk.x == monk.x and omonk.y == monk.y-1 then
  567.                             stillTrapped = true
  568.                             break
  569.                         end
  570.                     end
  571.                     --Perpetually trapped monks will try to excape much more quickly
  572.                     if stillTrapped then
  573.                         --This needs to be tweaked
  574.                         monk.trapped = os.startTimer(0.75)
  575.                     else
  576.                         --When free, they head in your general direction, re-evaluate later
  577.                         monk.y = monk.y - 1
  578.                         --This is necessary to stop 'double jumping'
  579.                         monk.desX = nil
  580.                         monk.trapped = nil
  581.                         monk.behaviour = "none"
  582.                         monk.justEscaped = true
  583.                        
  584.                         updateMap(monk.x, monk.y+1)
  585.                         drawMonk(monk)
  586.                     end
  587.                     break
  588.                 elseif p1 == monk.dead then
  589.                     --Same deal- you can camp spawn
  590.                     local stillDead = plX == monk.spawnX and plY == monk.spawnY
  591.                     for _,omonk in pairs(monks) do
  592.                         if omonk.x == monk.spawnX and omonk.y == monk.spawnY then
  593.                             stillDead = true
  594.                             break
  595.                         end
  596.                     end
  597.                     --They'll spawn the second you give them the chance
  598.                     if stillDead then
  599.                         monk.dead = os.startTimer(0.5)
  600.                     else
  601.                         monk.x = monk.spawnX
  602.                         monk.y = monk.spawnY
  603.                         monk.dead = nil
  604.                         monk.justSpawned = true
  605.                         monk.behaviour = "none"
  606.                         drawMonk(monk)
  607.                         break
  608.                     end
  609.                 end
  610.             end
  611.         end
  612.     end
  613. end
  614.  
  615. term.clear()
  616. if not fs.exists(shell.resolve(".").."/levels") then
  617.     error("Level directory not present!")
  618. end
  619. levelList = fs.list(shell.resolve(".").."/levels")
  620. if #levelList == 0 then
  621.     error("Level directory is empty!")
  622. end
  623.  
  624. loadMap(shell.resolve(".").."/levels/"..levelList[currentLevel])
  625. while running do
  626.     drawMap()
  627.     drawHUD()
  628.     os.pullEvent("key")
  629.     monkTimer = os.startTimer(moveIntv * 1.5)
  630.    
  631.     started = true
  632.     while started do
  633.         handleEvents()
  634.     end
  635.    
  636.     if nextLevel then
  637.         if currentLevel == #levelList then
  638.             running = false
  639.             break
  640.         else
  641.             currentLevel = currentLevel + 1
  642.    resetMap()
  643.             loadMap(shell.resolve(".").."/levels/"..levelList[currentLevel])
  644.         end
  645.         nextLevel = false
  646.     else
  647.         playerLives = playerLives-1
  648.         if playerLives > 0 then resetMap()
  649.         else running = false end
  650.     end
  651. end
  652.  
  653. if nextLevel then
  654.     local msg = "All levels defeated, Code Runner!"
  655.     term.setBackgroundColour(colours.black)
  656.     term.setTextColour(colours.lime)
  657.     term.setCursorPos(25 - #msg/2, 2)
  658.     term.write(msg)
  659. else
  660.     local msg = "Game over!"
  661.     term.setBackgroundColour(colours.black)
  662.     term.setTextColour(colours.red)
  663.     term.setCursorPos(25 - #msg/2, 2)
  664.     term.write(msg)
  665. end
  666. sleep(2)
  667. term.setCursorPos(19,51)
  668. print("")
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement