Advertisement
GauHelldragon

mcrawl

Dec 13th, 2015
198
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 13.51 KB | None | 0 0
  1. local event = require("event")
  2. local term = require("term")
  3. local component = require("component")
  4. local gpu = component.gpu
  5. local mry
  6. local mrx
  7. mrx, mry = gpu.maxResolution()
  8. gpu.setResolution(mrx,mry)
  9.  
  10. if ( mrx > 40 ) then mrx = 40 end
  11. if ( mry > 20 ) then mry = 20 end
  12.  
  13. local quit_program = false
  14.  
  15. local mapTiles
  16. local viewChange = true
  17. local infoChange = true
  18. local logChange = true
  19.  
  20.  
  21. local log_y_size = math.ceil(mry / 3)
  22. local INFO_X_SIZE = 20
  23.  
  24. local view_max_x = mrx - INFO_X_SIZE
  25. local view_max_y = mry - ( log_y_size + 1 )
  26.  
  27. local map_max_x = 50
  28. local map_max_y = 50
  29.  
  30. local max_rooms = 10
  31. local rooms = {}
  32. local floorItems = {}
  33.  
  34. local moved = false
  35. local endTurn = false
  36.  
  37.  
  38. local player = {
  39.    x = 10,
  40.    y = 10,
  41.    name = "Steve",
  42.    maxHP = 10,
  43.    HP = 10,
  44.    level = 1,
  45.    xp = 0,
  46.    defence = 0,
  47.    food = 10,
  48.    maxFood = 10,
  49.    emeralds = 0,
  50.    
  51.    
  52.    weapon = nil,
  53.    armor = nil,
  54.    
  55.    inventory = {}
  56.    
  57. }
  58.  
  59. -- MAP GENERATION
  60.  
  61. function drawSquare(x,y,x2,y2)
  62.    xadder = 1
  63.    yadder = 1
  64.    if ( x > x2 ) then xadder = -1 end
  65.    if ( y > y2 ) then yadder = -1 end
  66.  
  67.    for mx = x,x2,xadder do
  68.       for my = y,y2,yadder do
  69.          if ( my >= 1 and my <= map_max_y and mx >= 1 and mx <= map_max_x ) then
  70.             if ( math.random() > 0.1 ) then mapTiles[mx][my] = "."
  71.             else mapTiles[mx][my] = "," end
  72.          end
  73.       end
  74.    end
  75. end
  76.  
  77. function doRoomsIntersect(room1,room2)
  78.    if ( room1.x-2 < room2.x2 and room1.x2+2 > room2.x and room1.y-2 < room2.y2 and room1.y2+2 > room2.y ) then return true end
  79.    return false
  80. end
  81.  
  82. function isRoomOK(room)
  83.    for i,croom in pairs(rooms)    do
  84.      
  85.       if ( doRoomsIntersect(room,croom)) then return false end
  86.    end
  87.    return true
  88. end
  89.  
  90.  
  91. function drawRoom(room)
  92.    x = room.x
  93.    y = room.y
  94.    x2 = room.x2
  95.    y2 = room.y2
  96.    drawSquare(x,y,x2,y2)
  97. end
  98.  
  99.  
  100. function NewRoom()
  101.    local width = math.random(4,8)
  102.    local height = math.random(4,8)
  103.    local mx = math.random(2,map_max_x-width-1)
  104.    local my = math.random(2,map_max_y-height-1)
  105.    room = {
  106.       x = mx,
  107.       y = my,
  108.       w = width,
  109.       h = height,
  110.       x2 = mx + width - 1,
  111.       y2 = my + height - 1
  112.    }
  113.    return room
  114. end
  115.  
  116. function getRandomSpot(room)
  117.    local x = room.x + math.random(0,room.w-1)
  118.    local y = room.y + math.random(0,room.h-1)
  119.    return x,y
  120. end
  121.  
  122. function drawPath(room1,room2)
  123.    startX, startY = getRandomSpot(room1)
  124.    endX, endY = getRandomSpot(room2)
  125.    
  126.    if ( math.random() > 0.5 ) then
  127.       drawSquare(startX,startY,endX,startY)
  128.       drawSquare(endX,startY,endX,endY)
  129.    else
  130.       drawSquare(startX,startY,startX,endY)
  131.       drawSquare(startX,endY,endX,endY)
  132.    end
  133.  
  134. end
  135.  
  136. -- FOG OF WAR
  137.  
  138. function getPlayerRoom()
  139.    for i,room in pairs(rooms) do
  140.       if ( player.x >= room.x and player.x <= room.x2 and player.y >= room.y and player.y <= room.y2 ) then return room end
  141.    end
  142.    return 0
  143. end
  144.  
  145. function revealRoom(room)
  146.    room.revealed = true
  147.    for x=room.x-1,room.x2+1 do
  148.       for y=room.y-1,room.y2+1 do
  149.          revealMap[x][y] = 1
  150.       end
  151.    end
  152. end
  153.  
  154. function revealTunnel()
  155.    for x=player.x-1,player.x+1 do
  156.       for y=player.y-1,player.y+1 do
  157.          revealMap[x][y] = 1
  158.       end
  159.    end
  160. end  
  161.  
  162. function generateMap()
  163.    mapTiles = {}
  164.    revealMap = {}
  165.    for x=1,map_max_x do  -- Clear Map
  166.       mapTiles[x] = {}
  167.      revealMap[x] = {}
  168.       for y=1,map_max_y do
  169.          mapTiles[x][y] = "#"
  170.        revealMap[x][y] = 0
  171.       end
  172.    end
  173.    
  174.    local totalRooms = 0
  175.    for i=1,max_rooms do
  176.       local newRoom = NewRoom()
  177.       local tries = 1
  178.       while ( not isRoomOK(newRoom) and tries < 10 ) do
  179.          tries = tries + 1
  180.          newRoom = NewRoom()
  181.       end
  182.       if ( isRoomOK(newRoom) ) then
  183.       table.insert(rooms,newRoom)
  184.       totalRooms = totalRooms + 1
  185.      local ix, iy = getRandomSpot(newRoom)
  186.      addNewFloorItem("Apple",ix,iy)
  187.    end
  188.    end
  189.    
  190.    max_rooms = totalRooms
  191.    
  192.    startRoom = rooms[1]
  193.    player.x, player.y = getRandomSpot(startRoom)
  194.    revealRoom(startRoom)
  195.    
  196.    for i=1,max_rooms do
  197.      drawRoom(rooms[i])
  198.    end
  199.    for i=1,max_rooms-1 do
  200.      drawPath(rooms[i],rooms[i+1])
  201.    end
  202. end
  203.  
  204.  
  205.  
  206. function getMapTile(x,y)
  207.    
  208.    if ( x == player.x and y == player.y ) then return "@" end
  209.    
  210.    if ( revealMap[x][y] == 0 ) then return "*" end
  211.    
  212.    local item = getItemAt(x,y)
  213.    if ( item ~= nil ) then return item.icon end
  214.    
  215.    return mapTiles[x][y]
  216. end
  217.  
  218.  
  219.  
  220.  
  221. function changeReveal()
  222.    local playerRoom = getPlayerRoom()
  223.    if ( playerRoom ~= 0 ) then
  224.       if ( playerRoom.revealed ~= true ) then
  225.          revealRoom(playerRoom)
  226.       end
  227.    else
  228.       revealTunnel()
  229.    end
  230. end
  231.  
  232. -- SCREEN DRAWING
  233.  
  234. function drawView()
  235.    local px = math.ceil(view_max_x / 2 )
  236.    local py = math.ceil(view_max_y / 2 )
  237.    
  238.    
  239.    local x_start = 1 + player.x - px
  240.    if ( x_start < 1 ) then x_start = 1 end
  241.    if ( x_start + view_max_x > map_max_x ) then x_start = map_max_x - view_max_x end
  242.    local x_end = x_start + view_max_x
  243.    
  244.    local dy = player.y - py
  245.    if ( dy < 0 ) then dy = 0 end
  246.    if ( dy + view_max_y > map_max_y ) then dy = map_max_y - view_max_y end
  247.    
  248.    for y = 1, view_max_y, 1 do
  249.      --local line = mapstring[y+dy]
  250.     --local display = string.sub(line,x_start,x_end)
  251.     term.setCursor(1,y)
  252.    
  253.     for x = x_start, x_end do term.write(getMapTile(x,y+dy)) end
  254.    end
  255.    
  256.    --term.setCursor(player.x - ( x_start - 1 ), player.y - dy )
  257.    --term.write("@")
  258.  
  259. end
  260.  
  261. function drawInfo()
  262.    local sx = view_max_x+4
  263.    term.setCursor(sx,1)
  264.    term.write("Player : " .. player.name)
  265.    term.setCursor(sx,2)
  266.    term.write("Health : " .. player.HP .. "/" .. player.maxHP)
  267.    term.setCursor(sx,3)
  268.    term.write("Defence : " .. player.defence)
  269.    term.setCursor(sx,4)
  270.    term.write("Food : " .. math.ceil(player.food) .. "/" .. player.maxFood)
  271.    term.setCursor(sx,5)
  272.    term.write("Level : " .. player.level)
  273.    term.setCursor(sx,6)
  274.    term.write("EXP : " .. player.xp )
  275.    term.setCursor(sx,7)
  276.    term.write("Weapon: ")
  277.    if ( player.weapon == nil ) then term.write("Fists") else term.write(weapon.name) end
  278.    term.setCursor(sx,8)
  279.    term.write("Armor: ")
  280.    if ( player.armor == nil ) then term.write("Clothes") else term.write(armor.name) end
  281.    term.setCursor(sx,9)
  282.    term.write("Emeralds: " .. player.emeralds)
  283.    
  284.    
  285. end
  286.  
  287. function drawLog()
  288.    local logI = 0
  289.    for y = view_max_y+3,mry do
  290.      term.setCursor(2,y)
  291.     term.clearLine()
  292.     term.setCursor(2,y)
  293.      logI = logI + 1
  294.    
  295.      if ( mLog[logI] ~= nil ) then term.write(mLog[logI]) end
  296.    end
  297. end
  298.  
  299. function drawScreen()
  300.    if (viewChange) then drawView() end
  301.    if (infoChange) then drawInfo() end
  302.    if (logChange) then drawLog() end
  303. end
  304.  
  305. local showingInv = false
  306.  
  307. function showInventory()
  308.    showingInv = true
  309.    
  310.    top = string.rep("=",mrx-6)
  311.    mid = "|" .. string.rep(" ",mrx-8) .. "|"
  312.    term.setCursor(3,3)
  313.    term.write(top)
  314.    term.setCursor(3,mry-3)
  315.    term.write(top)
  316.    for y=4,mry-4 do
  317.       term.setCursor(3,y)
  318.       term.write(mid)
  319.    end
  320.    term.setCursor(math.ceil((mrx/2) - 4), 4)
  321.    term.write("INVENTORY")
  322.    for i,item in pairs(player.inventory) do
  323.       if ( i < mry-6 ) then
  324.          term.setCursor(6, i+5)
  325.          term.write(item.name)
  326.          if ( item.quant > 1 ) then term.write(" x".. item.quant) end
  327.       end
  328.    
  329.    end
  330.    
  331.    
  332. end
  333.  
  334. -- PLAYER MOVEMENT
  335.  
  336. function movePlayer(direction)
  337.    if ( direction == "up"    and player.y > 1  ) then tryToMovePlayer(player.x,player.y-1) end
  338.    if ( direction == "down"  and player.y < map_max_y ) then tryToMovePlayer(player.x,player.y+1) end
  339.    if ( direction == "left"  and player.x > 1  ) then tryToMovePlayer(player.x-1,player.y) end
  340.    if ( direction == "right" and player.x < map_max_x ) then tryToMovePlayer(player.x+1,player.y)  end  
  341.    if ( direction == "nw"    and player.x > 1 and
  342.                                  player.y > 1 ) then tryToMovePlayer(player.x-1,player.y-1) end
  343.    if ( direction == "ne"    and player.x < map_max_x and
  344.                                  player.y > 1 ) then tryToMovePlayer(player.x+1,player.y-1) end
  345.    if ( direction == "sw"    and player.x > 1 and
  346.                                  player.y < map_max_y ) then tryToMovePlayer(player.x-1,player.y+1) end
  347.    if ( direction == "se"    and player.x < map_max_x and
  348.                                  player.y < map_max_y ) then tryToMovePlayer(player.x+1,player.y+1) end
  349.  
  350.                          
  351.    
  352. end
  353.  
  354. function tryToMovePlayer(newx,newy)
  355.    tile = getMapTile(newx,newy)
  356.  
  357.    if ( tile == "#" ) then return end
  358.    player.x = newx
  359.    player.y = newy
  360.    viewChange = true
  361.    changeReveal()
  362.    moved = true
  363.    endTurn = true
  364.    
  365. end
  366.  
  367. function isKey(chara,str)
  368.    return ( chara == string.byte(str) or chara == string.byte(string.upper(str)) )
  369. end
  370.  
  371. mLog = {}
  372. logSize = 0
  373. function addLog(message)
  374.     logSize = logSize + 1
  375.    table.insert(mLog,message)
  376.     if ( logSize >= log_y_size ) then
  377.       logSize = logSize - 1
  378.       table.remove(mLog,1)
  379.    end
  380.    logChange = true
  381. end
  382.  
  383. function handleKey(address,chara,code,pname)
  384.    --print(chara,code)
  385.    if ( player.name == "Steve" ) then
  386.       player.name = pname
  387.       addLog(player.name .. " has entered the dungeon!")
  388.       infoChange = true
  389.    end    
  390.    if ( isKey(chara,"1") ) then quit_program = true end
  391.    
  392.    if ( showingInv ) then
  393.      showingInv = false
  394.      viewChange = true
  395.      logChange = true
  396.      infoChange = true
  397.      term.clear()
  398.      return
  399.    end
  400.    
  401.    if ( isKey(chara,"w") or code == 200 ) then movePlayer("up") end
  402.    if ( isKey(chara,"x") or code == 208 ) then movePlayer("down") end
  403.    if ( isKey(chara,"a") or code == 203 ) then movePlayer("left") end
  404.    if ( isKey(chara,"d") or code == 205 ) then movePlayer("right") end
  405.    if ( isKey(chara,"q") or code == 199 ) then movePlayer("nw") end
  406.    if ( isKey(chara,"e") or code == 201 ) then movePlayer("ne") end
  407.    if ( isKey(chara,"z") or code == 207 ) then movePlayer("sw") end
  408.    if ( isKey(chara,"c") or code == 209 ) then movePlayer("se") end
  409.    if ( isKey(chara,"g") ) then playerGet() end
  410.    if ( isKey(chara,"i") ) then showInventory() end
  411. end
  412.  
  413. function eventHandler(eventID,...)
  414.    if ( eventID == "key_down" ) then handleKey(...) end
  415. end
  416.  
  417. -- ITEMS
  418.  
  419. function getItemAt(x,y)
  420.    for i,item in pairs(floorItems) do
  421.       if ( item.x == x and item.y == y ) then
  422.       item.id = i
  423.       return item
  424.      end
  425.    end
  426. end
  427.  
  428. function addNewFloorItem(itemType,x,y,quantity)
  429.    local newItem = newItem(itemType,quantity)
  430.    newItem.x = x
  431.    newItem.y = y
  432.    table.insert(floorItems,newItem)
  433. end
  434.  
  435. function playerDropItem(item)
  436.    table.remove(player.inventory,item.id)
  437.    item.x = player.x
  438.    item.y = player.y
  439.    table.insert(floorItems,item)
  440.    if ( player.weapon == item ) then player.weapon = nil end
  441.    if ( player.armor == item ) then player.armor = nil end
  442. end
  443.  
  444. function getPlayerItem(item)
  445.    for i,sitem in pairs(player.inventory) do
  446.      
  447.       if ( item.name == sitem.name ) then
  448.          sitem.id = i
  449.          return sitem
  450.       end
  451.    end
  452. end
  453.  
  454. function playerGetItem(item)
  455.  
  456.    table.remove(floorItems,item.id)
  457.    if ( item.iType == "emerald" ) then
  458.       player.emeralds = player.emeralds + item.quantity
  459.       return
  460.    end
  461.    
  462.    if ( isItemStackable(item) ) then
  463.       existingItem = getPlayerItem(item)
  464.       if ( existingItem ~= nil ) then
  465.         if ( existingItem.quant >= 64 ) then return false end
  466.         existingItem.quant = math.min(existingItem.quant + item.quant,64)
  467.         return true
  468.       end
  469.    end
  470.    table.insert(player.inventory,item)
  471.    return true
  472. end
  473.  
  474. function newItem(itemType,quantity)
  475.    if ( quantity == nil or quantity < 1 ) then quantity = 1 end
  476.    local retItem = {
  477.       name = itemType,
  478.       quant = quantity
  479.    }
  480.    
  481.    if ( itemType == "Emerald" ) then retItem.iType = "emerald" end
  482.    
  483.    if ( itemType == "Apple" ) then
  484.       retItem.iType = "food"
  485.       retItem.value = 2
  486.    end
  487.    
  488.    
  489.    if ( retItem.iType == "food" ) then retItem.icon = "%" end
  490.    if ( retItem.iType == "weapon" ) then retItem.icon = "/" end
  491.    if ( retItem.iType == "armor" ) then retItem.icon = "]" end
  492.    if ( retItem.iType == "potion" ) then retItem.icon = "!" end
  493.    if ( retItem.iType == "emerald" ) then retItem.icon = "$" end
  494.    if ( retItem.iType == "craft" ) then retItem.icon = "^" end
  495.    
  496.    if ( retItem.iType == nil ) then addLog("Bad item: ".. itemType) end
  497.    if ( retItem.icon == nil ) then addLog("Bad itemtype: " .. retItem.iType) end
  498.    
  499.    return retItem
  500.  
  501. end
  502.  
  503. function isItemStackable(item)
  504.    if ( item.name == "Arrows" ) then return true end
  505.    if ( item.iType == "weapon" or item.iType == "armor" ) then return false end
  506.    return true
  507.  
  508. end
  509.  
  510. -- player actions
  511. function resolveMovement()  
  512. end
  513.  
  514. function playerGet()
  515.    item = getItemAt(player.x,player.y)
  516.    if ( item == nil ) then
  517.       addLog("Nothing to pick up here.")
  518.       return
  519.    end
  520.    if ( playerGetItem(item) ) then
  521.      addLog("You picked up the " .. item.name)
  522.    else
  523.      addLog("You can't hold any more.")
  524.    end
  525. end
  526.  
  527. -- Monsters?
  528. function resolveTurn()
  529. end
  530.  
  531. -- MAIN LOOP
  532.  
  533.  
  534. generateMap()
  535. term.clear()
  536.  
  537. while ( quit_program == false ) do
  538.    drawScreen()
  539.    viewChange = false
  540.    logChange = false
  541.    infoChange = false
  542.    moved = false
  543.    endTurn = false
  544.    eventHandler(event.pull())
  545.    if ( moved == true ) then resolveMovement() end
  546.    if ( endTurn == true ) then resolveTurn() end
  547.    
  548. end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement