refactor some entity code out to entity.py

This commit is contained in:
David Vierra 2011-07-24 14:23:27 -10:00
parent 6e7c6f0ab3
commit b664a2bf73
5 changed files with 112 additions and 84 deletions

View File

@ -7,7 +7,22 @@ from mclevelbase import *
__all__ = "Entity, TileEntity".split(", ")
EntityId = "EntityId"
id = "id"
Motion = "Motion"
Pos = "Pos"
Rotation = "Rotation"
class TileEntity(object):
knownIDs = "Furnace, Sign, MonsterSpawner, Chest, Music, Trap, RecordPlayer".split(", ")
@classmethod
def Create(cls, tileEntityID, **kw):
tileEntityTag = TAG_Compound()
tileEntityTag[id] = TAG_String(tileEntityID)
cls.setpos(tileEntityTag, (0, 0, 0))
return tileEntityTag
@classmethod
def pos(cls, tag):
return [tag[a].value for a in 'xyz']
@ -17,12 +32,28 @@ class TileEntity(object):
for a, p in zip('xyz', pos):
tag[a] = TAG_Int(p)
@classmethod
def copyWithOffset(cls, tileEntity, copyOffset):
eTag = deepcopy(tileEntity)
eTag['x'] = TAG_Int(tileEntity['x'].value + copyOffset[0])
eTag['y'] = TAG_Int(tileEntity['y'].value + copyOffset[1])
eTag['z'] = TAG_Int(tileEntity['z'].value + copyOffset[2])
return eTag
class Entity(object):
@classmethod
def Create(cls, entityID, **kw):
entityTag = TAG_Compound()
entityTag[EntityId] = TAG_String(entityID)
entityTag[Pos] = [TAG_Int(0) for i in range(3)]
return entityTag
@classmethod
def pos(cls, tag):
if "Pos" not in tag:
print tag
return [a.value for a in tag["Pos"]]
if Pos not in tag:
raise InvalidEntity, tag
return [a.value for a in tag[Pos]]
@classmethod
def setpos(cls, tag, pos):
@ -41,3 +72,6 @@ class Entity(object):
eTag["TileZ"].value += copyOffset[2]
return eTag
class InvalidEntity(ValueError): pass
class InvalidTileEntity(ValueError): pass

View File

@ -1896,22 +1896,21 @@ class MCInfdevOldLevel(MCLevel):
entities = [];
if chunk.Entities is None: return entities;
for entity in chunk.Entities:
if map(lambda x:int(x.value), entity[Pos]) == [x, y, z]:
if map(lambda x:int(floor(x)), Entity.pos(entity)) == [x, y, z]:
entities.append(entity);
return entities;
def addEntity(self, entity):
assert isinstance(entity, TAG_Compound)
x = int(entity[Pos][0].value)
z = int(entity[Pos][2].value)
def addEntity(self, entityTag):
assert isinstance(entityTag, TAG_Compound)
x, y, z = map(lambda x:int(floor(x)), Entity.pos(entityTag))
try:
chunk = self.getChunk(x >> 4, z >> 4)
except (ChunkNotPresent, ChunkMalformed), e:
return None
# raise Error, can't find a chunk?
chunk.Entities.append(entity);
chunk.Entities.append(entityTag);
chunk.dirty = True
def tileEntityAt(self, x, y, z):
@ -1931,13 +1930,10 @@ class MCInfdevOldLevel(MCLevel):
return entities[0];
def addTileEntity(self, entity):
assert isinstance(entity, TAG_Compound)
if not 'x' in entity: return
x = int(entity['x'].value)
y = int(entity['y'].value)
z = int(entity['z'].value)
def addTileEntity(self, tileEntityTag):
assert isinstance(tileEntityTag, TAG_Compound)
if not 'x' in tileEntityTag: return
x, y, z = TileEntity.pos(tileEntityTag)
try:
chunk = self.getChunk(x >> 4, z >> 4)
@ -1945,11 +1941,11 @@ class MCInfdevOldLevel(MCLevel):
return
# raise Error, can't find a chunk?
def differentPosition(a):
return not ((entity is a) or ('x' in a and (a['x'].value == x and a['y'].value == y and a['z'].value == z)))
return not ((tileEntityTag is a) or ('x' in a and (a['x'].value == x and a['y'].value == y and a['z'].value == z)))
chunk.TileEntities.value[:] = filter(differentPosition, chunk.TileEntities);
chunk.TileEntities.append(entity);
chunk.TileEntities.append(tileEntityTag);
chunk.dirty = True
def removeEntitiesInBox(self, box):

View File

@ -569,16 +569,6 @@ class MCLevel(object):
def playerOrientation(self, player="Player"):
return (-45., 0.)
def copyEntityWithOffset(self, entity, copyOffset):
return Entity.copyWithOffset(entity, copyOffset)
def copyTileEntityWithOffset(self, tileEntity, copyOffset):
eTag = deepcopy(tileEntity)
eTag['x'] = TAG_Int(tileEntity['x'].value + copyOffset[0])
eTag['y'] = TAG_Int(tileEntity['y'].value + copyOffset[1])
eTag['z'] = TAG_Int(tileEntity['z'].value + copyOffset[2])
return eTag
def copyEntitiesFromInfinite(self, sourceLevel, sourceBox, destinationPoint):
chunkIterator = sourceLevel.getChunkSlices(sourceBox);
@ -586,29 +576,24 @@ class MCLevel(object):
for (chunk, slices, point) in chunkIterator:
#remember, slices are ordered x,z,y so you can subscript them like so: chunk.Blocks[slices]
cx, cz = chunk.chunkPosition
wx, wz = cx << 4, cz << 4
#wx, wz = cx << 4, cz << 4
copyOffset = map(lambda x, y:x - y, destinationPoint, sourceBox.origin)
for entity in chunk.Entities:
x, y, z = map(lambda x:x.value, entity[Pos])
for entityTag in chunk.Entities:
x, y, z = Entity.pos(entityTag)
if (x, y, z) not in sourceBox: continue
if x - wx < slices[0].start or x - wx >= slices[0].stop: continue
if y < slices[2].start or y >= slices[2].stop: continue
if z - wz < slices[1].start or z - wz >= slices[1].stop: continue
eTag = self.copyEntityWithOffset(entity, copyOffset)
eTag = Entity.copyWithOffset(entityTag, copyOffset)
self.addEntity(eTag);
for tileEntity in chunk.TileEntities:
if not 'x' in tileEntity: continue
for tileEntityTag in chunk.TileEntities:
if not 'x' in tileEntityTag: continue
x, y, z = tileEntity['x'].value, tileEntity['y'].value, tileEntity['z'].value
if x - wx < slices[0].start or x - wx >= slices[0].stop: continue
if y < slices[2].start or y >= slices[2].stop: continue
if z - wz < slices[1].start or z - wz >= slices[1].stop: continue
x, y, z = TileEntity.pos(tileEntityTag)
if (x, y, z) not in sourceBox: continue
eTag = self.copyTileEntityWithOffset(tileEntity, copyOffset)
eTag = TileEntity.copyWithOffset(tileEntityTag, copyOffset)
self.addTileEntity(eTag)
@ -628,7 +613,7 @@ class MCLevel(object):
tileEntsCopied = 0;
copyOffset = map(lambda x, y:x - y, destinationPoint, sourcePoint0)
for entity in getEntitiesInRange(sourceBox, sourceLevel.Entities):
eTag = self.copyEntityWithOffset(entity, copyOffset)
eTag = Entity.copyWithOffset(entity, copyOffset)
self.addEntity(eTag)
entsCopied += 1;
@ -636,13 +621,8 @@ class MCLevel(object):
for entity in getTileEntitiesInRange(sourceBox, sourceLevel.TileEntities):
if not 'x' in entity: continue
eTag = TileEntity.copyWithOffset(entity, copyOffset)
x, y, z = entity['x'].value, entity['y'].value, entity['z'].value
eTag = deepcopy(entity)
eTag['x'] = TAG_Int(x + copyOffset[0])
eTag['y'] = TAG_Int(y + copyOffset[1])
eTag['z'] = TAG_Int(z + copyOffset[2])
try:
self.addTileEntity(eTag)
tileEntsCopied += 1;

View File

@ -41,12 +41,9 @@ Height = "Height"
Length = "Length"
Blocks = "Blocks"
Data = "Data"
Inventory = 'Inventory'
#entities
Inventory = 'Inventory'
Motion = "Motion"
Pos = "Pos"
Rotation = "Rotation"
def decompress_first(func):
def dec_first(self, *args, **kw):

View File

@ -3,9 +3,10 @@ Created on Jul 23, 2011
@author: Rio
'''
from mclevel import fromFile, loadWorldNumber, BoundingBox
from infiniteworld import MCInfdevOldLevel
from schematic import MCSchematic
#from mclevel import fromFile, loadWorldNumber, BoundingBox
#from infiniteworld import MCInfdevOldLevel
#from schematic import MCSchematic
from pymclevel import *
import itertools
import traceback
@ -54,6 +55,16 @@ class TestIndevLevel(unittest.TestCase):
self.srclevel = TempLevel("hell.mclevel")
self.indevlevel = TempLevel("hueg.mclevel")
def testEntities(self):
level = self.indevlevel.level
entityTag = Entity.Create("Zombie")
tileEntityTag = TileEntity.Create("Painting")
level.addEntity(entityTag)
level.addTileEntity(tileEntityTag)
schem = level.extractSchematic(level.bounds)
level.copyBlocksFrom(schem, schem.bounds, (0, 0, 0))
#raise Failure
def testCopy(self):
info("Indev level")
@ -96,19 +107,25 @@ class TestAlphaLevel(unittest.TestCase):
self.alphalevel = TempLevel("PyTestWorld")
def testAlphaLevels(self):
info("Alpha level")
def testCreateChunks(self):
indevlevel = self.indevlevel.level
level = self.alphalevel.level
for ch in list(level.allChunks): level.deleteChunk(*ch)
level.createChunksInBox(BoundingBox((0, 0, 0), (32, 0, 32)))
def testCopyConvertBlocks(self):
indevlevel = self.indevlevel.level
level = self.alphalevel.level
level.copyBlocksFrom(indevlevel, BoundingBox((0, 0, 0), (256, 128, 256)), (-0, 0, 0))
convertedSourceBlocks, convertedSourceData = indevlevel.convertBlocksFromLevel(level, indevlevel.Blocks[0:16, 0:16, 0:indevlevel.Height], indevlevel.Data[0:16, 0:16, 0:indevlevel.Height])
assert (level.getChunk(0, 0).Blocks[0:16, 0:16, 0:indevlevel.Height] == convertedSourceBlocks).all()
def testImportSchematic(self):
indevlevel = self.indevlevel.level
level = self.alphalevel.level
schem = fromFile("schematics\\CreativeInABox.schematic");
level.copyBlocksFrom(schem, BoundingBox((0, 0, 0), (1, 1, 3)), (0, 64, 0));
schem = MCSchematic(shape=(1, 1, 3))
@ -116,32 +133,37 @@ class TestAlphaLevel(unittest.TestCase):
convertedSourceBlocks, convertedSourceData = schem.convertBlocksFromLevel(level, schem.Blocks, schem.Data)
assert (level.getChunk(0, 0).Blocks[0:1, 0:3, 64:65] == convertedSourceBlocks).all()
try:
for x, z in itertools.product(xrange(-1, 3), xrange(-1, 2)):
level.deleteChunk(x, z);
level.createChunk(x, z)
except Exception, e:
traceback.print_exc();
print e;
level.fillBlocks(BoundingBox((-11, 0, -7), (38, 128, 25)) , indevlevel.materials.WoodPlanks);
def testRecreateChunks(self):
level = self.alphalevel.level
for x, z in itertools.product(xrange(-1, 3), xrange(-1, 2)):
level.deleteChunk(x, z);
level.createChunk(x, z)
def testFill(self):
level = self.alphalevel.level
level.fillBlocks(BoundingBox((-11, 0, -7), (38, 128, 25)) , level.materials.WoodPlanks);
c = level.getChunk(0, 0)
assert (c.Blocks == 5).all()
level.fillBlocks(BoundingBox((-11, 0, -7), (38, 128, 25)) , indevlevel.materials.WoodPlanks, [indevlevel.materials.Dirt, indevlevel.materials.Grass]);
#print b.shape
#raise SystemExit
def testReplace(self):
level = self.alphalevel.level
level.fillBlocks(BoundingBox((-11, 0, -7), (38, 128, 25)) , level.materials.WoodPlanks, [level.materials.Dirt, level.materials.Grass]);
def testSaveRelight(self):
indevlevel = self.indevlevel.level
level = self.alphalevel.level
cx, cz = -3, -1;
try:
level.deleteChunk(cx, cz);
except KeyError:pass
level.deleteChunk(cx, cz);
level.createChunk(cx, cz);
level.copyBlocksFrom(indevlevel, BoundingBox((0, 0, 0), (64, 64, 64,)), (-96, 32, 0))
#blocks = zeros((16,16,128), 'uint8');
#blocks[:,:,:] = level.getChunk(cx, cz).Blocks[:,:,:]
#level.getChunk(cx, cz).Blocks[:,:,:] = blocks[:,:,:]
level.generateLights();
level.saveInPlace();
level.generateLights();
level.saveInPlace();
@ -157,11 +179,10 @@ class TestSchematics(unittest.TestCase):
schematic = MCSchematic(shape=size, filename="hell.schematic", mats='Classic');
level = self.indevlevel.level
schematic.rotateLeft();
try:
schematic.copyBlocksFrom(level, BoundingBox((-32, -32, -32), (64, 64, 64,)), (0, 0, 0))
except ValueError:
pass;
self.failUnlessRaises(ValueError, lambda:(
schematic.copyBlocksFrom(level, BoundingBox((-32, -32, -32), (64, 64, 64,)), (0, 0, 0))
))
schematic.copyBlocksFrom(level, BoundingBox((0, 0, 0), (64, 64, 64,)), (0, 0, 0))
assert((schematic.Blocks[0:64, 0:64, 0:64] == level.Blocks[0:64, 0:64, 0:64]).all())