1
0
mirror of https://github.com/veden/Rampant.git synced 2024-12-30 21:19:46 +02:00
Rampant/libs/MapUtils.lua

177 lines
5.7 KiB
Lua
Executable File

local mapUtils = {}
-- imports
local constants = require("Constants")
-- constants
local CHUNK_NORTH_SOUTH = constants.CHUNK_NORTH_SOUTH
local CHUNK_EAST_WEST = constants.CHUNK_EAST_WEST
local CHUNK_ALL_DIRECTIONS = constants.CHUNK_ALL_DIRECTIONS
local PASSABLE = constants.PASSABLE
local CHUNK_SIZE = constants.CHUNK_SIZE
local SENTINEL_IMPASSABLE_CHUNK = constants.SENTINEL_IMPASSABLE_CHUNK
local CHUNK_SIZE_DIVIDER = constants.CHUNK_SIZE_DIVIDER
-- imported functions
local mFloor = math.floor
-- module code
function mapUtils.getChunkByXY(map, x, y)
local chunkX = map[x]
if chunkX then
return chunkX[y] or SENTINEL_IMPASSABLE_CHUNK
end
return SENTINEL_IMPASSABLE_CHUNK
end
function mapUtils.getChunkByPosition(map, position)
local chunkX = map[mFloor(position.x * CHUNK_SIZE_DIVIDER) * CHUNK_SIZE]
if chunkX then
local chunkY = mFloor(position.y * CHUNK_SIZE_DIVIDER) * CHUNK_SIZE
return chunkX[chunkY] or SENTINEL_IMPASSABLE_CHUNK
end
return SENTINEL_IMPASSABLE_CHUNK
end
function mapUtils.getChunkByUnalignedXY(map, x, y)
local chunkX = map[mFloor(x * CHUNK_SIZE_DIVIDER) * CHUNK_SIZE]
if chunkX then
local chunkY = mFloor(y * CHUNK_SIZE_DIVIDER) * CHUNK_SIZE
return chunkX[chunkY] or SENTINEL_IMPASSABLE_CHUNK
end
return SENTINEL_IMPASSABLE_CHUNK
end
function mapUtils.positionToChunkXY(position)
local chunkX = mFloor(position.x * CHUNK_SIZE_DIVIDER) * CHUNK_SIZE
local chunkY = mFloor(position.y * CHUNK_SIZE_DIVIDER) * CHUNK_SIZE
return chunkX, chunkY
end
--[[
1 2 3
\|/
4- -5
/|\
6 7 8
]]--
function mapUtils.getNeighborChunks(map, x, y)
local neighbors = map.neighbors
local chunkYRow1 = y - CHUNK_SIZE
local chunkYRow3 = y + CHUNK_SIZE
local xChunks = map[x-CHUNK_SIZE]
if xChunks then
neighbors[1] = xChunks[chunkYRow1] or SENTINEL_IMPASSABLE_CHUNK
neighbors[4] = xChunks[y] or SENTINEL_IMPASSABLE_CHUNK
neighbors[6] = xChunks[chunkYRow3] or SENTINEL_IMPASSABLE_CHUNK
else
neighbors[1] = SENTINEL_IMPASSABLE_CHUNK
neighbors[4] = SENTINEL_IMPASSABLE_CHUNK
neighbors[6] = SENTINEL_IMPASSABLE_CHUNK
end
xChunks = map[x+CHUNK_SIZE]
if xChunks then
neighbors[3] = xChunks[chunkYRow1] or SENTINEL_IMPASSABLE_CHUNK
neighbors[5] = xChunks[y] or SENTINEL_IMPASSABLE_CHUNK
neighbors[8] = xChunks[chunkYRow3] or SENTINEL_IMPASSABLE_CHUNK
else
neighbors[3] = SENTINEL_IMPASSABLE_CHUNK
neighbors[5] = SENTINEL_IMPASSABLE_CHUNK
neighbors[8] = SENTINEL_IMPASSABLE_CHUNK
end
xChunks = map[x]
if xChunks then
neighbors[2] = xChunks[chunkYRow1] or SENTINEL_IMPASSABLE_CHUNK
neighbors[7] = xChunks[chunkYRow3] or SENTINEL_IMPASSABLE_CHUNK
else
neighbors[2] = SENTINEL_IMPASSABLE_CHUNK
neighbors[7] = SENTINEL_IMPASSABLE_CHUNK
end
return neighbors
end
function mapUtils.canMoveChunkDirection(direction, startChunk, endChunk)
local canMove = false
local startPassable = startChunk[PASSABLE]
local endPassable = endChunk[PASSABLE]
if (startPassable == CHUNK_ALL_DIRECTIONS) and (endPassable == CHUNK_ALL_DIRECTIONS) then
canMove = true
elseif ((direction == 2) or (direction == 7)) and (startPassable == CHUNK_NORTH_SOUTH) and (endPassable == CHUNK_NORTH_SOUTH) then
canMove = true
elseif ((direction == 4) or (direction == 5)) and (startPassable == CHUNK_EAST_WEST) and (endPassable == CHUNK_EAST_WEST) then
canMove = true
elseif (startChunk == SENTINEL_IMPASSABLE_CHUNK) and (endPassable == CHUNK_ALL_DIRECTIONS) then
canMove = true
end
return canMove
end
function mapUtils.getCardinalChunks(map, x, y)
local neighbors = map.cardinalNeighbors
local xChunks = map[x]
if xChunks then
neighbors[1] = xChunks[y-CHUNK_SIZE] or SENTINEL_IMPASSABLE_CHUNK
neighbors[4] = xChunks[y+CHUNK_SIZE] or SENTINEL_IMPASSABLE_CHUNK
else
neighbors[1] = SENTINEL_IMPASSABLE_CHUNK
neighbors[4] = SENTINEL_IMPASSABLE_CHUNK
end
xChunks = map[x-CHUNK_SIZE]
if xChunks then
neighbors[2] = xChunks[y] or SENTINEL_IMPASSABLE_CHUNK
else
neighbors[2] = SENTINEL_IMPASSABLE_CHUNK
end
xChunks = map[x+CHUNK_SIZE]
if xChunks then
neighbors[3] = xChunks[y] or SENTINEL_IMPASSABLE_CHUNK
else
neighbors[3] = SENTINEL_IMPASSABLE_CHUNK
end
return neighbors
end
function mapUtils.positionFromDirectionAndChunk(direction, startPosition, endPosition, scaling)
if (direction == 1) then
endPosition.x = startPosition.x - CHUNK_SIZE * scaling
endPosition.y = startPosition.y - CHUNK_SIZE * scaling
elseif (direction == 2) then
endPosition.x = startPosition.x
endPosition.y = startPosition.y - CHUNK_SIZE * scaling
elseif (direction == 3) then
endPosition.x = startPosition.x + CHUNK_SIZE * scaling
endPosition.y = startPosition.y - CHUNK_SIZE * scaling
elseif (direction == 4) then
endPosition.x = startPosition.x - CHUNK_SIZE * scaling
endPosition.y = startPosition.y
elseif (direction == 5) then
endPosition.x = startPosition.x + CHUNK_SIZE * scaling
endPosition.y = startPosition.y
elseif (direction == 6) then
endPosition.x = startPosition.x - CHUNK_SIZE * scaling
endPosition.y = startPosition.y + CHUNK_SIZE * scaling
elseif (direction == 7) then
endPosition.x = startPosition.x
endPosition.y = startPosition.y + CHUNK_SIZE * scaling
elseif (direction == 8) then
endPosition.x = startPosition.x + CHUNK_SIZE * scaling
endPosition.y = startPosition.y + CHUNK_SIZE * scaling
end
return endPosition
end
return mapUtils