import itertools import os import shutil import unittest import numpy from pymclevel import mclevel from pymclevel.infiniteworld import MCInfdevOldLevel from pymclevel import nbt from pymclevel.schematic import MCSchematic from pymclevel.box import BoundingBox from pymclevel import block_copy from templevel import mktemp, TempLevel __author__ = 'Rio' class TestAnvilLevelCreate(unittest.TestCase): def testCreate(self): temppath = mktemp("AnvilCreate") self.anvilLevel = MCInfdevOldLevel(filename=temppath, create=True) self.anvilLevel.close() shutil.rmtree(temppath) class TestAnvilLevel(unittest.TestCase): def setUp(self): self.indevLevel = TempLevel("hell.mclevel") self.anvilLevel = TempLevel("AnvilWorld") def testUnsetProperties(self): level = self.anvilLevel.level del level.root_tag['Data']['LastPlayed'] import time assert 0 != level.LastPlayed level.LastPlayed = time.time() * 1000 - 1000000 def testGetEntities(self): level = self.anvilLevel.level print len(level.getEntitiesInBox(level.bounds)) def testCreateChunks(self): level = self.anvilLevel.level for ch in list(level.allChunks): level.deleteChunk(*ch) level.createChunksInBox(BoundingBox((0, 0, 0), (32, 0, 32))) def testCopyChunks(self): level = self.anvilLevel.level temppath = mktemp("AnvilCreate") newLevel = MCInfdevOldLevel(filename=temppath, create=True) for cx, cz in level.allChunks: newLevel.copyChunkFrom(level, cx, cz) newLevel.close() shutil.rmtree(temppath) def testCopyConvertBlocks(self): indevlevel = self.indevLevel.level level = self.anvilLevel.level x, y, z = level.bounds.origin x += level.bounds.size[0]/2 & ~15 z += level.bounds.size[2]/2 & ~15 x -= indevlevel.Width / 2 z -= indevlevel.Height / 2 middle = (x, y, z) oldEntityCount = len(level.getEntitiesInBox(BoundingBox(middle, indevlevel.bounds.size))) level.copyBlocksFrom(indevlevel, indevlevel.bounds, middle) convertedSourceBlocks, convertedSourceData = block_copy.convertBlocks(indevlevel, level, indevlevel.Blocks[0:16, 0:16, 0:indevlevel.Height], indevlevel.Data[0:16, 0:16, 0:indevlevel.Height]) assert ((level.getChunk(x >> 4, z >> 4).Blocks[0:16, 0:16, 0:indevlevel.Height] == convertedSourceBlocks).all()) assert (oldEntityCount + len(indevlevel.getEntitiesInBox(indevlevel.bounds)) == len(level.getEntitiesInBox(BoundingBox(middle, indevlevel.bounds.size)))) def testImportSchematic(self): level = self.anvilLevel.level cx, cz = level.allChunks.next() schem = mclevel.fromFile("schematics/CreativeInABox.schematic") box = BoundingBox((cx * 16, 64, cz * 16), schem.bounds.size) level.copyBlocksFrom(schem, schem.bounds, (0, 64, 0)) schem = MCSchematic(shape=schem.bounds.size) schem.copyBlocksFrom(level, box, (0, 0, 0)) convertedSourceBlocks, convertedSourceData = block_copy.convertBlocks(schem, level, schem.Blocks, schem.Data) assert (level.getChunk(cx, cz).Blocks[0:1, 0:3, 64:65] == convertedSourceBlocks).all() def testRecreateChunks(self): level = self.anvilLevel.level for x, z in itertools.product(xrange(-1, 3), xrange(-1, 2)): level.deleteChunk(x, z) assert not level.containsChunk(x, z) level.createChunk(x, z) def testFill(self): level = self.anvilLevel.level cx, cz = level.allChunks.next() box = BoundingBox((cx * 16, 0, cz * 16), (32, level.Height, 32)) level.fillBlocks(box, level.materials.WoodPlanks) level.fillBlocks(box, level.materials.WoodPlanks, [level.materials.Stone]) level.saveInPlace() c = level.getChunk(cx, cz) assert (c.Blocks == 5).all() def testReplace(self): level = self.anvilLevel.level level.fillBlocks(BoundingBox((-11, 0, -7), (38, level.Height, 25)), level.materials.WoodPlanks, [level.materials.Dirt, level.materials.Grass]) def testSaveRelight(self): indevlevel = self.indevLevel.level level = self.anvilLevel.level cx, cz = -3, -1 level.deleteChunk(cx, cz) level.createChunk(cx, cz) level.copyBlocksFrom(indevlevel, BoundingBox((0, 0, 0), (32, 64, 32,)), level.bounds.origin) level.generateLights() level.saveInPlace() def testRecompress(self): level = self.anvilLevel.level cx, cz = level.allChunks.next() ch = level.getChunk(cx, cz) ch.dirty = True ch.Blocks[:] = 6 ch.Data[:] = 13 d = {} keys = 'Blocks Data SkyLight BlockLight'.split() for key in keys: d[key] = numpy.array(getattr(ch, key)) for i in range(5): level.saveInPlace() ch = level.getChunk(cx, cz) ch.dirty = True assert (ch.Data == 13).all() for key in keys: assert (d[key] == getattr(ch, key)).all() def testPlayerSpawn(self): level = self.anvilLevel.level level.setPlayerSpawnPosition((0, 64, 0), "Player") level.getPlayerPosition() assert len(level.players) != 0 def testBigEndianIntHeightMap(self): """ Test modifying, saving, and loading the new TAG_Int_Array heightmap added with the Anvil format. """ chunk = nbt.load("testfiles/AnvilChunk.dat") hm = chunk["Level"]["HeightMap"] hm.value[2] = 500 oldhm = numpy.array(hm.value) filename = mktemp("ChangedChunk") chunk.save(filename) changedChunk = nbt.load(filename) os.unlink(filename) eq = (changedChunk["Level"]["HeightMap"].value == oldhm) assert eq.all()