def _load_chunk_from_tag(self, chunk, tag): """ Load a chunk from a tag. We cannot instantiate chunks, ever, so pass it in from above. """ level = tag["Level"] # These fromstring() calls are designed to raise if there are any # issues, but still be speedy. # Loop through the sections and unpack anything that we find. for tag in level["Sections"].tags: index = tag["Y"].value section = Section() section.blocks = array("B") section.blocks.fromstring(tag["Blocks"].value) section.metadata = array("B", unpack_nibbles(tag["Data"].value)) section.skylight = array("B", unpack_nibbles(tag["SkyLight"].value)) chunk.sections[index] = section chunk.heightmap = array("B") chunk.heightmap.fromstring(level["HeightMap"].value) chunk.blocklight = array("B", unpack_nibbles(level["BlockLight"].value)) chunk.populated = bool(level["TerrainPopulated"]) if "Entities" in level: for tag in level["Entities"].tags: try: entity = self._load_entity_from_tag(tag) chunk.entities.add(entity) except KeyError: log.msg("Unknown entity %s" % tag["id"].value) log.msg("Tag for entity:") log.msg(tag.pretty_tree()) if "TileEntities" in level: for tag in level["TileEntities"].tags: try: tile = self._load_tile_from_tag(tag) chunk.tiles[tile.x, tile.y, tile.z] = tile except KeyError: log.msg("Unknown tile entity %s" % tag["id"].value) log.msg("Tag for tile:") log.msg(tag.pretty_tree()) chunk.dirty = not chunk.populated
def __init__(self, x, z): """ :param int x: X coordinate in chunk coords :param int z: Z coordinate in chunk coords :ivar array.array heightmap: Tracks the tallest block in each xz-column. :ivar bool all_damaged: Flag for forcing the entire chunk to be damaged. This is for efficiency; past a certain point, it is not efficient to batch block updates or track damage. Heavily damaged chunks have their damage represented as a complete resend of the entire chunk. """ self.x = int(x) self.z = int(z) self.heightmap = array("B", [0] * (16 * 16)) self.blocklight = array("B", [0] * (16 * 16 * CHUNK_HEIGHT)) self.sections = [Section() for i in range(16)] self.entities = set() self.tiles = {} self.damaged = set()
class TestSectionInternals(TestCase): def setUp(self): self.s = Section() def test_set_block(self): """ ``set_block`` correctly alters the internal array. """ self.s.set_block((0, 0, 0), 1) self.assertEqual(self.s.blocks[0], 1) def test_set_block_xyz_xzy(self): """ ``set_block`` swizzles into the internal array correctly. """ self.s.set_block((1, 0, 0), 1) self.s.set_block((0, 1, 0), 2) self.s.set_block((0, 0, 1), 3) self.assertEqual(self.s.blocks[1], 1) self.assertEqual(self.s.blocks[256], 2) self.assertEqual(self.s.blocks[16], 3)
def setUp(self): self.s = Section()