This repository has been archived on 2024-06-13. You can view files and clone it, but cannot push or open issues or pull requests.
pymclevel/test/anvil_test.py

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()