A smarter (?) attempt at rotating everything.
This commit is contained in:
5
chunk.py
5
chunk.py
@@ -55,8 +55,7 @@ def get_lvldata(world, filename, x, y, retries=2):
|
|||||||
raise NoSuchChunk
|
raise NoSuchChunk
|
||||||
|
|
||||||
try:
|
try:
|
||||||
d = world.load_from_region(filename, x, y)
|
d = world.load_from_region(filename, x, y)
|
||||||
#TODO should probably do rotation from here
|
|
||||||
except Exception, e:
|
except Exception, e:
|
||||||
if retries > 0:
|
if retries > 0:
|
||||||
# wait a little bit, and try again (up to `retries` times)
|
# wait a little bit, and try again (up to `retries` times)
|
||||||
@@ -78,7 +77,7 @@ def get_blockarray(level, north_direction):
|
|||||||
|
|
||||||
def get_blockarray_fromfile(filename, north_direction):
|
def get_blockarray_fromfile(filename, north_direction):
|
||||||
"""Same as get_blockarray except takes a filename. This is a shortcut"""
|
"""Same as get_blockarray except takes a filename. This is a shortcut"""
|
||||||
d = nbt.load_from_region(filename, x, y)
|
d = nbt.load_from_region(filename, x, y, north_direction)
|
||||||
level = d[1]['Level']
|
level = d[1]['Level']
|
||||||
return get_blockarray(level, north_direction)
|
return get_blockarray(level, north_direction)
|
||||||
|
|
||||||
|
|||||||
29
nbt.py
29
nbt.py
@@ -17,6 +17,7 @@ import gzip, zlib
|
|||||||
import struct
|
import struct
|
||||||
import StringIO
|
import StringIO
|
||||||
import os
|
import os
|
||||||
|
import numpy
|
||||||
|
|
||||||
# decorator to handle filename or object as first parameter
|
# decorator to handle filename or object as first parameter
|
||||||
def _file_loader(func):
|
def _file_loader(func):
|
||||||
@@ -34,15 +35,15 @@ def _file_loader(func):
|
|||||||
def load(fileobj):
|
def load(fileobj):
|
||||||
return NBTFileReader(fileobj).read_all()
|
return NBTFileReader(fileobj).read_all()
|
||||||
|
|
||||||
def load_from_region(filename, x, y):
|
def load_from_region(filename, x, y, north_direction):
|
||||||
nbt = load_region(filename).load_chunk(x, y)
|
nbt = load_region(filename, north_direction).load_chunk(x, y)
|
||||||
if nbt is None:
|
if nbt is None:
|
||||||
return None ## return none. I think this is who we should indicate missing chunks
|
return None ## return none. I think this is who we should indicate missing chunks
|
||||||
#raise IOError("No such chunk in region: (%i, %i)" % (x, y))
|
#raise IOError("No such chunk in region: (%i, %i)" % (x, y))
|
||||||
return nbt.read_all()
|
return nbt.read_all()
|
||||||
|
|
||||||
def load_region(filename):
|
def load_region(filename, north_direction):
|
||||||
return MCRFileReader(filename)
|
return MCRFileReader(filename, north_direction)
|
||||||
|
|
||||||
|
|
||||||
# compile the unpacker's into a classes
|
# compile the unpacker's into a classes
|
||||||
@@ -199,13 +200,25 @@ class MCRFileReader(object):
|
|||||||
chunks (as instances of NBTFileReader), getting chunk timestamps,
|
chunks (as instances of NBTFileReader), getting chunk timestamps,
|
||||||
and for listing chunks contained in the file."""
|
and for listing chunks contained in the file."""
|
||||||
|
|
||||||
def __init__(self, filename):
|
def __init__(self, filename, north_direction):
|
||||||
self._file = None
|
self._file = None
|
||||||
self._filename = filename
|
self._filename = filename
|
||||||
|
self.north_direction = north_direction
|
||||||
# cache used when the entire header tables are read in get_chunks()
|
# cache used when the entire header tables are read in get_chunks()
|
||||||
self._locations = None
|
self._locations = None
|
||||||
self._timestamps = None
|
self._timestamps = None
|
||||||
self._chunks = None
|
self._chunks = None
|
||||||
|
|
||||||
|
def get_north_rotations(self):
|
||||||
|
#Upper-left and lower-right are swapped from chunk.py rots
|
||||||
|
if self.north_direction == "upper-left":
|
||||||
|
return 3
|
||||||
|
elif self.north_direction == "upper-right":
|
||||||
|
return 2
|
||||||
|
elif self.north_direction == "lower-right":
|
||||||
|
return 1
|
||||||
|
elif self.north_direction == "lower-left":
|
||||||
|
return 0
|
||||||
|
|
||||||
def _read_24bit_int(self):
|
def _read_24bit_int(self):
|
||||||
"""Read in a 24-bit, big-endian int, used in the chunk
|
"""Read in a 24-bit, big-endian int, used in the chunk
|
||||||
@@ -328,11 +341,13 @@ class MCRFileReader(object):
|
|||||||
locations_append = self._locations.append
|
locations_append = self._locations.append
|
||||||
for _ in xrange(32*32):
|
for _ in xrange(32*32):
|
||||||
locations_append(self._read_chunk_location())
|
locations_append(self._read_chunk_location())
|
||||||
|
self._locations = numpy.reshape(numpy.rot90(numpy.reshape(self._locations, (32,32)),self.get_north_rotations()), -1)
|
||||||
|
|
||||||
# read chunk timestamp table
|
# read chunk timestamp table
|
||||||
timestamp_append = self._timestamps.append
|
timestamp_append = self._timestamps.append
|
||||||
for _ in xrange(32*32):
|
for _ in xrange(32*32):
|
||||||
timestamp_append(self._read_chunk_timestamp())
|
timestamp_append(self._read_chunk_timestamp())
|
||||||
|
self._timestamps = numpy.reshape(numpy.rot90(numpy.reshape(self._timestamps, (32,32)),self.get_north_rotations()), -1)
|
||||||
|
|
||||||
if closeFile:
|
if closeFile:
|
||||||
self.closefile()
|
self.closefile()
|
||||||
@@ -344,10 +359,10 @@ class MCRFileReader(object):
|
|||||||
load_chunk(), this will wrap x and y into the range [0, 31].
|
load_chunk(), this will wrap x and y into the range [0, 31].
|
||||||
"""
|
"""
|
||||||
x = x % 32
|
x = x % 32
|
||||||
y = y % 32
|
y = y % 32
|
||||||
if self._timestamps is None:
|
if self._timestamps is None:
|
||||||
self.get_chunk_info()
|
self.get_chunk_info()
|
||||||
return self._timestamps[x + y * 32]
|
return self._timestamps[x + y * 32]
|
||||||
|
|
||||||
def chunkExists(self, x, y):
|
def chunkExists(self, x, y):
|
||||||
"""Determines if a chunk exists without triggering loading of the backend data"""
|
"""Determines if a chunk exists without triggering loading of the backend data"""
|
||||||
|
|||||||
@@ -240,10 +240,6 @@ class QuadtreeGen(object):
|
|||||||
continue
|
continue
|
||||||
|
|
||||||
chunkx, chunky = unconvert_coords(col, row)
|
chunkx, chunky = unconvert_coords(col, row)
|
||||||
if self.north_direction == 'upper-right':
|
|
||||||
chunky = -chunky
|
|
||||||
elif self.north_direction == 'lower-right':
|
|
||||||
chunkx = -chunkx
|
|
||||||
|
|
||||||
regionx_ = chunkx//32
|
regionx_ = chunkx//32
|
||||||
regiony_ = chunky//32
|
regiony_ = chunky//32
|
||||||
|
|||||||
25
world.py
25
world.py
@@ -169,7 +169,7 @@ class World(object):
|
|||||||
if self.regions.get(filename) is not None:
|
if self.regions.get(filename) is not None:
|
||||||
self.regions[filename][0].closefile()
|
self.regions[filename][0].closefile()
|
||||||
chunkcache = {}
|
chunkcache = {}
|
||||||
mcr = nbt.MCRFileReader(filename)
|
mcr = nbt.MCRFileReader(filename, self.north_direction)
|
||||||
self.regions[filename] = (mcr,os.path.getmtime(filename),chunkcache)
|
self.regions[filename] = (mcr,os.path.getmtime(filename),chunkcache)
|
||||||
return mcr
|
return mcr
|
||||||
|
|
||||||
@@ -185,26 +185,12 @@ class World(object):
|
|||||||
in the image each one should be. Returns (col, row)."""
|
in the image each one should be. Returns (col, row)."""
|
||||||
|
|
||||||
# change this function, and you MUST change unconvert_coords
|
# change this function, and you MUST change unconvert_coords
|
||||||
if self.north_direction == 'lower-left':
|
return (chunkx + chunky, chunky - chunkx)
|
||||||
return (chunkx + chunky, chunky - chunkx)
|
|
||||||
elif self.north_direction == 'lower-right':
|
|
||||||
return (chunkx + chunky, chunkx - chunky)
|
|
||||||
elif self.north_direction == 'upper-left':
|
|
||||||
return (chunkx - chunky, chunkx + chunky)
|
|
||||||
elif self.north_direction == 'upper-right':
|
|
||||||
return (chunky - chunkx, chunkx + chunky)
|
|
||||||
|
|
||||||
def unconvert_coords(self, col, row):
|
def unconvert_coords(self, col, row):
|
||||||
"""Undoes what convert_coords does. Returns (chunkx, chunky)."""
|
"""Undoes what convert_coords does. Returns (chunkx, chunky)."""
|
||||||
|
|
||||||
if self.north_direction == 'lower-left':
|
return ((col - row) / 2, (row + col) / 2)
|
||||||
return ((col - row) / 2, (row + col) / 2)
|
|
||||||
if self.north_direction == 'lower-right':
|
|
||||||
return ((col + row) / 2, (col - row) / 2)
|
|
||||||
if self.north_direction == 'upper-left':
|
|
||||||
return ((col + row) / 2, (row - col) / 2)
|
|
||||||
if self.north_direction == 'upper-right':
|
|
||||||
return ((row - col) / 2, (col + row) / 2)
|
|
||||||
|
|
||||||
def findTrueSpawn(self):
|
def findTrueSpawn(self):
|
||||||
"""Adds the true spawn location to self.POI. The spawn Y coordinate
|
"""Adds the true spawn location to self.POI. The spawn Y coordinate
|
||||||
@@ -225,7 +211,10 @@ class World(object):
|
|||||||
chunkFile = self.get_region_path(chunkX, chunkY)
|
chunkFile = self.get_region_path(chunkX, chunkY)
|
||||||
|
|
||||||
if chunkFile is not None:
|
if chunkFile is not None:
|
||||||
data = nbt.load_from_region(chunkFile, chunkX, chunkY)[1]
|
#TODO I broke it
|
||||||
|
|
||||||
|
#data = nbt.load_from_region(chunkFile, chunkX, chunkY, self.north_direction)[1]
|
||||||
|
data = None
|
||||||
if data is not None:
|
if data is not None:
|
||||||
level = data['Level']
|
level = data['Level']
|
||||||
blockArray = numpy.frombuffer(level['Blocks'], dtype=numpy.uint8).reshape((16,16,128))
|
blockArray = numpy.frombuffer(level['Blocks'], dtype=numpy.uint8).reshape((16,16,128))
|
||||||
|
|||||||
Reference in New Issue
Block a user