175 lines
5.9 KiB
Python
175 lines
5.9 KiB
Python
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()
|