diff --git a/materials.py b/materials.py index 673ca8c..ed03321 100644 --- a/materials.py +++ b/materials.py @@ -130,35 +130,8 @@ classicMaterials.blockTextures = [ classicMaterials.names = [name for (faces, name) in classicMaterials.blockTextures] -classicMaterials.lightAbsorption = [15]*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 = zeros( (256,) ); -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.blockTextures = [ @@ -382,12 +355,7 @@ for i in materials.transparentBlocks: la[i] = materials.transparentBlocks[i]; materials.transparentBlocks = materials.lightAbsorption < 15 classicMaterials.transparentBlocks = materials.transparentBlocks - -#la[bn("Glass")] = 0 -#la[bn("Leaves")] = 1 -#la[bn("Water")] = 3 -#la[bn("Stationary water")] = 3 -#la[bn("Ice")] = 3 +classicMaterials.lightAbsorption = materials.lightAbsorption materials.lightEmission = zeros(256, uint8) @@ -401,6 +369,7 @@ le[bn("Redstone Torch (on)")] = 7 le[bn("Redstone Ore (glowing)")] = 9 le[bn("Brown mushroom")] = 1 +classicMaterials.lightEmission = materials.lightEmission namedMaterials = { diff --git a/mce.py b/mce.py index ea7e2d7..e8934d0 100755 --- a/mce.py +++ b/mce.py @@ -315,9 +315,7 @@ class mce(object): """ blockCounts = zeros( (256,), 'uint64') - i=0; - for cPos in self.level.presentChunks: - i += 1; + for i, cPos in enumerate(self.level.presentChunks, 1): ch = self.level.getChunk(*cPos); counts = bincount(ch.Blocks.ravel()) blockCounts[:counts.shape[0]] += counts diff --git a/mclevel.py b/mclevel.py index 98384a7..f0b0158 100644 --- a/mclevel.py +++ b/mclevel.py @@ -368,7 +368,7 @@ class MCLevel: pass; 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) def getChunk(self, cx, cz): @@ -378,8 +378,13 @@ class MCLevel: class FakeChunk: def load(self):pass def compress(self):pass - + def __init__(self):pass + + + f = FakeChunk() + f.world = self; + f.Blocks = self.blocksForChunk(cx, cz) whiteLight = zeros_like(f.Blocks); @@ -387,6 +392,7 @@ class MCLevel: f.BlockLight = whiteLight f.SkyLight = whiteLight + f.root_tag = TAG_Compound(); return f @@ -1025,8 +1031,12 @@ class MCSchematic (MCLevel): info( "Relocating entities..." ) for entity in self.Entities: for p in "Pos", "Motion": + if p == "Pos": + zBase = self.Length + else: + zBase = 0.0; 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][2].value = newZ @@ -1184,10 +1194,10 @@ class ZeroChunk: def load(self): pass def __init__(self, height=512): zeroChunk = zeros((16,16,height), uint8) - + whiteLight = zeroChunk + 15; self.Blocks = zeroChunk - self.BlockLight = zeroChunk - self.SkyLight = zeroChunk + self.BlockLight = whiteLight + self.SkyLight = whiteLight self.Data = zeroChunk HeightMap = zeros((16,16),uint8) @@ -1346,7 +1356,7 @@ class InfdevChunk(MCLevel): self.dirty = True; self.needsLighting = calcLighting or self.needsLighting; - self.generateHeightMap(); + generateHeightMap(self); if calcLighting: self.genFastLights() @@ -1364,39 +1374,14 @@ class InfdevChunk(MCLevel): self.SkyLight[x,z,self.HeightMap[z,x]:128] = 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) if lv <= 0: break; 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): """ 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] 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): materials = materials; @@ -1573,10 +1569,7 @@ class MCInfdevOldLevel(MCLevel): playerFilePath = os.path.join(self.worldDir, "players") if os.path.exists(playerFilePath): - playerDats = os.listdir(playerFilePath); - playerDats = filter(lambda x:x.endswith(".dat"), playerDats) - players = map(lambda x:x[:-4], playerDats); - self.players = players + self.players = [x[:-4] for x in os.listdir(playerFilePath) if x.endswith(".dat")] self.preloadChunkPaths(); @@ -1635,23 +1628,7 @@ class MCInfdevOldLevel(MCLevel): base36alphabet = "0123456789abcdefghijklmnopqrstuvwxyz" def decbase36(self, s): - n = 0; - 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; + return int(s, 36) def base36(self, 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 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(); diff --git a/nbt.py b/nbt.py index 8f09d56..455800b 100644 --- a/nbt.py +++ b/nbt.py @@ -49,9 +49,9 @@ class TAG_Value: def __init__(self, value=0, name=None, data=""): self.name=name if(data==""): - self.value = self.dataType(value) + self.value = value else: - (self.value,) = struct.unpack(self.fmt, data[0:struct.calcsize(self.fmt)]); + (self.value,) = struct.unpack_from(self.fmt, data); def __repr__(self): return "%s ( %s ) : %s" % (self.__class__, self.name, repr(self.value)) @@ -152,7 +152,7 @@ class TAG_Byte_Array(TAG_Value): if(data==""): self.value = value; 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'); def nbt_length(self) : @@ -177,7 +177,7 @@ class TAG_String(TAG_Value): if(data==""): self.value = value; else: - (string_len,) = struct.unpack(">h", data[0:2]); + (string_len,) = struct.unpack_from(">h", data); self.value = data[2:string_len+2].tostring(); def nbt_length(self) : @@ -196,14 +196,14 @@ class TAG_Compound(TAG_Value, collections.MutableMapping): tag = 10; - def setValue(self, val): + def dataType(self, val): for i in val: assert isinstance(val, TAG_Value) assert val.name - list = list(val) + return list(val) 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=""): @@ -211,9 +211,9 @@ class TAG_Compound(TAG_Value, collections.MutableMapping): if value.__class__ == ''.__class__: self.name = value; value = []; - self.list = [] + self.value = [] if(data == ""): - self.list += value; + self.value += value; else: 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 ) data_cursor += tag.nbt_length() - self.list.append(tag); + self.value.append(tag); 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): - for i in self.list: + for i in self.value: i.save(buf=buf) buf.write("\x00") "collection functions" 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]; - for key in self.list: + for key in self.value: if key.name == k: return key raise KeyError("Key {0} not found".format(k)); - def __iter__(self): return itertools.imap(lambda x:x.name, self.list); - def __contains__(self, k):return k in map(lambda x:x.name, self.list); - def __len__(self): return self.list.__len__() + 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.value); + def __len__(self): return self.value.__len__() def __setitem__(self, k, v): if not (v.__class__ in tag_handlers.values()): raise TypeError("Invalid type %s for TAG_Compound" % (v.__class__)) """remove any items already named "k". """ - olditems = filter(lambda x:x.name==k, self.list) - for i in olditems: self.list.remove(i) - self.list.append(v); + olditems = filter(lambda x:x.name==k, self.value) + for i in olditems: self.value.remove(i) + self.value.append(v); 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): self[v.name] = v; @@ -352,7 +352,7 @@ class TAG_List(TAG_Value, collections.MutableSequence): self.list.insert(i, v); 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): buf.write(struct.pack(TAGfmt, self.list_type)) @@ -376,7 +376,7 @@ tag_handlers = { }; 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): #sio = StringIO.StringIO();