Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- local function flipTable(table)
- local ntable = {}
- for i=1,#table do
- ntable[i] = table[#table - i + 1]
- end
- return ntable
- end
- local function drawLine(x1, y1, x2, y2)
- local pixs = {}
- x1 = math.floor(x1)
- y1 = math.floor(y1)
- x2 = math.floor(x2)
- y2 = math.floor(y2)
- if x1 == x2 and y1 == y2 then
- pixs[#pixs + 1] = {x1, y1}
- return pixs
- end
- local minX = math.min( x1, x2 )
- if minX == x1 then
- minY = y1
- maxX = x2
- maxY = y2
- else
- minY = y2
- maxX = x1
- maxY = y1
- end
- local xDiff = maxX - minX
- local yDiff = maxY - minY
- if xDiff > math.abs(yDiff) then
- local y = minY
- local dy = yDiff / xDiff
- for x=minX,maxX do
- if #pixs > 0 then
- if pixs[#pixs][1] == x and pixs[#pixs][2] == math.floor(y + 0.5) then else
- pixs[#pixs + 1] = {x, math.floor(y + 0.5)}
- end
- else
- pixs[#pixs + 1] = {x, math.floor(y + 0.5)}
- end
- y = y + dy
- end
- else
- local x = minX
- local dx = xDiff / yDiff
- if maxY >= minY then
- for y=minY,maxY do
- if #pixs > 0 then
- if pixs[#pixs][1] == math.floor(x+0.5) and pixs[#pixs][2] == y then else
- pixs[#pixs + 1] = {math.floor(x+0.5), y}
- end
- else
- pixs[#pixs + 1] = {math.floor(x+0.5), y}
- end
- x = x + dx
- end
- else
- for y=minY,maxY,-1 do
- if #pixs > 0 then
- if pixs[#pixs][1] == math.floor(x+0.5) and pixs[#pixs][2] == y then else
- pixs[#pixs + 1] = {math.floor(x+0.5), y}
- end
- else
- pixs[#pixs + 1] = {math.floor(x+0.5), y}
- end
- x = x - dx
- end
- end
- end
- if pixs[1][1] == x2 and pixs[1][2] == y2 then pixs = flipTable(pixs) end
- return pixs
- end
- local function createMap(width, height)
- local map = {}
- map.lights = {}
- map.width = width
- map.height = height
- map.offset = {0,0}
- map.convert = {
- {{colors.white, colors.black, " "}, {colors.yellow, colors.black, " "}},
- {{colors.black, colors.white, " "}, {colors.black, colors.white, " "}},
- {{colors.white, colors.white, " "}, {colors.lightGray, colors.lightGray, " "}, {colors.gray, colors.gray, " "}}
- }
- local boxs = {}
- for i=1,math.random(3, 6) do
- local h = math.random(2, 5)
- local w = math.random(2, 5)
- local box = {math.random(2, width-1-w), math.random(2, height-1-h), w, h}
- boxs[#boxs + 1] = box
- end
- for x=1,width do
- map[x] = {}
- for y=1,height do
- local id = 0
- if x == 1 or x == width or y == 1 or y == height then id = 1 end
- for i=1,#boxs do
- local box = boxs[i]
- if x >= box[1] and x < box[1]+box[3] and y >= box[2] and y < box[2]+box[4] then id = 1 end
- end
- map[x][y] = {id, false}
- end
- end
- map.draw = function(self)
- --term.setBackgroundColor(colors.black)
- --term.clear()
- --term.setCursorPos(1,1)
- for x=1,self.width do
- if self[x] ~= nil then
- for y=1,self.height do
- local p = self[x][y]
- local id = p[1] + 1
- local cols = self.convert[id]
- local col = cols[1]
- --if p[2] then col = cols[2] end
- if p[2] == false then col = self.convert[2][1] end
- if p[2] ~= false then
- cols = self.convert[3]
- local i = p[2] + 1
- if i > 3 then i = 3 end
- i = 3 - i + 1
- col = cols[i]
- end
- term.setCursorPos(x + self.offset[1], y + self.offset[2])
- term.setBackgroundColor(col[1])
- term.setTextColor(col[2])
- term.write(col[3])
- end
- end
- end
- end
- map.resetLight = function(self)
- for x=1,self.width do
- if self[x] ~= nil then
- for y=1,self.height do
- local p = self[x][y]
- p[2] = false
- end
- end
- end
- end
- map.doLight = function(self)
- self:resetLight()
- if #self.lights > 0 then
- for i=1,#self.lights do
- local l = self.lights[i]
- if self[l.x][l.y+1][1] == 0 then l.y = l.y + 1 end
- l:cast(self)
- end
- end
- end
- map.castRay = function(self, x1, y1, x2, y2)
- --print("CASTING RAY "..x1..","..y1.." TO "..x2..","..y2)
- local line = drawLine(x1, y1, x2, y2)
- --print("CAST RAY, CHECKING "..#line.." TILES")
- local lit = {}
- local ok = true
- for i=1,#line do
- if ok then
- local p = line[i]
- if self[p[1]] ~= nil then
- if self[p[1]][p[2]] ~= nil then
- if self[p[1]][p[2]][1] ~= 0 then
- --print("SOLID TILE FOUND")
- ok = false
- break
- else
- lit[#lit + 1] = p
- end
- else
- ok = false
- break
- end
- else
- --print("INVALID X FOUND")
- ok = false
- break
- end
- end
- end
- --print("LIT "..#lit.." TILES")
- --sleep(1)
- return lit
- end
- return map
- end
- local function getDistance(x1, y1, x2, y2)
- local dist = math.sqrt((math.abs(x1-x2)^2) + (math.abs(y1-y2)^2))
- return math.ceil(dist)
- end
- local function createLight(x, y, strength, arcRot1, arcRot2)
- local light = {}
- light.x = x
- light.y = y
- light.str = strength
- light.arc = {arcRot1, arcRot2}
- light.cast = function(self, map)
- for rot = self.arc[1],self.arc[2] do
- local r = math.rad(rot%360)
- local x2 = self.x + self.str * math.cos(r)
- local y2 = self.y + self.str * math.sin(r)
- local lit = map:castRay(self.x, self.y, math.floor(x2), math.floor(y2))
- local key = math.random()
- for i=1,#lit do
- local p = lit[i]
- local tab = map[p[1]][p[2]]
- --map[p[1]][p[2]][2] = math.abs(self.str-getDistance(self.x, self.y, p[1], p[2]))
- local j = #lit - i
- if tab[2] ~= false and tab[3] ~= key then
- if j == 1 and tab[2] == 1 then else
- j = j + tab[2]
- end
- end
- tab[2] = j
- tab[3] = key
- end
- end
- end
- return light
- end
- local map = createMap(term.getSize())
- local mid = {math.floor(map.width/2), math.floor(map.height/2)}
- --local l = createLight(mid[1], mid[2], 10, 1, 360)
- --map.lights[#map.lights + 1] = l
- local on = true
- local pause = 0.15
- local timer = os.startTimer(pause)
- while on do
- local event, p1, p2, p3 = os.pullEvent()
- if event == "key" then
- if p1 == 29 then on = false end
- elseif event == "mouse_click" or event == "mouse_drag" then
- if p1 == 1 then
- local l = createLight(p2, p3, 7, 1, 360)
- map.lights[#map.lights + 1] = l
- else
- map.lights = {}
- end
- elseif event == "timer" and p1 == timer then
- map:doLight()
- map:draw()
- timer = os.startTimer(pause)
- end
- end
- term.setBackgroundColor(colors.black)
- term.clear()
- term.setCursorPos(1,1)
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement