Advertisement
billysback

light

Aug 21st, 2013
138
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 6.44 KB | None | 0 0
  1.  
  2. local function flipTable(table)
  3.     local ntable = {}
  4.     for i=1,#table do
  5.         ntable[i] = table[#table - i + 1]
  6.     end
  7.     return ntable
  8. end
  9.  
  10. local function drawLine(x1, y1, x2, y2)
  11.         local pixs = {}
  12.        
  13.         x1 = math.floor(x1)
  14.         y1 = math.floor(y1)
  15.         x2 = math.floor(x2)
  16.         y2 = math.floor(y2)
  17.        
  18.         if x1 == x2 and y1 == y2 then
  19.             pixs[#pixs + 1] = {x1, y1}
  20.             return pixs
  21.         end
  22.        
  23.         local minX = math.min( x1, x2 )
  24.         if minX == x1 then
  25.                 minY = y1
  26.                 maxX = x2
  27.                 maxY = y2
  28.         else
  29.                 minY = y2
  30.                 maxX = x1
  31.                 maxY = y1
  32.         end
  33.                
  34.         local xDiff = maxX - minX
  35.         local yDiff = maxY - minY
  36.                        
  37.         if xDiff > math.abs(yDiff) then
  38.                 local y = minY
  39.                 local dy = yDiff / xDiff
  40.                 for x=minX,maxX do
  41.                         if #pixs > 0 then
  42.                             if pixs[#pixs][1] == x and pixs[#pixs][2] == math.floor(y + 0.5) then else
  43.                                 pixs[#pixs + 1] = {x, math.floor(y + 0.5)}
  44.                             end
  45.                         else
  46.                             pixs[#pixs + 1] = {x, math.floor(y + 0.5)}
  47.                         end
  48.                         y = y + dy
  49.                 end
  50.         else
  51.                 local x = minX
  52.                 local dx = xDiff / yDiff
  53.                 if maxY >= minY then
  54.                         for y=minY,maxY do
  55.                                 if #pixs > 0 then
  56.                                     if pixs[#pixs][1] == math.floor(x+0.5) and pixs[#pixs][2] == y then else
  57.                                         pixs[#pixs + 1] = {math.floor(x+0.5), y}
  58.                                     end
  59.                                 else
  60.                                     pixs[#pixs + 1] = {math.floor(x+0.5), y}
  61.                                 end
  62.                                 x = x + dx
  63.                         end
  64.                 else
  65.                         for y=minY,maxY,-1 do
  66.                                 if #pixs > 0 then
  67.                                     if pixs[#pixs][1] == math.floor(x+0.5) and pixs[#pixs][2] == y then else
  68.                                         pixs[#pixs + 1] = {math.floor(x+0.5), y}
  69.                                     end
  70.                                 else
  71.                                     pixs[#pixs + 1] = {math.floor(x+0.5), y}
  72.                                 end
  73.                                 x = x - dx
  74.                         end
  75.                 end
  76.         end
  77.         if pixs[1][1] == x2 and pixs[1][2] == y2 then pixs = flipTable(pixs) end
  78.         return pixs
  79. end
  80.  
  81. local function createMap(width, height)
  82.     local map = {}
  83.     map.lights = {}
  84.     map.width = width
  85.     map.height = height
  86.     map.offset = {0,0}
  87.     map.convert = {
  88.         {{colors.white, colors.black, " "}, {colors.yellow, colors.black, " "}},
  89.         {{colors.black, colors.white, " "}, {colors.black, colors.white, " "}},
  90.         {{colors.white, colors.white, " "}, {colors.lightGray, colors.lightGray, " "}, {colors.gray, colors.gray, " "}}
  91.     }
  92.     local boxs = {}
  93.     for i=1,math.random(3, 6) do
  94.         local h = math.random(2, 5)
  95.         local w = math.random(2, 5)
  96.         local box = {math.random(2, width-1-w), math.random(2, height-1-h), w, h}
  97.         boxs[#boxs + 1] = box
  98.     end
  99.     for x=1,width do
  100.         map[x] = {}
  101.         for y=1,height do
  102.             local id = 0
  103.             if x == 1 or x == width or y == 1 or y == height then id = 1 end
  104.             for i=1,#boxs do
  105.                 local box = boxs[i]
  106.                 if x >= box[1] and x < box[1]+box[3] and y >= box[2] and y < box[2]+box[4] then id = 1 end
  107.             end
  108.             map[x][y] = {id, false}
  109.         end
  110.     end
  111.    
  112.     map.draw = function(self)
  113.         --term.setBackgroundColor(colors.black)
  114.         --term.clear()
  115.         --term.setCursorPos(1,1)
  116.         for x=1,self.width do
  117.             if self[x] ~= nil then
  118.                 for y=1,self.height do
  119.                     local p = self[x][y]
  120.                     local id = p[1] + 1
  121.                     local cols = self.convert[id]
  122.                     local col = cols[1]
  123.                     --if p[2] then col = cols[2] end
  124.                     if p[2] == false then col = self.convert[2][1] end
  125.                     if p[2] ~= false then
  126.                         cols = self.convert[3]
  127.                         local i = p[2] + 1
  128.                         if i > 3 then i = 3 end
  129.                         i = 3 - i + 1
  130.                         col = cols[i]
  131.                     end
  132.                     term.setCursorPos(x + self.offset[1], y + self.offset[2])
  133.                     term.setBackgroundColor(col[1])
  134.                     term.setTextColor(col[2])
  135.                     term.write(col[3])
  136.                 end
  137.             end
  138.         end
  139.     end
  140.    
  141.     map.resetLight = function(self)
  142.         for x=1,self.width do
  143.             if self[x] ~= nil then
  144.                 for y=1,self.height do
  145.                     local p = self[x][y]
  146.                     p[2] = false
  147.                 end
  148.             end
  149.         end
  150.     end
  151.    
  152.     map.doLight = function(self)
  153.         self:resetLight()
  154.         if #self.lights > 0 then
  155.             for i=1,#self.lights do
  156.                 local l = self.lights[i]
  157.                 if self[l.x][l.y+1][1] == 0 then l.y = l.y + 1 end
  158.                 l:cast(self)
  159.             end
  160.         end
  161.     end
  162.    
  163.     map.castRay = function(self, x1, y1, x2, y2)
  164.         --print("CASTING RAY "..x1..","..y1.." TO "..x2..","..y2)
  165.         local line = drawLine(x1, y1, x2, y2)
  166.         --print("CAST RAY, CHECKING "..#line.." TILES")
  167.         local lit = {}
  168.         local ok = true
  169.         for i=1,#line do
  170.             if ok then
  171.                 local p = line[i]
  172.                 if self[p[1]] ~= nil then
  173.                     if self[p[1]][p[2]] ~= nil then
  174.                         if self[p[1]][p[2]][1] ~= 0 then
  175.                             --print("SOLID TILE FOUND")
  176.                             ok = false
  177.                             break
  178.                         else
  179.                             lit[#lit + 1] = p
  180.                         end
  181.                     else
  182.                         ok = false
  183.                         break
  184.                     end
  185.                 else
  186.                     --print("INVALID X FOUND")
  187.                     ok = false
  188.                     break
  189.                 end
  190.             end
  191.         end
  192.         --print("LIT "..#lit.." TILES")
  193.         --sleep(1)
  194.         return lit
  195.     end
  196.    
  197.     return map
  198. end
  199.  
  200. local function getDistance(x1, y1, x2, y2)
  201.     local dist = math.sqrt((math.abs(x1-x2)^2) + (math.abs(y1-y2)^2))
  202.     return math.ceil(dist)
  203. end
  204.  
  205. local function createLight(x, y, strength, arcRot1, arcRot2)
  206.     local light = {}
  207.     light.x = x
  208.     light.y = y
  209.     light.str = strength
  210.     light.arc = {arcRot1, arcRot2}
  211.     light.cast = function(self, map)
  212.         for rot = self.arc[1],self.arc[2] do
  213.             local r = math.rad(rot%360)
  214.             local x2 = self.x + self.str * math.cos(r)
  215.             local y2 = self.y + self.str * math.sin(r)
  216.             local lit = map:castRay(self.x, self.y, math.floor(x2), math.floor(y2))
  217.             local key = math.random()
  218.             for i=1,#lit do
  219.                 local p = lit[i]
  220.                 local tab = map[p[1]][p[2]]
  221.                 --map[p[1]][p[2]][2] = math.abs(self.str-getDistance(self.x, self.y, p[1], p[2]))
  222.                 local j = #lit - i
  223.                 if tab[2] ~= false and tab[3] ~= key then
  224.                     if j == 1 and tab[2] == 1 then else
  225.                         j = j + tab[2]
  226.                     end
  227.                 end
  228.                 tab[2] = j
  229.                 tab[3] = key
  230.             end
  231.         end
  232.     end
  233.     return light
  234. end
  235.  
  236.  
  237. local map = createMap(term.getSize())
  238.  
  239. local mid = {math.floor(map.width/2), math.floor(map.height/2)}
  240. --local l = createLight(mid[1], mid[2], 10, 1, 360)
  241. --map.lights[#map.lights + 1] = l
  242.  
  243. local on = true
  244. local pause = 0.15
  245. local timer = os.startTimer(pause)
  246. while on do
  247.     local event, p1, p2, p3 = os.pullEvent()
  248.     if event == "key" then
  249.         if p1 == 29 then on = false end
  250.     elseif event == "mouse_click" or event == "mouse_drag" then
  251.         if p1 == 1 then
  252.             local l = createLight(p2, p3, 7, 1, 360)
  253.             map.lights[#map.lights + 1] = l
  254.         else
  255.             map.lights = {}
  256.         end
  257.     elseif event == "timer" and p1 == timer then
  258.         map:doLight()
  259.         map:draw()
  260.         timer = os.startTimer(pause)
  261.     end
  262. end
  263.  
  264. term.setBackgroundColor(colors.black)
  265. term.clear()
  266. term.setCursorPos(1,1)
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement