Advertisement
nitrogenfingers

Gold Runner

Jun 5th, 2013
361
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. --[[
  2.         Code Runner
  3.         Inspired by the game by Doug fKqTDD5r
  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 finY < 1 or finY > #map or finX < 1 or finX > 49 then
  256.         return false
  257.     end
  258.    
  259.     if map[finY][finX] ~= 0 and map[finY][finX] ~= '#' then
  260.         --This reports 'self moves' as being illegal, but that's fine
  261.         for _,monk in pairs(monks) do
  262.             if monk.x == finX and monk.y == finY then return false end
  263.         end
  264.  
  265.         if finY == initY-1 and (map[initY][initX] == "H" or (map[initY][initX] == "h" and goldCount == 0))
  266.             then return true
  267.         elseif finY == initY+1 and (map[finY][finX] == "H" or (map[finY][finX] == "h" and goldCount == 0)
  268.                 or (type(map[finY][finX]) == "number" and map[finY][finX] > 0) or map[finY][finX] == nil or
  269.                 map[finY][finX] == "-" or (map[finY][finX] == 'h' and goldCount ~= 0))
  270.             then return true
  271.         elseif finX == initX-1 or finX == initX+1 then return true
  272.         end
  273.     end
  274. end
  275.  
  276. --Moves the player to a given step.
  277. local function movePlayer(x,y,ignoreLegal)
  278.     if not ignoreLegal and not isLegalMove(plX,plY,x,y) then return false end
  279.    
  280.     local ox = plX
  281.     local oy = plY
  282.     plX = x
  283.     plY = y
  284.    
  285.     updateMap(ox,oy)
  286.     updateMap(x,y)
  287.     if goldMap[y][x] == 1 then
  288.         goldMap[y][x] = 0
  289.         goldCount = goldCount - 1
  290.         playerScore = playerScore + 5
  291.         if playerScore % 200 == 0 then playerLives = playerLives + 1 end
  292.         drawHUD()
  293.         if (goldCount == 0) then
  294.             drawEndgameMap()
  295.         end
  296.     elseif exX == plX and exY == plY and goldCount == 0 then
  297.         started = false
  298.         nextLevel = true
  299.     end
  300.    
  301.     pfalling = (y < #map and map[y][x] ~= '-' and map[y][x] ~= 'H' and not (map[y][x] == 'h' and goldCount == 0)
  302.         and (map[y+1][x] == nil or map[y+1][x] == 2 or map[y+1][x] == '-'))
  303.     if (map[y+1][x] == 'h' and goldCount ~= 0) then pfalling = true end
  304.     for _,monk in pairs(monks) do
  305.         if monk.x == plX and monk.y == plY + 1 then pfalling = false break end
  306.     end
  307.     return true
  308. end
  309.  
  310. local function updateMonks()
  311.     for _,monk in pairs(monks) do
  312.         --Absolute first step- if he's trapped or dead, he's going nowhere
  313.         if monk.trapped or monk.dead then
  314.         --If he's just spawned he takes a second to orient himself
  315.         elseif monk.justSpawned then
  316.             monk.justSpawned = false
  317.             --We evaluate their falling behaviour here (as freed monks CAN stand on air)
  318.             monk.falling = (monk.y < #map and map[monk.y][monk.x] ~= '-' and (map[monk.y+1][monk.x] == nil or
  319.                 map[monk.y+1][monk.x] == 2 or map[monk.y+1][monk.x] == '-') and type(map[monk.y][monk.x] ~= "number"))
  320.             for _,omonk in pairs(monks) do
  321.                 if omonk.x == monk.x and omonk.y == monk.y + 1 then monk.falling = false break end
  322.             end
  323.             if monk.x == plX and monk.y == plY + 1 then monk.falling = false end
  324.         --Then we consider if he's just gotten out of a hole
  325.         elseif monk.justEscaped then
  326.             monk.justEscaped = false
  327.             --He tries the player side first
  328.             local playerSide = (plX-monk.x) / math.abs(plX-monk.x)
  329.             if isLegalMove(monk.x, monk.y, monk.x + playerSide, monk.y) then
  330.                 monk.x = monk.x + playerSide
  331.                 updateMap(monk.x - playerSide, monk.y)
  332.             elseif isLegalMove(monk.x, monk.y, monk.x - playerSide, monk.y) then
  333.                 monk.x = monk.x - playerSide
  334.                 updateMap(monk.x + playerSide, monk.y)
  335.             end
  336.             drawMonk(monk)
  337.         --Then we evaluate falling
  338.         elseif monk.falling then
  339.             monk.behaviour = "none"
  340.             monk.y = monk.y + 1
  341.             updateMap(monk.x, monk.y-1)
  342.             drawMonk(monk)
  343.             monk.desX = nil
  344.             if type(map[monk.y][monk.x]) == "number" then
  345.                 monk.trapped = os.startTimer(monkTrapIntv)
  346.                 monk.falling = false
  347.             else
  348.                 monk.falling = (monk.y < #map and map[monk.y][monk.x] ~= '-' and (map[monk.y+1][monk.x] == nil or
  349.                     map[monk.y+1][monk.x] == 2 or map[monk.y+1][monk.x] == '-') and type(map[monk.y][monk.x] ~= "number"))
  350.                 for _,omonk in pairs(monks) do
  351.                     if omonk.x == monk.x and omonk.y == monk.y + 1 then monk.falling = false break end
  352.                 end
  353.                 if monk.x == plX and monk.y == plY + 1 then monk.falling = false end
  354.                 if monk.justEscaped then monk.falling = false end
  355.             end
  356.         --If he's on his feet and not trapped, he's allowed to think about where to move
  357.         elseif monk.y == plY then
  358.             --Is the monk on the same level as the player? How lucky! They'll just walk towards him
  359.             monk.desX = plX
  360.             monk.behaviour = "across"
  361.         --Y difference takes precedence over X (as in the original, makes them a bit smarter)
  362.         elseif monk.y < plY then
  363.             --If they can move up, they will
  364.             if isLegalMove(monk.x,monk.y,monk.x,monk.y+1) and not monk.justEscaped then
  365.                 monk.y = monk.y+1
  366.                 updateMap(monk.x, monk.y-1)
  367.                 drawMonk(monk)
  368.                 monk.desX = nil
  369.                 --A down move can lead to a fall, so we check if they're now falling.
  370.                 monk.falling = (monk.y < #map and map[monk.y][monk.x] ~= '-' and (map[monk.y+1][monk.x] == nil or
  371.                     map[monk.y+1][monk.x] == 2 or map[monk.y+1][monk.x] == '-') and type(map[monk.y][monk.x] ~= "number"))
  372.                 monk.falling = (monk.y < #map and map[monk.y][monk.x] ~= '-' and (map[monk.y+1][monk.x] == nil or
  373.                     map[monk.y+1][monk.x] == 2 or map[monk.y+1][monk.x] == '-') and type(map[monk.y][monk.x] ~= "number"))
  374.                 for _,omonk in pairs(monks) do
  375.                     if omonk.x == monk.x and omonk.y == monk.y + 1 then monk.falling = false break end
  376.                 end
  377.                 if monk.x == plX and monk.y == plY + 1 then monk.falling = false end
  378.             --Otherwise, it's off to the nearest ladder, monkey bars or perilous ledge to jump off
  379.             --assuming they haven't found one already
  380.             elseif monk.desX == nil then
  381.                 if monk.behaviour ~= "down" then monk.desX = nil end
  382.                 monk.behaviour = "down"
  383.                 monk.desX = nil
  384.                 local cmLeft = true
  385.                 local cmRight = true
  386.                 --We try to find the nearest by searching alternate left and right at variable distance
  387.                 for i=1,math.max(monk.x - 1, 49 - monk.x) do
  388.                     if monk.x-i > 0 and cmLeft then
  389.                         --If a wall blocks the monks path, they can't keep going left or right
  390.                         cmLeft = map[monk.y][monk.x-i] ~= 0
  391.                         --But if it's all clear, they look for something to climb/jump down
  392.                         if cmLeft and (map[monk.y+1][monk.x-i] == "H" or (map[monk.y+1][monk.x-i] == 'h' and goldCount == 0)
  393.                             or map[monk.y+1][monk.x-i] == nil or map[monk.y][monk.x-i] == '-') then
  394.                             monk.desX = monk.x-i
  395.                             break
  396.                         end
  397.                     end
  398.                     if monk.x+i < 50 and cmRight then
  399.                         --If a wall blocks the monks path, they can't keep going left or right
  400.                         cmRight = map[monk.y][monk.x+i] ~= 0
  401.                         --But if it's all clear, they look for something to climb/jump down
  402.                         if cmRight and (map[monk.y+1][monk.x+i] == "H" or (map[monk.y+1][monk.x+i] == 'h' and goldCount == 0)
  403.                             or map[monk.y+1][monk.x+i] == nil or map[monk.y][monk.x+i] == '-') then
  404.                             monk.desX = monk.x+i
  405.                             break
  406.                         end
  407.                     end
  408.                 end
  409.             end
  410.         elseif monk.y > plY then
  411.             if monk.behaviour ~= "up" then monk.desX = nil end
  412.             monk.behaviour = "up"
  413.             --Same deal again- try moving up first
  414.             if isLegalMove(monk.x,monk.y,monk.x,monk.y-1) then
  415.                 monk.y = monk.y-1
  416.                 updateMap(monk.x, monk.y+1)
  417.                 drawMonk(monk)
  418.                 monk.desX = nil
  419.                 --You can never move up and start falling, so we don't bother to check
  420.             --Otherwise they need ladders to climb up
  421.             elseif monk.desX == nil then
  422.                 monk.behaviour = "up"
  423.                 monk.desX = nil
  424.                 local cmLeft = true
  425.                 local cmRight = true
  426.                 --We try to find the nearest by searching alternate left and right at variable distance
  427.                 for i=1,math.max(monk.x - 1, 49 - monk.x) do
  428.                     if monk.x-i > 0 and cmLeft then
  429.                         --If a wall blocks the monks path or a pit is in the way, they can't keep going left or right
  430.                         cmLeft = map[monk.y][monk.x-i] ~= 0 and (monk.y == #map or map[monk.y+1][monk.x-i] ~= nil
  431.                                 or map[monk.y][monk.x-i] == '-')
  432.                         --But if it's all clear, they look for a ladder
  433.                         if cmLeft and (map[monk.y][monk.x-i] == "H" or (map[monk.y][monk.x-i] == 'h' and goldCount == 0)) then
  434.                             monk.desX = monk.x-i
  435.                             break
  436.                         end
  437.                     end
  438.                     if monk.x+i < 50 and cmRight then
  439.                         cmRight = map[monk.y][monk.x+i] ~= 0 and (monk.y == #map or map[monk.y+1][monk.x+i] ~= nil
  440.                                 or map[monk.y][monk.x+i] == '-')
  441.                         if cmRight and (map[monk.y][monk.x+i] == "H" or (map[monk.y][monk.x+i] == 'h' and goldCount == 0)) then
  442.                             monk.desX = monk.x+i
  443.                             break
  444.                         end
  445.                     end
  446.                 end
  447.             end
  448.         end
  449.        
  450.         if not (monk.trapped or monk.dead) then
  451.             --Has the monk decided on moving left or right? If so we try to move him
  452.             if monk.desX and not monk.falling then
  453.                 local mdir = monk.desX - monk.x
  454.                 local mdir = mdir / math.abs(mdir)
  455.                 if isLegalMove(monk.x,monk.y,monk.x+mdir,monk.y) then
  456.                     monk.x = monk.x + mdir
  457.                     updateMap(monk.x - mdir, monk.y)
  458.                     drawMonk(monk)
  459.                 else
  460.                     --This allows re-evaluations if they get stuck- not ideal but good enough
  461.                     monk.desX = nil
  462.                 end
  463.             end
  464.             monk.falling = (monk.y < #map and map[monk.y][monk.x] ~= '-' and (map[monk.y+1][monk.x] == nil or
  465.                 map[monk.y+1][monk.x] == 2 or map[monk.y+1][monk.x] == '-') and type(map[monk.y][monk.x] ~= "number"))
  466.             for _,omonk in pairs(monks) do
  467.                 if omonk.x == monk.x and omonk.y == monk.y + 1 then monk.falling = false break end
  468.             end
  469.             if monk.x == plX and monk.y == plY + 1 then monk.falling = false end
  470.             --We have caught and killed the player
  471.             if monk.x == plX and monk.y == plY and spawnTimer == -1 then
  472.                 spawnTimer = os.startTimer(2)
  473.             end
  474.         end
  475.     end
  476. end
  477.  
  478. local function updateBlockTimer(tid)
  479.     local remAt = nil
  480.     for i,v in ipairs(blockTimers) do
  481.         if v.timer == tid then
  482.             if map[v.y][v.x] == 3 then
  483.                 map[v.y][v.x] = 2
  484.                 v.timer = os.startTimer(blockIntv)
  485.             elseif map[v.y][v.x] == 2 then
  486.                 map[v.y][v.x] = 1
  487.                 v.timer = os.startTimer(0.1)
  488.             elseif map[v.y][v.x] == 1 then
  489.                 map[v.y][v.x] = 0
  490.                 --If the player is caught in a block, he dies
  491.                 if v.y == plY and v.x == plX then
  492.                     spawnTimer = os.startTimer(2)
  493.                 end
  494.                 for _,monk in pairs(monks) do
  495.                     if monk.x == v.x and monk.y == v.y then
  496.                         monk.dead = os.startTimer(monkSpawnIntv)
  497.                         --Easiest way to get them out of the way rather than evaluation
  498.                         monk.x = -1
  499.                         monk.y = -1
  500.                         monk.trapped = nil
  501.                     end
  502.                 end
  503.                 remAt = i
  504.             end
  505.             updateMap(v.x,v.y)
  506.             break
  507.         end
  508.     end
  509.     if remAt then table.remove(blockTimers,remAt) end
  510. end
  511.  
  512. local function shootBlock(x,y)
  513.     if y <= #map and map[y][x] == 0 and (map[y-1][x] == nil
  514.             or map[y-1][x] == 2 or (map[y-1][x] == 'h' and goldCount > 0)) then
  515.         map[y][x] = 3
  516.         table.insert(blockTimers, {x = x; y = y; timer = os.startTimer(0.1);} )
  517.         updateMap(x,y)
  518.     end
  519. end
  520.  
  521. local function handleEvents()
  522.     local id,p1,p2,p3 = os.pullEvent()
  523.    
  524.     if id == "key" then
  525.         if p1 == keys.a and moveTimer == -1 and spawnTimer == -1 then
  526.             movePlayer(plX-1,plY)
  527.             moveTimer = os.startTimer(moveIntv)
  528.         elseif p1 == keys.d and moveTimer == -1 and spawnTimer == -1 then
  529.             movePlayer(plX+1,plY)
  530.             moveTimer = os.startTimer(moveIntv)
  531.         elseif p1 == keys.w and moveTimer == -1 and spawnTimer == -1 then
  532.             movePlayer(plX,plY-1)
  533.             moveTimer = os.startTimer(moveIntv)
  534.         elseif p1 == keys.s and moveTimer == -1 and spawnTimer == -1 then
  535.             movePlayer(plX,plY+1)
  536.             moveTimer = os.startTimer(moveIntv)
  537.         elseif p1 == keys.q and shootTimer == -1 and not pfalling and spawnTimer == -1 then
  538.             shootBlock(plX-1,plY+1)
  539.             shootTimer = os.startTimer(moveIntv)
  540.         elseif p1 == keys.e and shootTimer == -1 and not pfalling and spawnTimer == -1 then
  541.             shootBlock(plX+1,plY+1)
  542.             shootTimer = os.startTimer(moveIntv)
  543.         elseif p1 == keys.enter then
  544.             started = false
  545.         elseif p1 == keys.t then
  546.             started = false
  547.             running = false
  548.         end
  549.     elseif id == "timer" then
  550.         if p1 == shootTimer then shootTimer = -1
  551.         elseif p1 == spawnTimer then
  552.             started = false
  553.         elseif p1 == moveTimer then
  554.             if pfalling then
  555.                 movePlayer(plX,plY+1)
  556.                 moveTimer = os.startTimer(moveIntv)
  557.             else
  558.                 moveTimer = -1
  559.             end
  560.         elseif p1 == monkTimer then
  561.             updateMonks()
  562.             monkTimer = os.startTimer(moveIntv * 2)
  563.         elseif updateBlockTimer(p1) then
  564.         else
  565.             for _,monk in pairs(monks) do
  566.                 if p1 == monk.trapped then
  567.                     --You can stand on a monk to force them to be killed- so we check for that
  568.                     --along with being buried in tunnels, etc.
  569.                     local stillTrapped = map[monk.y-1][monk.x] == 0 or (plX == monk.x and plY == monk.y-1)
  570.                     for _,omonk in pairs(monks) do
  571.                         if omonk.x == monk.x and omonk.y == monk.y-1 then
  572.                             stillTrapped = true
  573.                             break
  574.                         end
  575.                     end
  576.                     --Perpetually trapped monks will try to excape much more quickly
  577.                     if stillTrapped then
  578.                         --This needs to be tweaked
  579.                         monk.trapped = os.startTimer(0.75)
  580.                     else
  581.                         --When free, they head in your general direction, re-evaluate later
  582.                         monk.y = monk.y - 1
  583.                         --This is necessary to stop 'double jumping'
  584.                         monk.desX = nil
  585.                         monk.trapped = nil
  586.                         monk.behaviour = "none"
  587.                         monk.justEscaped = true
  588.                        
  589.                         updateMap(monk.x, monk.y+1)
  590.                         drawMonk(monk)
  591.                     end
  592.                     break
  593.                 elseif p1 == monk.dead then
  594.                     --Same deal- you can camp spawn
  595.                     local stillDead = plX == monk.spawnX and plY == monk.spawnY
  596.                     for _,omonk in pairs(monks) do
  597.                         if omonk.x == monk.spawnX and omonk.y == monk.spawnY then
  598.                             stillDead = true
  599.                             break
  600.                         end
  601.                     end
  602.                     --They'll spawn the second you give them the chance
  603.                     if stillDead then
  604.                         monk.dead = os.startTimer(0.5)
  605.                     else
  606.                         monk.x = monk.spawnX
  607.                         monk.y = monk.spawnY
  608.                         monk.dead = nil
  609.                         monk.justSpawned = true
  610.                         monk.behaviour = "none"
  611.                         drawMonk(monk)
  612.                         break
  613.                     end
  614.                 end
  615.             end
  616.         end
  617.     end
  618. end
  619.  
  620. term.clear()
  621. if not fs.exists(shell.resolve(".").."/levels") then
  622.     error("Level directory not present!")
  623. end
  624. levelList = fs.list(shell.resolve(".").."/levels")
  625. if #levelList == 0 then
  626.     error("Level directory is empty!")
  627. end
  628.  
  629. loadMap(shell.resolve(".").."/levels/"..levelList[currentLevel])
  630. while running do
  631.     drawMap()
  632.     drawHUD()
  633.     os.pullEvent("key")
  634.     monkTimer = os.startTimer(moveIntv * 1.5)
  635.    
  636.     started = true
  637.     while started do
  638.         handleEvents()
  639.     end
  640.    
  641.     if nextLevel then
  642.         if currentLevel == #levelList then
  643.             running = false
  644.             break
  645.         else
  646.             currentLevel = currentLevel + 1
  647.    resetMap()
  648.             loadMap(shell.resolve(".").."/levels/"..levelList[currentLevel])
  649.         end
  650.         nextLevel = false
  651.     else
  652.         playerLives = playerLives-1
  653.         if playerLives > 0 then resetMap()
  654.         else running = false end
  655.     end
  656. end
  657.  
  658. if nextLevel then
  659.     local msg = "All levels defeated, Code Runner!"
  660.     term.setBackgroundColour(colours.black)
  661.     term.setTextColour(colours.lime)
  662.     term.setCursorPos(25 - #msg/2, 2)
  663.     term.write(msg)
  664. else
  665.     local msg = "Game over!"
  666.     term.setBackgroundColour(colours.black)
  667.     term.setTextColour(colours.red)
  668.     term.setCursorPos(25 - #msg/2, 2)
  669.     term.write(msg)
  670. end
  671. sleep(2)
  672. term.setCursorPos(19,51)
  673. print("")
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement