0

Initial work on generating markers.js from signposts

Details:
 * A queue object is passed to all renderers, allowing each process to
   avoid using shared memory when recording signpost data.
 * New overviewer.dat file that stores persistent data between runs.
   Currently used to store information on signs.  markers.js is
   generated by merging the stored POI list with the newly generated POI
   list.
 * POIs are tagged with their type (e.g. "spawn" or "sign").  This
   should be useful if different types of POIs needs to be
   handled/displayed differently

Known bugs:
 * If you delete the last sign in a chunk, it won't be removed from
   markers.js
This commit is contained in:
Andrew Chin
2010-10-20 22:11:34 -04:00
parent 32ba6c4424
commit cb363df3cd
3 changed files with 105 additions and 9 deletions

View File

@@ -81,6 +81,11 @@ def get_blockdata_array(level):
in a similar manner to skylight data"""
return numpy.frombuffer(level['Data'], dtype=numpy.uint8).reshape((16,16,64))
def get_tileentity_data(level):
"""Returns the TileEntities TAG_List from chunk dat file"""
data = level['TileEntities']
return data
def iterate_chunkblocks(xoff,yoff):
"""Iterates over the 16x16x128 blocks of a chunk in rendering order.
Yields (x,y,z,imgx,imgy)
@@ -100,12 +105,12 @@ def iterate_chunkblocks(xoff,yoff):
transparent_blocks = set([0, 6, 8, 9, 18, 20, 37, 38, 39, 40, 44, 50, 51, 52, 53,
59, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 74, 75, 76, 77, 78, 79, 81, 83, 85])
def render_and_save(chunkfile, cachedir, worldobj, cave=False):
def render_and_save(chunkfile, cachedir, worldobj, cave=False, queue=None):
"""Used as the entry point for the multiprocessing workers (since processes
can't target bound methods) or to easily render and save one chunk
Returns the image file location"""
a = ChunkRenderer(chunkfile, cachedir, worldobj)
a = ChunkRenderer(chunkfile, cachedir, worldobj, queue)
try:
return a.render_and_save(cave)
except ChunkCorrupt:
@@ -128,21 +133,29 @@ class ChunkCorrupt(Exception):
pass
class ChunkRenderer(object):
def __init__(self, chunkfile, cachedir, worldobj):
def __init__(self, chunkfile, cachedir, worldobj, queue):
"""Make a new chunk renderer for the given chunkfile.
chunkfile should be a full path to the .dat file to process
cachedir is a directory to save the resulting chunk images to
"""
self.queue = queue
if not os.path.exists(chunkfile):
raise ValueError("Could not find chunkfile")
self.chunkfile = chunkfile
destdir, filename = os.path.split(self.chunkfile)
filename_split = filename.split(".")
chunkcoords = filename_split[1:3]
chunkcoords = filename.split(".")[1:3]
self.coords = map(world.base36decode, chunkcoords)
self.blockid = ".".join(chunkcoords)
self.world = worldobj
# chunk coordinates (useful to converting local block coords to
# global block coords)
self.chunkX = int(filename_split[1], base=36)
self.chunkY = int(filename_split[2], base=36)
self.world = worldobj
# Cachedir here is the base directory of the caches. We need to go 2
# levels deeper according to the chunk file. Get the last 2 components
# of destdir and use that
@@ -293,7 +306,7 @@ class ChunkRenderer(object):
is up to date, this method doesn't render anything.
"""
blockid = self.blockid
oldimg, oldimg_path = self.find_oldimage(cave)
if oldimg:
@@ -474,6 +487,8 @@ class ChunkRenderer(object):
# Odd elements get the upper 4 bits
blockData_expanded[:,:,1::2] = blockData >> 4
tileEntities = get_tileentity_data(self.level)
# Each block is 24x24
# The next block on the X axis adds 12px to x and subtracts 6px from y in the image
@@ -504,6 +519,33 @@ class ChunkRenderer(object):
else:
t = textures.blockmap[blockid]
# see if we want to do anything else with this chunk
if blockid in (63, 68): # signs
# find the sign text from the TileEntities list
print "Found a sign!"
for entity in tileEntities:
if entity['id'] == 'Sign':
print "adding to POI list"
# TODO assert that the x,y,z of this entity matches
# the x,y,z of this block
# convert the blockID coordinates from local chunk
# coordinates to global world coordinates
newPOI = dict(type="sign",
x= x+(self.chunkX*16),
y= z,
z= y+(self.chunkY*16),
msg="%s\n%s\n%s\n%s" %
(entity['Text1'], entity['Text2'], entity['Text3'], entity['Text4']),
chunk= (self.chunkX, self.chunkY),
)
print "new POI: %s" % newPOI
self.queue.put(["newpoi", newPOI])
break
if not t:
continue