local consts = require 'constants'
local tile = require 'tile'
local Board = {}
Board.__index = Board
function Board:new()
local t = {
base = {},
entity = {},
}
for y = 0, consts.boardHeight - 1 do
for x = 0, consts.boardWidth - 1 do
t.base[y * consts.boardWidth + x] = tile.getTile('grass')
t.entity[y * consts.boardWidth + x] = {}
end
end
return setmetatable(t, Board)
end
function loadBoard(filename)
local f = io.open(filename)
if f then
data = load('return ' .. f:read('*all'))()
local t = {
base = {},
entity = {},
}
for y = 0, consts.boardHeight - 1 do
for x = 0, consts.boardWidth - 1 do
local n = y * consts.boardWidth + x
for k, v in pairs(data[n+1]) do
if k == 1 then
t.base[n] = tile.getTile(v)
elseif k == 2 then
t.entity[n] = tile.copyTile(v)
else
t.entity[n][k] = v
end
end
end
end
return setmetatable(t, Board)
end
end
function loadBoardFromTiled(filename)
local data = loadfile(filename)()
local t = {
base = {},
entity = {},
}
for x = 0, consts.boardWidth - 1 do
for y = 0, consts.boardHeight - 1 do
local n = y * consts.boardWidth + x
local baseT = data.layers[1].data[n + 1]
if baseT ~= 0 then
t.base[n] = tile.getSprite(data, baseT)
end
local entityT = data.layers[2].data[n + 1]
if entityT ~= 0 then
t.entity[n] = t.entity[n] or {}
table.insert(t.entity[n], tile.getSprite(data, entityT))
end
local decorT = data.layers[3].data[n + 1]
if decorT ~= 0 then
t.entity[n] = t.entity[n] or {}
table.insert(t.entity[n], tile.getSprite(data, decorT))
end
end
end
for i, meta in pairs(data.layers[4].objects) do
local gx = math.floor(meta.x / consts.tileSize)
local gy = math.floor(meta.y / consts.tileSize)
local n = gy * consts.boardWidth + gx
if t.entity[n] then
local c = t.entity[n][1]:mkCopy()
for prop, val in pairs(meta.properties) do
c[prop] = val
end
t.entity[n][1] = c
end
end
t.south = data.properties.south
t.north = data.properties.north
t.east = data.properties.east
t.west = data.properties.west
return setmetatable(t, Board)
end
function Board:enterSquare(x, y, state)
if 0 <= x and x < consts.boardWidth then
local e = self.entity[y * consts.boardWidth + x]
if e and e[1] then e[1]:enterTile(state) end
end
end
function Board:offside(x, y)
if x < 0 then
return 'west'
elseif x >= consts.boardWidth then
return 'east'
elseif y < 0 then
return 'north'
elseif y >= consts.boardHeight then
return 'south'
end
end
function Board:lookup(x, y)
if 0 <= x and x < consts.boardWidth then
return self.base[y * consts.boardWidth + x]
end
end
function Board:set(x, y, r)
self.base[y * consts.boardWidth + x] = r
end
function Board:lookupEntity(x, y)
if 0 <= x and x < consts.boardWidth then
return self.entity[y * consts.boardWidth + x]
end
end
function Board:setEntity(x, y, r)
self.entity[y * consts.boardWidth + x] = r
end
function Board:passable(x, y)
local t, e = self:lookup(x, y), self:lookupEntity(x, y)
if e and e[1] then
return t and t.pass and e[1].pass
else
return t and t.pass
end
end
return {
Board = Board,
loadBoard = loadBoard,
loadBoardFromTiled = loadBoardFromTiled,
}