Advertisement
Jummit

Computercraft TerrariCCa Alpha

Mar 30th, 2018
204
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 17.30 KB | None | 0 0
  1. local engine = {}
  2. engine.w, engine.h = term.getSize()
  3.  
  4. engine.ui = {}
  5. engine.ui = {
  6.   isBoxClicked = function(box, x, y)
  7.     return x>=box.x and y>=box.y and x<box.x+box.w and y<box.y+box.h
  8.   end,
  9.   codes = {
  10.     [colors.red] = "e",
  11.     [colors.orange] = 1,
  12.     [colors.yellow] = 4,
  13.     [colors.black] = "f",
  14.     [colors.gray] = 7,
  15.     [colors.lightGray] = 8,
  16.     [colors.white] = 1,
  17.     [colors.blue] = "b",
  18.     [colors.cyan] = 9,
  19.     [colors.lightBlue] = 3,
  20.     [colors.green] = "d",
  21.     [colors.lime] = 5,
  22.     [colors.brown] = "c",
  23.     [colors.magenta] = 2,
  24.     [colors.pink] = 6,
  25.     [colors.purple] = "a",
  26.   },
  27.   getColorOfPaintCode = function(code)
  28.     for color, paintCode in pairs(engine.ui.paintColorCodes) do
  29.       if paintCode == code then return color end
  30.     end
  31.   end
  32. }
  33.  
  34. engine.mouseKeys = {"left", "right", "wheel"}
  35. engine.mouse = {x = 0, y = 0}
  36. engine.keyboard = {}
  37. engine.eventHandler = {
  38.   mouse_click = function(button, x, y)
  39.     engine.mouse.x, engine.mouse.y = x, y
  40.     engine.mouse[engine.mouseKeys[button]] = true
  41.   end,
  42.   mouse_up = function(button, x, y)
  43.     engine.mouse.x, engine.mouse.y = x, y
  44.     engine.mouse[engine.mouseKeys[button]] = false
  45.     engine.mouse.dragged = false
  46.   end,
  47.   mouse_drag = function(button, x, y)
  48.     engine.eventHandler.mouse_click(button, x, y)
  49.     engine.mouse.dragged = true
  50.   end,
  51.  
  52.   key = function(key)
  53.     engine.keyboard[keys.getName(key)] = true
  54.   end,
  55.   key_up = function(key)
  56.     engine.keyboard[keys.getName(key)] = false
  57.   end,
  58.   char = function(char)
  59.     engine.keyboard[char] = true
  60.   end
  61. }
  62.  
  63. engine.math = {
  64.   reduce = function(value)
  65.     local returnValue = value
  66.     if math.abs(value) ~= 0 then
  67.       if value > 0 then
  68.         returnValue = returnValue - 1
  69.       else
  70.         returnValue = returnValue + 1
  71.       end
  72.     end
  73.     return returnValue
  74.   end,
  75.   getOffset = function(w, pos)
  76.     return math.floor(-pos+w/2)
  77.   end,
  78.   getDistance = function(x1, y1, x2, y2)
  79.     --error(x1.." "..x2.." "..y1.." "..y2.." "..math.sqrt((x1-x2)^2+(y2-y2)^2))
  80.     return math.sqrt((x1-x2)^2+(y1-y2)^2)
  81.   end
  82. }
  83.  
  84. engine.elements = {}
  85. engine.elements.methods = {
  86.   element = true,
  87.   moveAndCollide = function(self, xmove, ymove, tilemap)
  88.     local canMove = true
  89.     for x = self.x, self.x+self.w-1 do
  90.       for y = self.y, self.y+self.h-1 do
  91.         local tile = tilemap:getTile(x+xmove, y+ymove)
  92.         if (not tile) or tile.solid then canMove = false end
  93.       end
  94.     end
  95.     if canMove then
  96.       self:move(xmove, ymove)
  97.     end
  98.   end,
  99.   move = function(self, xmove, ymove)
  100.     self.x = self.x + xmove
  101.     self.y = self.y + ymove
  102.   end
  103. }
  104. engine.elements.newElement = function(elementTable)
  105.   return function(argTable)
  106.     return setmetatable(argTable, {__index = setmetatable(elementTable, {__index = engine.elements.methods})})
  107.   end
  108. end
  109. engine.elements.new = {
  110.   template = engine.elements.newElement({
  111.     INIT = function(self)
  112.     end,
  113.     UPDATE = function(self, event, var1, var2, var3)
  114.     end,
  115.     DRAW = function(self)
  116.     end
  117.   }),
  118.   texture = engine.elements.newElement({
  119.     offX = 0,
  120.     offY = 0,
  121.     getDimensions = function(self)
  122.       local w = 1
  123.       for rowNum = 1, #self do
  124.         local row = self[rowNum][1]
  125.         if #row > w then
  126.           w = #row
  127.         end
  128.       end
  129.       return w, #self
  130.     end,
  131.     INIT = function(self)
  132.       self.w, self.h = self:getDimensions()
  133.     end,
  134.     DRAW = function(self)
  135.       if self.x and self.y then
  136.         self:drawTexture(self.x, self.y)
  137.       end
  138.     end,
  139.     drawTexture = function(self, x, y, offX, offY)
  140.       local drawX, drawY = x+(offX or 0)+self.offX, y+(offY or 0)+self.offY
  141.       if not (drawX < 0 or drawX > engine.w or drawY < 0 or drawY > engine.h) then
  142.         for row = 1, #self do
  143.           local texture = self[row]
  144.           term.setCursorPos(drawX, drawY+row-1)
  145.           term.blit(texture[1], texture[2], texture[3])
  146.         end
  147.       end
  148.     end,
  149.     replaceColor = function(self, toReplaceColor, color)
  150.       for row = 1, #self do
  151.         local texture = self[row]
  152.         for i = 2, #texture do
  153.           texture[i] = string.gsub(texture[i], toReplaceColor, color)
  154.         end
  155.       end
  156.     end
  157.   }),
  158.   button = engine.elements.newElement({
  159.     clicked = false,
  160.     INIT = function(self)
  161.       self.mouse_drag = self.mouse_click
  162.     end,
  163.     mouse_click = function(self, button, x, y)
  164.       if engine.ui.isBoxClicked(self, x, y) then
  165.         self.clicked = true
  166.         if self.clickedFunction then
  167.           self:clickedFunction()
  168.         end
  169.       else
  170.         self.clicked = false
  171.       end
  172.     end,
  173.     mouse_up = function(self)
  174.       if self.clicked then
  175.         if self.releasedFunction then
  176.           self:releasedFunction()
  177.         end
  178.         self.clicked = false
  179.       end
  180.     end,
  181.     DRAW = function(self)
  182.       local color = self.color
  183.       if self.clicked then
  184.         color = self.clickedColor
  185.       end
  186.       paintutils.drawFilledBox(self.x, self.y, self.x+self.w, self.y+self.h, color)
  187.     end
  188.   }),
  189.   tileset = engine.elements.newElement({
  190.   }),
  191.   tilemap = engine.elements.newElement({
  192.     INIT = function(self)
  193.       self.w, self.h = 0, 0
  194.     end,
  195.     offX = 0,
  196.     offY = 0,
  197.     DRAW = function(self)
  198.       offX, offY = self.offX, self.offY
  199.       for x = 1, engine.w do
  200.         for y = 1, engine.h do
  201.           if self[x-offX] then
  202.             local tile = self.tileset[self[x-offX][y-offY]]
  203.             if tile then
  204.               tile.texture:drawTexture(x, y)
  205.             end
  206.           end
  207.         end
  208.       end
  209.     end,
  210.     updateDimensions = function(self)
  211.       local h = 0
  212.       for rowNum = 1, #self do
  213.         local row = self[rowNum]
  214.         if #row > h then
  215.           h = #row
  216.         end
  217.       end
  218.       self.w, self.h = #self, h
  219.     end,
  220.     getTile = function(self, x, y)
  221.       if self[x] then
  222.         return self.tileset[self[x][y]]
  223.       end
  224.     end,
  225.     set = {
  226.       tile = function(self, x, y, tile)
  227.         local tileToSet = tile
  228.         if type(tile) == "table" then
  229.           tileToSet = tile[math.random(#tile)]
  230.         end
  231.         if not self[x] then self[x] = {} end
  232.         self[x][y] = tileToSet
  233.         --self:updateDimensions()
  234.       end,
  235.       rectangle = function(self, x, y, w, h, tile)
  236.         for x = x, x+w-1 do
  237.           for y = y, y+h-1 do
  238.             self.set.tile(self, x, y, tile)
  239.           end
  240.         end
  241.       end,
  242.       sphere = function(self, sx, sy, r, tile)
  243.         for x = sx-r*2, sx+r*2 do
  244.           for y = sy-r*2, sy+r*2 do
  245.             if engine.math.getDistance(x, y, sx, sy) <= r then
  246.               self.set.tile(self, x, y, tile)
  247.             end
  248.           end
  249.         end
  250.       end
  251.     }
  252.   }),
  253.   kinematic = engine.elements.newElement({
  254.     jumping = false,
  255.     jumpedHeight = 0,
  256.     w = 1, h = 1,
  257.     moves = {
  258.       left = {-1, 0},
  259.       right = {1, 0}
  260.     },
  261.     INIT = function(self)
  262.       self.w, self.h = self.texture:getDimensions()
  263.     end,
  264.     UPDATE = function(self)
  265.       self.jumping = engine.keyboard.up
  266.       if self.tilemap:getTile(self.x, self.y-1).solid then
  267.         self.jumping = false
  268.       end
  269.     end,
  270.     DRAW = function(self)
  271.       self.texture:drawTexture(self.x, self.y, self.offX, self.offY)
  272.     end,
  273.     PHYSICSUPDATE = function(self)
  274.       for key, move in pairs(self.moves) do
  275.         if engine.keyboard[key] then
  276.           self:moveAndCollide(move[1], move[2], self.tilemap)
  277.         end
  278.       end
  279.  
  280.       if self.jumping and self.jumpedHeight<self.maxJumpHeight then
  281.         self:moveAndCollide(0, -1, self.tilemap)
  282.         self.jumpedHeight = self.jumpedHeight + 1
  283.       else
  284.         self:moveAndCollide(0, 1, self.tilemap)
  285.       end
  286.       if self.tilemap:getTile(self.x, self.y+self.h).solid then
  287.         self.jumpedHeight = 0
  288.       end
  289.     end
  290.   })
  291. }
  292. engine.elements.new.inventory = engine.elements.newElement({
  293.   INIT = function(self)
  294.     for slotNum = 1, self.slotNum do
  295.       self[slotNum] = {}
  296.     end
  297.   end,
  298.   UPDATE = function(self, event, var1, var2, var3)
  299.   end,
  300.   textures = {
  301.     up = engine.elements.new.texture({{"\143", "a", "0"}}),
  302.     left = engine.elements.new.texture({{"\149", "a", "0"}}),
  303.     right = engine.elements.new.texture({{"\149", "0", "a"}}),
  304.     down = engine.elements.new.texture({{"\131", "0", "a"}})
  305.   },
  306.   charPos = {
  307.     up = {0, -1},
  308.     down = {0, 1},
  309.     left = {-1, 0},
  310.     right = {1, 0},
  311.   },
  312.   drawSlot = function(self, slotNum)
  313.     local slotX, slotY = self.x+(slotNum-1)*3, self.y
  314.     for direction, pos in pairs(self.charPos) do
  315.       local charX, charY = slotX+pos[1], slotY+pos[2]
  316.       local texture = self.textures[direction]
  317.       local tileX, tileY = charX-self.tilemap.offX, charY-self.tilemap.offY
  318.       local colorOfTile = self.tilemap:getTile(tileX, tileY).texture[1][3]
  319.       texture:replaceColor("a", colorOfTile)
  320.       texture:drawTexture(charX, charY)
  321.       texture:replaceColor(colorOfTile, "a")
  322.     end
  323.   end,
  324.   DRAW = function(self)
  325.     for slotNum = 1, #self do
  326.       self:drawSlot(slotNum)
  327.     end
  328.   end
  329. })
  330.  
  331. engine.elements.runFunction = function(elements, func, ...)
  332.   local prioritys = {}
  333.   for elementName, element in pairs(elements) do
  334.     local priority = element.priority
  335.     if priority then
  336.       if priority == true then
  337.         table.insert(prioritys, element)
  338.       else
  339.         prioritys[priority] = element
  340.       end
  341.     end
  342.     if element.element then
  343.       if element[func] then
  344.         element[func](element, ...)
  345.       end
  346.     else
  347.       engine.elements.runFunction(element, func, ...)
  348.     end
  349.   end
  350.   for priorityNum = 1, #prioritys do
  351.     local element = prioritys[priorityNum]
  352.     if element[func] then
  353.       element[func](element, ...)
  354.     end
  355.   end
  356. end
  357. engine.elements.init = function(elements)
  358.   engine.elements.runFunction(elements, "INIT")
  359.   engine.elements.runFunction(elements, "init")
  360. end
  361. engine.elements.update = function(elements, event, ...)
  362.   engine.elements.runFunction(elements, "UPDATE", event, ...)
  363.   engine.elements.runFunction(elements, "update", event, ...)
  364.   engine.elements.runFunction(elements, event, ...)
  365. end
  366. engine.elements.physicsUpdate = function(elements)
  367.   engine.elements.runFunction(elements, "PHYSICSUPDATE")
  368.   engine.elements.runFunction(elements, "physicsUpdate")
  369. end
  370. engine.elements.draw = function(elements)
  371.   engine.elements.runFunction(elements, "DRAW")
  372.   engine.elements.runFunction(elements, "draw")
  373. end
  374.  
  375. engine.run = function(elements, dt)
  376.   engine.elements.init(elements)
  377.  
  378.   local dt = dt or 0.01
  379.   local buffer = window.create(term.current(), 1, 1, engine.w, engine.h)
  380.   local oldTerm = term.redirect(buffer)
  381.  
  382.   local succ, mess = pcall(function()
  383.   local gameRunning = true
  384.   local physicsUpdateTimer = os.startTimer(0.1)
  385.   while gameRunning do
  386.     buffer.setVisible(false)
  387.     term.setBackgroundColor(colors.black)
  388.     term.clear()
  389.     engine.elements.draw(elements)
  390.     buffer.setVisible(true)
  391.  
  392.     local event, var1, var2, var3 = os.pullEventRaw()
  393.     if engine.eventHandler[event] then
  394.       engine.eventHandler[event](var1, var2, var3)
  395.     end
  396.     if event == "timer" then
  397.       engine.elements.physicsUpdate(elements)
  398.       os.cancelTimer(physicsUpdateTimer)
  399.       physicsUpdateTimer = os.startTimer(0.1)
  400.     end
  401.     if event == "char" and var1 == "q" then gameRunning = false end
  402.     engine.elements.update(elements, event, var1, var2, var3)
  403.   end
  404.   end)
  405.  
  406.   buffer.setVisible(true)
  407.   term.setBackgroundColor(colors.black)
  408.   term.clear()
  409.   term.setCursorPos(1, 1)
  410.   term.setTextColor(colors.red)
  411.   if not succ and mess then
  412.     print("The game crashed!")
  413.     print("Error: "..tostring(mess))
  414.   end
  415. end
  416.  
  417. local elements = {}
  418. elements.tilemap = engine.elements.new.tilemap({
  419.   offset = {0, 0},
  420.   tileset = engine.elements.new.tileset({
  421.     air = {texture = engine.elements.new.texture({{" ", "3", "3"}})},
  422.     grass = {texture = engine.elements.new.texture({{" ", "7", "d"}}),solid = true, behind = "dirt"},
  423.     plant = {texture = engine.elements.new.texture({{"p", "d", "3"}})},
  424.     dirt = {texture = engine.elements.new.texture({{" ", "7", "c"}}), solid = true, behind = "wall"},
  425.     stone = {texture = engine.elements.new.texture({{" ", "f", "8"}}), solid = true, behind = "wall"},
  426.     leaves = {texture = engine.elements.new.texture({{"b", "5", "d"}}), behind = "air"},
  427.     log = {texture = engine.elements.new.texture({{"B", "7", "c"}}), behind = "air"},
  428.   }),
  429.   createWall = function(self, tileName)
  430.     local tile = self.tileset[tileName]
  431.     self.tileset[tileName.."wall"] = {
  432.       texture = engine.elements.new.texture({{"\127", tile.texture[1][3], "7"}})
  433.     }
  434.   end,
  435.   changeMove = function(oldMove)
  436.     local move = oldMove
  437.     if math.random(1, 10) == 1 then
  438.       if math.random(2) == 1 then
  439.         move = 0.6
  440.       else
  441.         move = -0.6
  442.       end
  443.       if math.random(1, 10) == 1 then
  444.         move = move * 2
  445.       end
  446.     elseif math.random(1, 10) == 1 then
  447.       move = engine.math.reduce(oldMove)
  448.     elseif math.random(1, 10) == 1 then
  449.       move = move + 0.5
  450.     elseif math.random(1, 10) == 1 then
  451.       move = move - 0.5
  452.     end
  453.     if math.abs(move) >= 3 then
  454.       engine.math.reduce(move)
  455.     end
  456.     return move
  457.   end,
  458.   generateLine = function(self, x, surfaceHeight, stoneHeight, height)
  459.     self.set.rectangle(self, x, surfaceHeight, 1, height-surfaceHeight, "dirt")
  460.     self.set.rectangle(self, x, stoneHeight, 1, height-stoneHeight, "stone")
  461.     self.set.tile(self, x, surfaceHeight, "grass")
  462.     if math.random(1, 5) == 1 then
  463.       self.set.tile(self, x, surfaceHeight+1, "grass")
  464.     end
  465.     if math.random(1, 2) == 1 then
  466.       self.set.tile(self, x, surfaceHeight-1, "plant")
  467.     end
  468.   end,
  469.   addTree = function(self, x, trees, surfaceHeight, height)
  470.     local height = math.random(4, 12)
  471.     table.insert(trees, {
  472.       x = x, y = surfaceHeight-height-1,
  473.       height = height,
  474.     })
  475.     return trees
  476.   end,
  477.   generateStump = function(self, tree)
  478.     for y = tree.y, tree.y+tree.height do
  479.       self.set.tile(self, tree.x, y, "log")
  480.     end
  481.   end,
  482.   generateLeaves = function(self, tree)
  483.     self.set.sphere(self, tree.x, tree.y, tree.height/2, "leaves")
  484.   end,
  485.   generateWalls = function(self)
  486.     for tileName, tile in pairs(self.tileset) do
  487.       if tile.texture then
  488.         self:createWall(tileName)
  489.       end
  490.     end
  491.   end,
  492.   generateTrees = function(self, trees)
  493.     local generatedTrees = {}
  494.     for treeNum = 1, #trees do
  495.       local tree = trees[treeNum]
  496.       if not generatedTrees[tree.x-1] and not generatedTrees[tree.x+1] then
  497.         self:generateStump(tree)
  498.         generatedTrees[tree.x] = true
  499.       end
  500.     end
  501.     for treeNum = 1, #trees do
  502.       local tree = trees[treeNum]
  503.       if not generatedTrees[tree.x-1] and not generatedTrees[tree.x+1] then
  504.         self:generateLeaves(tree)
  505.         generatedTrees[tree.x] = true
  506.       end
  507.     end
  508.   end,
  509.   spawnPlayer = function(self)
  510.     local y = 1
  511.     while true do
  512.       if self[elements.player.x][y] ~= "air" then
  513.         elements.player.y = y-1
  514.         return
  515.       end
  516.       y = y + 1
  517.     end
  518.   end,
  519.   init = function(self)
  520.     local trees = {}
  521.     local width = engine.w*50
  522.     local height = engine.h*20
  523.     local surfaceY = math.floor(height/2)
  524.     local surfaceHeight = surfaceY
  525.     local stoneHeight = surfaceY+10
  526.     local move = 0
  527.  
  528.     self:generateWalls()
  529.     self.set.rectangle(self, 1, 1, width, height, "air")
  530.  
  531.     for x = 1, width do
  532.       move = self.changeMove(move)
  533.       stoneHeight = stoneHeight + move+math.random(3)-2
  534.       surfaceHeight = surfaceHeight + move
  535.       local tiledSurfaceHeight = math.floor(surfaceHeight)
  536.       local tiledStoneHeight = math.floor(stoneHeight)
  537.       if stoneHeight-surfaceHeight < 5 then stoneHeight = stoneHeight + 2 end
  538.  
  539.       self:generateLine(x, tiledSurfaceHeight, tiledStoneHeight, height)
  540.       if math.floor(move) == 0 and math.random(1, 5) == 1 then
  541.         trees = self:addTree(x, trees, tiledSurfaceHeight, height)
  542.       end
  543.     end
  544.  
  545.     self:spawnPlayer()
  546.     self:generateTrees(trees)
  547.   end
  548. })
  549. elements.player = engine.elements.new.kinematic({
  550.   priority = true,
  551.   tilemap = elements.tilemap,
  552.   texture = engine.elements.new.texture({
  553.     {" ", "4", "4"},
  554.     {" ", "9", "9"}
  555.   }),
  556.   x = math.floor(engine.w*3/2), y = 3,
  557.   maxJumpHeight = 6,
  558.   breakBlock = function(self, tileX, tileY)
  559.     local tileToSetOn = self.tilemap:getTile(tileX, tileY)
  560.     if tileToSetOn then
  561.       local tileToSet = tileToSetOn.behind
  562.       local tileName = self.tilemap[tileX][tileY]
  563.       if tileToSet == "wall" then
  564.         tileToSet = tileName.."wall"
  565.       end
  566.       if tileToSet then
  567.         if not self.tilemap.tileset[tileToSet] then
  568.           self.tilemap:createWall(tileName)
  569.         end
  570.         self.tilemap.set.tile(self.tilemap, tileX, tileY, tileToSet)
  571.       end
  572.     end
  573.   end,
  574.   update = function(self)
  575.     local offX, offY = engine.math.getOffset(engine.w, self.x), engine.math.getOffset(engine.h, self.y)
  576.     self.offX, self.offY = offX, offY
  577.     self.tilemap.offX, self.tilemap.offY = offX, offY
  578.     if engine.mouse.left then
  579.       self:breakBlock(engine.mouse.x-offX, engine.mouse.y-offY)
  580.     end
  581.   end
  582. })
  583. elements.inventory = engine.elements.new.inventory({
  584.   x = 3, y = 3, slotNum = 5, priority = true, tilemap = elements.tilemap
  585. })
  586.  
  587. engine.run(elements, 0.001)
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement