122 lines
4.2 KiB
Python
122 lines
4.2 KiB
Python
import sys
|
|
from constants import CHUNK_WIDTH, CHUNK_HEIGHT, CHUNK_TILE_COUNT, TILE_WIDTH_HEIGHT
|
|
import math
|
|
|
|
def parseChunkLayerData(layer, mapData, chunkData):
|
|
layerData = []
|
|
for y in range(CHUNK_HEIGHT):
|
|
for x in range(CHUNK_WIDTH):
|
|
inputTileIndex = chunkGetTileIndex(x, y, mapData, chunkData)
|
|
outputTileIndex = chunkGetOutputTileIndex(x, y)
|
|
layerData.append(layer['data'][inputTileIndex])
|
|
|
|
if len(layerData) != CHUNK_TILE_COUNT:
|
|
print(f"Error: Layer data length {len(layerData)} does not match expected chunk tile count {CHUNK_TILE_COUNT}.")
|
|
sys.exit(1)
|
|
|
|
return layerData
|
|
|
|
def parseChunk(chunkX, chunkY, mapData):
|
|
chunkData = { }
|
|
chunkData['topLeftTileX'] = chunkX * CHUNK_WIDTH
|
|
chunkData['topLeftTileY'] = chunkY * CHUNK_HEIGHT
|
|
chunkData['inputTopLeftTileX'] = math.floor(
|
|
float(chunkData['topLeftTileX']) / float(mapData['inputLayerWidthInTiles'])
|
|
) * mapData['inputLayerWidthInTiles']
|
|
chunkData['inputTopLeftTileY'] = math.floor(
|
|
float(chunkData['topLeftTileY']) / float(mapData['inputLayerHeightInTiles'])
|
|
) * mapData['inputLayerHeightInTiles']
|
|
|
|
# Get the data for this chunk out of the map data.
|
|
chunkData['layers'] = []
|
|
for layer in mapData['tileLayers']:
|
|
foundChunk = None
|
|
|
|
if 'chunks' not in layer or not isinstance(layer['chunks'], list):
|
|
print(f"Error: Layer '{layer['name']}' does not contain 'chunks' key or it is not a list.")
|
|
sys.exit(1)
|
|
|
|
for chunk in layer['chunks']:
|
|
if 'x' not in chunk or 'y' not in chunk:
|
|
print(f"Error: Chunk in layer '{layer['name']}' does not contain 'x' or 'y' key.")
|
|
sys.exit(1)
|
|
|
|
# Check if this chunk is within the bounds of the top left tile.
|
|
if chunk['x'] != chunkData['inputTopLeftTileX'] or chunk['y'] != chunkData['inputTopLeftTileY']:
|
|
continue
|
|
|
|
foundChunk = chunk
|
|
break
|
|
|
|
if foundChunk is None:
|
|
chunkData['layers'].append(None)
|
|
continue
|
|
|
|
# Is layer empty?
|
|
layerEmpty = True
|
|
for tile in foundChunk['data']:
|
|
if tile == 0:
|
|
continue
|
|
layerEmpty = False
|
|
break
|
|
|
|
if layerEmpty:
|
|
chunkData['layers'].append(None)
|
|
else:
|
|
chunkData['layers'].append(foundChunk)
|
|
|
|
# Any layers for this chunk?
|
|
if all(chunk is None for chunk in chunkData['layers']):
|
|
return None
|
|
|
|
if len(chunkData['layers']) == 0:
|
|
return None
|
|
|
|
# Parse Layer Data
|
|
chunkData['layerBase'] = chunkData['layers'][0]
|
|
chunkData['layerBaseOverlay'] = None
|
|
if len(chunkData['layers']) > 1:
|
|
chunkData['layerBaseOverlay'] = chunkData['layers'][1]
|
|
|
|
chunkData['layerBaseData'] = parseChunkLayerData(chunkData['layerBase'], mapData, chunkData)
|
|
if chunkData['layerBaseOverlay'] is not None:
|
|
chunkData['layerBaseOverlayData'] = parseChunkLayerData(chunkData['layerBaseOverlay'], mapData, chunkData)
|
|
else:
|
|
chunkData['layerBaseOverlayData'] = []
|
|
|
|
# Parse chunk entities.
|
|
chunkData['entities'] = []
|
|
for ob in mapData['objectLayer']['objects']:
|
|
if 'x' not in ob or 'y' not in ob:
|
|
print(f"Error: Object in object layer does not contain 'x' or 'y' key.")
|
|
sys.exit(1)
|
|
|
|
# Is this object within the chunk?
|
|
if ob['x'] < chunkData['topLeftTileX'] * TILE_WIDTH_HEIGHT:
|
|
continue
|
|
if ob['x'] >= (chunkData['topLeftTileX'] + CHUNK_WIDTH) * TILE_WIDTH_HEIGHT:
|
|
continue
|
|
if ob['y'] < chunkData['topLeftTileY'] * TILE_WIDTH_HEIGHT:
|
|
continue
|
|
if ob['y'] >= (chunkData['topLeftTileY'] + CHUNK_HEIGHT) * TILE_WIDTH_HEIGHT:
|
|
continue
|
|
|
|
chunkData['entities'].append(ob)
|
|
|
|
return chunkData
|
|
|
|
def chunkGetLocalTileX(absoluteTileX, mapData):
|
|
return absoluteTileX % mapData['inputLayerWidthInTiles']
|
|
|
|
def chunkGetLocalTileY(absoluteTileY, mapData):
|
|
return absoluteTileY % mapData['inputLayerHeightInTiles']
|
|
|
|
def chunkGetTileIndex(localX, localY, mapData, chunkData):
|
|
absoluteTileX = chunkData['topLeftTileX'] + localX
|
|
absoluteTileY = chunkData['topLeftTileY'] + localY
|
|
inputLocalTileX = chunkGetLocalTileX(absoluteTileX, mapData)
|
|
inputLocalTileY = chunkGetLocalTileY(absoluteTileY, mapData)
|
|
return inputLocalTileY * mapData['inputLayerWidthInTiles'] + inputLocalTileX
|
|
|
|
def chunkGetOutputTileIndex(localX, localY):
|
|
return localY * CHUNK_WIDTH + localX |