Merge remote branch 'origin/master' into topic/regression_testing
This commit is contained in:
commit
af7e286c7e
37
materials.py
37
materials.py
@ -130,35 +130,8 @@ classicMaterials.blockTextures = [
|
|||||||
classicMaterials.names = [name for (faces, name) in classicMaterials.blockTextures]
|
classicMaterials.names = [name for (faces, name) in classicMaterials.blockTextures]
|
||||||
|
|
||||||
|
|
||||||
classicMaterials.lightAbsorption = [15]*256;
|
classicMaterials.lightEmission = zeros( (256,) );
|
||||||
bn = classicMaterials.materialNamed
|
|
||||||
la = classicMaterials.lightAbsorption
|
|
||||||
la[0] = 0;
|
|
||||||
la[bn("Glass")] = 0
|
|
||||||
la[bn("Leaves")] = 1
|
|
||||||
la[bn("Water")] = 3
|
|
||||||
la[bn("Stationary water")] = 3
|
|
||||||
|
|
||||||
classicMaterials.lightEmission = [0] * 256;
|
|
||||||
|
|
||||||
classicMaterials.transparentBlocks = {
|
|
||||||
0:0, #air
|
|
||||||
6:0, #sapling
|
|
||||||
8:3, #water
|
|
||||||
9:3, #stat. water
|
|
||||||
10:0, #lava
|
|
||||||
11:0, #stat. lava
|
|
||||||
18:1, #leaves
|
|
||||||
20:0, #glass
|
|
||||||
37:0, #flower
|
|
||||||
38:0, #rose
|
|
||||||
39:0, #brown shroom
|
|
||||||
40:0, #red shroom
|
|
||||||
50:0, #torch
|
|
||||||
52:3, #water spring
|
|
||||||
53:0, #lava spring
|
|
||||||
59:0, #crops
|
|
||||||
};
|
|
||||||
|
|
||||||
materials = MCMaterials();
|
materials = MCMaterials();
|
||||||
materials.blockTextures = [
|
materials.blockTextures = [
|
||||||
@ -382,12 +355,7 @@ for i in materials.transparentBlocks:
|
|||||||
la[i] = materials.transparentBlocks[i];
|
la[i] = materials.transparentBlocks[i];
|
||||||
materials.transparentBlocks = materials.lightAbsorption < 15
|
materials.transparentBlocks = materials.lightAbsorption < 15
|
||||||
classicMaterials.transparentBlocks = materials.transparentBlocks
|
classicMaterials.transparentBlocks = materials.transparentBlocks
|
||||||
|
classicMaterials.lightAbsorption = materials.lightAbsorption
|
||||||
#la[bn("Glass")] = 0
|
|
||||||
#la[bn("Leaves")] = 1
|
|
||||||
#la[bn("Water")] = 3
|
|
||||||
#la[bn("Stationary water")] = 3
|
|
||||||
#la[bn("Ice")] = 3
|
|
||||||
|
|
||||||
|
|
||||||
materials.lightEmission = zeros(256, uint8)
|
materials.lightEmission = zeros(256, uint8)
|
||||||
@ -401,6 +369,7 @@ le[bn("Redstone Torch (on)")] = 7
|
|||||||
le[bn("Redstone Ore (glowing)")] = 9
|
le[bn("Redstone Ore (glowing)")] = 9
|
||||||
le[bn("Brown mushroom")] = 1
|
le[bn("Brown mushroom")] = 1
|
||||||
|
|
||||||
|
classicMaterials.lightEmission = materials.lightEmission
|
||||||
|
|
||||||
|
|
||||||
namedMaterials = {
|
namedMaterials = {
|
||||||
|
4
mce.py
4
mce.py
@ -315,9 +315,7 @@ class mce(object):
|
|||||||
"""
|
"""
|
||||||
blockCounts = zeros( (256,), 'uint64')
|
blockCounts = zeros( (256,), 'uint64')
|
||||||
|
|
||||||
i=0;
|
for i, cPos in enumerate(self.level.presentChunks, 1):
|
||||||
for cPos in self.level.presentChunks:
|
|
||||||
i += 1;
|
|
||||||
ch = self.level.getChunk(*cPos);
|
ch = self.level.getChunk(*cPos);
|
||||||
counts = bincount(ch.Blocks.ravel())
|
counts = bincount(ch.Blocks.ravel())
|
||||||
blockCounts[:counts.shape[0]] += counts
|
blockCounts[:counts.shape[0]] += counts
|
||||||
|
92
mclevel.py
92
mclevel.py
@ -368,7 +368,7 @@ class MCLevel:
|
|||||||
pass;
|
pass;
|
||||||
|
|
||||||
def getPresentChunks(self):
|
def getPresentChunks(self):
|
||||||
return itertools.product(xrange(0, self.Width>>4), xrange(0, self.Length>>4))
|
return itertools.product(xrange(0, self.Width+15>>4), xrange(0, self.Length+15>>4))
|
||||||
presentChunks = property(getPresentChunks)
|
presentChunks = property(getPresentChunks)
|
||||||
|
|
||||||
def getChunk(self, cx, cz):
|
def getChunk(self, cx, cz):
|
||||||
@ -378,8 +378,13 @@ class MCLevel:
|
|||||||
class FakeChunk:
|
class FakeChunk:
|
||||||
def load(self):pass
|
def load(self):pass
|
||||||
def compress(self):pass
|
def compress(self):pass
|
||||||
|
def __init__(self):pass
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
f = FakeChunk()
|
f = FakeChunk()
|
||||||
|
f.world = self;
|
||||||
|
|
||||||
f.Blocks = self.blocksForChunk(cx, cz)
|
f.Blocks = self.blocksForChunk(cx, cz)
|
||||||
|
|
||||||
whiteLight = zeros_like(f.Blocks);
|
whiteLight = zeros_like(f.Blocks);
|
||||||
@ -387,6 +392,7 @@ class MCLevel:
|
|||||||
|
|
||||||
f.BlockLight = whiteLight
|
f.BlockLight = whiteLight
|
||||||
f.SkyLight = whiteLight
|
f.SkyLight = whiteLight
|
||||||
|
|
||||||
f.root_tag = TAG_Compound();
|
f.root_tag = TAG_Compound();
|
||||||
|
|
||||||
return f
|
return f
|
||||||
@ -1025,8 +1031,12 @@ class MCSchematic (MCLevel):
|
|||||||
info( "Relocating entities..." )
|
info( "Relocating entities..." )
|
||||||
for entity in self.Entities:
|
for entity in self.Entities:
|
||||||
for p in "Pos", "Motion":
|
for p in "Pos", "Motion":
|
||||||
|
if p == "Pos":
|
||||||
|
zBase = self.Length
|
||||||
|
else:
|
||||||
|
zBase = 0.0;
|
||||||
newX = entity[p][2].value
|
newX = entity[p][2].value
|
||||||
newZ = self.Length - entity[p][0].value - 1.0
|
newZ = zBase - entity[p][0].value
|
||||||
|
|
||||||
entity[p][0].value = newX
|
entity[p][0].value = newX
|
||||||
entity[p][2].value = newZ
|
entity[p][2].value = newZ
|
||||||
@ -1184,10 +1194,10 @@ class ZeroChunk:
|
|||||||
def load(self): pass
|
def load(self): pass
|
||||||
def __init__(self, height=512):
|
def __init__(self, height=512):
|
||||||
zeroChunk = zeros((16,16,height), uint8)
|
zeroChunk = zeros((16,16,height), uint8)
|
||||||
|
whiteLight = zeroChunk + 15;
|
||||||
self.Blocks = zeroChunk
|
self.Blocks = zeroChunk
|
||||||
self.BlockLight = zeroChunk
|
self.BlockLight = whiteLight
|
||||||
self.SkyLight = zeroChunk
|
self.SkyLight = whiteLight
|
||||||
self.Data = zeroChunk
|
self.Data = zeroChunk
|
||||||
HeightMap = zeros((16,16),uint8)
|
HeightMap = zeros((16,16),uint8)
|
||||||
|
|
||||||
@ -1346,7 +1356,7 @@ class InfdevChunk(MCLevel):
|
|||||||
|
|
||||||
self.dirty = True;
|
self.dirty = True;
|
||||||
self.needsLighting = calcLighting or self.needsLighting;
|
self.needsLighting = calcLighting or self.needsLighting;
|
||||||
self.generateHeightMap();
|
generateHeightMap(self);
|
||||||
if calcLighting:
|
if calcLighting:
|
||||||
self.genFastLights()
|
self.genFastLights()
|
||||||
|
|
||||||
@ -1364,39 +1374,14 @@ class InfdevChunk(MCLevel):
|
|||||||
|
|
||||||
self.SkyLight[x,z,self.HeightMap[z,x]:128] = 15
|
self.SkyLight[x,z,self.HeightMap[z,x]:128] = 15
|
||||||
lv = 15;
|
lv = 15;
|
||||||
for y in xrange(self.HeightMap[z,x]).__reversed__():
|
for y in reversed(xrange(self.HeightMap[z,x])):
|
||||||
lv -= max(la[self.Blocks[x,z,y]], 1)
|
lv -= max(la[self.Blocks[x,z,y]], 1)
|
||||||
|
|
||||||
if lv <= 0:
|
if lv <= 0:
|
||||||
break;
|
break;
|
||||||
self.SkyLight[x,z,y] = lv;
|
self.SkyLight[x,z,y] = lv;
|
||||||
|
|
||||||
def generateHeightMap(self):
|
|
||||||
if None is self.root_tag: self.load();
|
|
||||||
|
|
||||||
blocks = self.Blocks
|
|
||||||
heightMap = self.HeightMap
|
|
||||||
heightMap[:] = 0;
|
|
||||||
|
|
||||||
lightAbsorption = self.world.materials.lightAbsorption[blocks]
|
|
||||||
axes = lightAbsorption.nonzero()
|
|
||||||
heightMap[axes[1],axes[0]] = axes[2]; #assumes the y-indices come out in increasing order
|
|
||||||
heightMap += 1;
|
|
||||||
"""
|
|
||||||
for (x,z) in itertools.product(range(16), range(16)):
|
|
||||||
lv = 15;
|
|
||||||
for y in range(self.world.Height).__reversed__():
|
|
||||||
la = lightAbsorption[blocks[x,z,y]]
|
|
||||||
#if la == 15:
|
|
||||||
if la: #xxxx work on heightmap
|
|
||||||
#again, reversed heightmap indices.
|
|
||||||
#we actually need y+1 here - at least that's how it is in game-genned levels.
|
|
||||||
heightMap[z,x] = y+1;
|
|
||||||
break;
|
|
||||||
lv -= la;
|
|
||||||
if lv<=0:
|
|
||||||
heightMap[z,x] = y+1;
|
|
||||||
break; """
|
|
||||||
|
|
||||||
def unpackChunkData(self):
|
def unpackChunkData(self):
|
||||||
""" for internal use. call getChunk and compressChunk to load, compress, and unpack chunks automatically """
|
""" for internal use. call getChunk and compressChunk to load, compress, and unpack chunks automatically """
|
||||||
@ -1478,6 +1463,17 @@ class InfdevChunk(MCLevel):
|
|||||||
return self.root_tag[Level][TileEntities]
|
return self.root_tag[Level][TileEntities]
|
||||||
TileEntities = property(getTileEntities);
|
TileEntities = property(getTileEntities);
|
||||||
|
|
||||||
|
def generateHeightMap(self):
|
||||||
|
if None is self.root_tag: self.load();
|
||||||
|
|
||||||
|
blocks = self.Blocks
|
||||||
|
heightMap = self.HeightMap
|
||||||
|
heightMap[:] = 0;
|
||||||
|
|
||||||
|
lightAbsorption = self.world.materials.lightAbsorption[blocks]
|
||||||
|
axes = lightAbsorption.nonzero()
|
||||||
|
heightMap[axes[1],axes[0]] = axes[2]; #assumes the y-indices come out in increasing order
|
||||||
|
heightMap += 1;
|
||||||
|
|
||||||
class MCInfdevOldLevel(MCLevel):
|
class MCInfdevOldLevel(MCLevel):
|
||||||
materials = materials;
|
materials = materials;
|
||||||
@ -1573,10 +1569,7 @@ class MCInfdevOldLevel(MCLevel):
|
|||||||
|
|
||||||
playerFilePath = os.path.join(self.worldDir, "players")
|
playerFilePath = os.path.join(self.worldDir, "players")
|
||||||
if os.path.exists(playerFilePath):
|
if os.path.exists(playerFilePath):
|
||||||
playerDats = os.listdir(playerFilePath);
|
self.players = [x[:-4] for x in os.listdir(playerFilePath) if x.endswith(".dat")]
|
||||||
playerDats = filter(lambda x:x.endswith(".dat"), playerDats)
|
|
||||||
players = map(lambda x:x[:-4], playerDats);
|
|
||||||
self.players = players
|
|
||||||
|
|
||||||
self.preloadChunkPaths();
|
self.preloadChunkPaths();
|
||||||
|
|
||||||
@ -1635,23 +1628,7 @@ class MCInfdevOldLevel(MCLevel):
|
|||||||
|
|
||||||
base36alphabet = "0123456789abcdefghijklmnopqrstuvwxyz"
|
base36alphabet = "0123456789abcdefghijklmnopqrstuvwxyz"
|
||||||
def decbase36(self, s):
|
def decbase36(self, s):
|
||||||
n = 0;
|
return int(s, 36)
|
||||||
neg = False;
|
|
||||||
s = s.lower();
|
|
||||||
|
|
||||||
if s[0] == '-':
|
|
||||||
neg = True;
|
|
||||||
s=s[1:];
|
|
||||||
|
|
||||||
while(len(s)):
|
|
||||||
if not s[0] in self.base36alphabet:
|
|
||||||
break;
|
|
||||||
n*=36
|
|
||||||
n+=self.base36alphabet.index(s[0])
|
|
||||||
s=s[1:];
|
|
||||||
|
|
||||||
if neg: return -n
|
|
||||||
return n;
|
|
||||||
|
|
||||||
def base36(self, n):
|
def base36(self, n):
|
||||||
n = int(n);
|
n = int(n);
|
||||||
@ -1979,7 +1956,10 @@ class MCInfdevOldLevel(MCLevel):
|
|||||||
we calculate all chunks one step before moving to the next step, to ensure all gaps at chunk edges are filled.
|
we calculate all chunks one step before moving to the next step, to ensure all gaps at chunk edges are filled.
|
||||||
we do an extra cycle because lights sent across edges may lag by one cycle.
|
we do an extra cycle because lights sent across edges may lag by one cycle.
|
||||||
"""
|
"""
|
||||||
dirtyChunks = sorted(set(newDirtyChunks), key=lambda x:x.chunkPosition)
|
newDirtyChunks = set(newDirtyChunks)
|
||||||
|
newDirtyChunks.discard(zeroChunk)
|
||||||
|
|
||||||
|
dirtyChunks = sorted(newDirtyChunks, key=lambda x:x.chunkPosition)
|
||||||
|
|
||||||
newDirtyChunks = list();
|
newDirtyChunks = list();
|
||||||
|
|
||||||
|
46
nbt.py
46
nbt.py
@ -49,9 +49,9 @@ class TAG_Value:
|
|||||||
def __init__(self, value=0, name=None, data=""):
|
def __init__(self, value=0, name=None, data=""):
|
||||||
self.name=name
|
self.name=name
|
||||||
if(data==""):
|
if(data==""):
|
||||||
self.value = self.dataType(value)
|
self.value = value
|
||||||
else:
|
else:
|
||||||
(self.value,) = struct.unpack(self.fmt, data[0:struct.calcsize(self.fmt)]);
|
(self.value,) = struct.unpack_from(self.fmt, data);
|
||||||
|
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
return "%s ( %s ) : %s" % (self.__class__, self.name, repr(self.value))
|
return "%s ( %s ) : %s" % (self.__class__, self.name, repr(self.value))
|
||||||
@ -152,7 +152,7 @@ class TAG_Byte_Array(TAG_Value):
|
|||||||
if(data==""):
|
if(data==""):
|
||||||
self.value = value;
|
self.value = value;
|
||||||
else:
|
else:
|
||||||
(string_len,) = struct.unpack(">i", data[0:4]);
|
(string_len,) = struct.unpack_from(">i", data);
|
||||||
self.value = fromstring(data[4:string_len+4], 'uint8');
|
self.value = fromstring(data[4:string_len+4], 'uint8');
|
||||||
|
|
||||||
def nbt_length(self) :
|
def nbt_length(self) :
|
||||||
@ -177,7 +177,7 @@ class TAG_String(TAG_Value):
|
|||||||
if(data==""):
|
if(data==""):
|
||||||
self.value = value;
|
self.value = value;
|
||||||
else:
|
else:
|
||||||
(string_len,) = struct.unpack(">h", data[0:2]);
|
(string_len,) = struct.unpack_from(">h", data);
|
||||||
self.value = data[2:string_len+2].tostring();
|
self.value = data[2:string_len+2].tostring();
|
||||||
|
|
||||||
def nbt_length(self) :
|
def nbt_length(self) :
|
||||||
@ -196,14 +196,14 @@ class TAG_Compound(TAG_Value, collections.MutableMapping):
|
|||||||
|
|
||||||
tag = 10;
|
tag = 10;
|
||||||
|
|
||||||
def setValue(self, val):
|
def dataType(self, val):
|
||||||
for i in val:
|
for i in val:
|
||||||
assert isinstance(val, TAG_Value)
|
assert isinstance(val, TAG_Value)
|
||||||
assert val.name
|
assert val.name
|
||||||
list = list(val)
|
return list(val)
|
||||||
|
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
return "%s( %s ): %s" % (str(self.__class__), self.name, self.list)
|
return "%s( %s ): %s" % (str(self.__class__), self.name, self.value)
|
||||||
|
|
||||||
def __init__(self, value=[], name="",data=""):
|
def __init__(self, value=[], name="",data=""):
|
||||||
|
|
||||||
@ -211,9 +211,9 @@ class TAG_Compound(TAG_Value, collections.MutableMapping):
|
|||||||
if value.__class__ == ''.__class__:
|
if value.__class__ == ''.__class__:
|
||||||
self.name = value;
|
self.name = value;
|
||||||
value = [];
|
value = [];
|
||||||
self.list = []
|
self.value = []
|
||||||
if(data == ""):
|
if(data == ""):
|
||||||
self.list += value;
|
self.value += value;
|
||||||
else:
|
else:
|
||||||
|
|
||||||
data_cursor = 0;
|
data_cursor = 0;
|
||||||
@ -234,39 +234,39 @@ class TAG_Compound(TAG_Value, collections.MutableMapping):
|
|||||||
tag = tag_handlers[tag_type]( data=data[data_cursor:], name=tag_name )
|
tag = tag_handlers[tag_type]( data=data[data_cursor:], name=tag_name )
|
||||||
|
|
||||||
data_cursor += tag.nbt_length()
|
data_cursor += tag.nbt_length()
|
||||||
self.list.append(tag);
|
self.value.append(tag);
|
||||||
|
|
||||||
|
|
||||||
def nbt_length(self):
|
def nbt_length(self):
|
||||||
return sum(map(lambda x:(x.nbt_length()+len(x.name)+3), self.list))+1;
|
return sum(x.nbt_length() + len(x.name) + 3 for x in self.value) + 1;
|
||||||
|
|
||||||
def write_value(self, buf):
|
def write_value(self, buf):
|
||||||
for i in self.list:
|
for i in self.value:
|
||||||
i.save(buf=buf)
|
i.save(buf=buf)
|
||||||
buf.write("\x00")
|
buf.write("\x00")
|
||||||
|
|
||||||
"collection functions"
|
"collection functions"
|
||||||
def __getitem__(self, k):
|
def __getitem__(self, k):
|
||||||
#hits=filter(lambda x:x.name==k, self.list);
|
#hits=filter(lambda x:x.name==k, self.value);
|
||||||
#if(len(hits)): return hits[0];
|
#if(len(hits)): return hits[0];
|
||||||
for key in self.list:
|
for key in self.value:
|
||||||
if key.name == k: return key
|
if key.name == k: return key
|
||||||
raise KeyError("Key {0} not found".format(k));
|
raise KeyError("Key {0} not found".format(k));
|
||||||
|
|
||||||
def __iter__(self): return itertools.imap(lambda x:x.name, self.list);
|
def __iter__(self): return itertools.imap(lambda x:x.name, self.value);
|
||||||
def __contains__(self, k):return k in map(lambda x:x.name, self.list);
|
def __contains__(self, k):return k in map(lambda x:x.name, self.value);
|
||||||
def __len__(self): return self.list.__len__()
|
def __len__(self): return self.value.__len__()
|
||||||
|
|
||||||
|
|
||||||
def __setitem__(self, k, v):
|
def __setitem__(self, k, v):
|
||||||
if not (v.__class__ in tag_handlers.values()): raise TypeError("Invalid type %s for TAG_Compound" % (v.__class__))
|
if not (v.__class__ in tag_handlers.values()): raise TypeError("Invalid type %s for TAG_Compound" % (v.__class__))
|
||||||
"""remove any items already named "k". """
|
"""remove any items already named "k". """
|
||||||
olditems = filter(lambda x:x.name==k, self.list)
|
olditems = filter(lambda x:x.name==k, self.value)
|
||||||
for i in olditems: self.list.remove(i)
|
for i in olditems: self.value.remove(i)
|
||||||
self.list.append(v);
|
self.value.append(v);
|
||||||
v.name=k;
|
v.name=k;
|
||||||
|
|
||||||
def __delitem__(self, k): self.list.__delitem__(self.list.index(self[k]));
|
def __delitem__(self, k): self.value.__delitem__(self.value.index(self[k]));
|
||||||
|
|
||||||
def add(self, v):
|
def add(self, v):
|
||||||
self[v.name] = v;
|
self[v.name] = v;
|
||||||
@ -352,7 +352,7 @@ class TAG_List(TAG_Value, collections.MutableSequence):
|
|||||||
self.list.insert(i, v);
|
self.list.insert(i, v);
|
||||||
|
|
||||||
def nbt_length(self):
|
def nbt_length(self):
|
||||||
return 5 + sum(map(lambda x:x.nbt_length(), self.list));
|
return 5 + sum(x.nbt_length() for x in self.list)
|
||||||
|
|
||||||
def write_value(self, buf):
|
def write_value(self, buf):
|
||||||
buf.write(struct.pack(TAGfmt, self.list_type))
|
buf.write(struct.pack(TAGfmt, self.list_type))
|
||||||
@ -376,7 +376,7 @@ tag_handlers = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
def assert_type(t, offset) :
|
def assert_type(t, offset) :
|
||||||
if not t in tag_handlers.keys(): raise TypeError("Unexpected type %d at %d" % (t, offset));
|
if not t in tag_handlers: raise TypeError("Unexpected type %d at %d" % (t, offset));
|
||||||
|
|
||||||
def loadFile(filename):
|
def loadFile(filename):
|
||||||
#sio = StringIO.StringIO();
|
#sio = StringIO.StringIO();
|
||||||
|
Reference in New Issue
Block a user