Beispiel #1
0
def convert(tag):
    out = None
    if (tag.type is parse.TAG_Byte):
        out = nbt.TAG_Byte(value=tag.data, name=tag.name)
    elif (tag.type is parse.TAG_Byte_Array):
        out = nbt.TAG_Byte_Array(value=fromstring(tag.data), name=tag.name)
    elif (tag.type is parse.TAG_Double):
        out = nbt.TAG_Double(value=tag.data, name=tag.name)
    elif (tag.type is parse.TAG_Float):
        out = nbt.TAG_Float(value=tag.data, name=tag.name)
    elif (tag.type is parse.TAG_Int):
        out = nbt.TAG_Int(value=tag.data, name=tag.name)
    elif (tag.type is parse.TAG_Int_Array):
        out = nbt.TAG_Int_Array(value=tag.data, name=tag.name)
    elif (tag.type is parse.TAG_Long):
        out = nbt.TAG_Long(value=tag.data, name=tag.name)
    elif (tag.type is parse.TAG_Short):
        out = nbt.TAG_Short(value=tag.data, name=tag.name)
    elif (tag.type is parse.TAG_String):
        out = nbt.TAG_String(value=tag.data, name=tag.name)
    # Recursives
    elif (tag.type is parse.TAG_Compound):
        out = nbt.TAG_Compound(name=tag.name)
        for item in tag.data:
            temp = convert(item)
            if (temp is not None):
                out[temp.name] = temp
    elif (tag.type is parse.TAG_List):
        out = nbt.TAG_List(name=tag.name)
        for item in tag.data[1]:
            temp = convert(dummyNBTyaml(tag.data[0], item))
            if (temp is not None):
                out.append(temp)

    return out
Beispiel #2
0
    def generate_map(self, dungeon, level):
        '''Generate a new map, save it to disk, flush the cache, and return a
        map item NBT with the appropriate map ID.'''

        dungeon_key = '%s,%s' % (dungeon.position.x, dungeon.position.z)
        if dungeon_key not in self.mapcache['used']:
            self.mapcache['used'][dungeon_key] = set([])

        # Find a map id. Look in the available list for old mcdungeon maps
        # that can be reused. If not, bump up the idcount and use that.
        if len(self.mapcache['available']) == 0:
            # Initialize the map count if it doesn't exist.
            if 'map' not in self.idcounts:
                self.idcounts['map'] = nbt.TAG_Short(-1)

            self.idcounts['map'].value += 1
            mapid = self.idcounts['map'].value
            self.mapcache['used'][dungeon_key].add(mapid)
        else:
            mapid = self.mapcache['available'].pop()
            self.mapcache['used'][dungeon_key].add(mapid)
        filename = os.path.join(self.mapstore, 'map_%d.dat' % (mapid))

        # Setup the defaults.
        # Offset will be way off somewhere were players are unlikely to go
        # to avoid the maps from being overwritten. Nothing else really
        # matters.
        tags = nbt.TAG_Compound()
        tags['data'] = nbt.TAG_Compound()
        tags['data']['scale'] = nbt.TAG_Byte(0)
        tags['data']['xCenter'] = nbt.TAG_Int(-12500000)
        tags['data']['zCenter'] = nbt.TAG_Int(-12500000)
        tags['data']['height'] = nbt.TAG_Short(128)
        tags['data']['width'] = nbt.TAG_Short(128)
        tags['data']['dimension'] = nbt.TAG_Byte(0)
        tags['data']['colors'] = nbt.TAG_Byte_Array(zeros(16384, uint8))

        # Generate the map.
        blocks = dungeon.blocks
        colors = tags['data']['colors'].value
        y = level * dungeon.room_height - 3
        # Scale the map. We only scale up, not down since scaling
        # looks terrible.
        max_dungeon = max(dungeon.xsize * dungeon.room_size,
                          dungeon.zsize * dungeon.room_size)
        max_dungeon = max(128, max_dungeon)

        # If the size is less than 8, try to center it.
        xoffset = 0
        zoffset = 0
        if dungeon.xsize * dungeon.room_size < 128:
            xoffset = (128 - dungeon.xsize * dungeon.room_size) / 2
        if dungeon.zsize * dungeon.room_size < 128:
            zoffset = (128 - dungeon.zsize * dungeon.room_size) / 2

        # Draw pixels on the map corresponding to blocks just above
        # floor level. Color chests and spawners. Hide things that should be
        # hidden.
        for x in xrange(128):
            for z in xrange(128):
                block = Vec(x * max_dungeon / 128 - xoffset, y,
                            z * max_dungeon / 128 - zoffset)
                if block in blocks:
                    mat = blocks[block].material
                    if mat == materials.StonePressurePlate:
                        colors[x + z * 128] = 10
                    elif blocks[block].hide is True:
                        colors[x + z * 128] = 0
                    elif blocks[block].blank is True:
                        colors[x + z * 128] = 0
                    elif mat == materials.Air:
                        colors[x + z * 128] = 10
                    elif mat == materials.Spawner:
                        colors[x + z * 128] = 48
                    elif (mat == materials.Chest
                          or mat == materials.TrappedChest):
                        colors[x + z * 128] = 42
                    else:
                        colors[x + z * 128] = 54
                else:
                    colors[x + z * 128] = 0

        # Draw the level number in the corner
        digits = [[0, 1, 0, 1, 0, 1, 1, 0, 1, 1, 0, 1, 0, 1, 0],
                  [0, 1, 0, 1, 1, 0, 0, 1, 0, 0, 1, 0, 1, 1, 1],
                  [1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1],
                  [1, 1, 0, 0, 0, 1, 0, 1, 0, 0, 0, 1, 1, 1, 0],
                  [1, 0, 1, 1, 0, 1, 1, 1, 1, 0, 0, 1, 0, 0, 1],
                  [1, 1, 1, 1, 0, 0, 1, 1, 1, 0, 0, 1, 1, 1, 1],
                  [0, 1, 1, 1, 0, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1],
                  [1, 1, 1, 0, 0, 1, 0, 1, 0, 0, 1, 0, 0, 1, 0],
                  [1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1],
                  [1, 1, 1, 1, 0, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1]]
        sx = 120
        if level < 10:
            sx = 124
        sz = 123
        for d in str(level):
            for x in xrange(3):
                for z in xrange(5):
                    if digits[int(d)][x + z * 3] == 1:
                        colors[x + sx + (z + sz) * 128] = 16
            sx += 4

        # Save the map file, cache, and idcount.dat
        tags.save(filename)
        self.update_mapstore()

        # Return a map item
        item = nbt.TAG_Compound()
        item['id'] = nbt.TAG_String(items.byName('map').id)
        item['Damage'] = nbt.TAG_Short(mapid)
        item['Count'] = nbt.TAG_Byte(1)
        item['tag'] = nbt.TAG_Compound()
        item['tag']['display'] = nbt.TAG_Compound()
        name = dungeon.dungeon_name + ' Lv {l}'
        item['tag']['display']['Name'] = nbt.TAG_String(name.format(l=level))
        item['tag']['display']['MapColor'] = nbt.TAG_Int(self.mapcolor)
        print item['tag']['display']['Name'].value

        return item
Beispiel #3
0
    def testCreate():
        "Create an indev level."

        # The root of an NBT file is always a TAG_Compound.
        level = nbt.TAG_Compound(name="MinecraftLevel")

        # Subtags of a TAG_Compound are automatically named when you use the [] operator.
        level["About"] = nbt.TAG_Compound()
        level["About"]["Author"] = nbt.TAG_String("codewarrior")
        level["About"]["CreatedOn"] = nbt.TAG_Long(time.time())

        level["Environment"] = nbt.TAG_Compound()
        level["Environment"]["SkyBrightness"] = nbt.TAG_Byte(16)
        level["Environment"]["SurroundingWaterHeight"] = nbt.TAG_Short(32)
        level["Environment"]["FogColor"] = nbt.TAG_Int(0xcccccc)

        entity = nbt.TAG_Compound()
        entity["id"] = nbt.TAG_String("Creeper")
        entity["Pos"] = nbt.TAG_List([nbt.TAG_Float(d) for d in (32.5, 64.0, 33.3)])

        level["Entities"] = nbt.TAG_List([entity])

        # You can also create and name a tag before adding it to the compound.
        spawn = nbt.TAG_List((nbt.TAG_Short(100), nbt.TAG_Short(45), nbt.TAG_Short(55)))
        spawn.name = "Spawn"

        mapTag = nbt.TAG_Compound()
        mapTag.add(spawn)
        mapTag.name = "Map"
        level.add(mapTag)

        mapTag2 = nbt.TAG_Compound([spawn])
        mapTag2.name = "Map"

        # I think it looks more familiar with [] syntax.

        l, w, h = 128, 128, 128
        mapTag["Height"] = nbt.TAG_Short(h)  # y dimension
        mapTag["Length"] = nbt.TAG_Short(l)  # z dimension
        mapTag["Width"] = nbt.TAG_Short(w)  # x dimension

        # Byte arrays are stored as numpy.uint8 arrays.

        mapTag["Blocks"] = nbt.TAG_Byte_Array()
        mapTag["Blocks"].value = numpy.zeros(l * w * h, dtype=numpy.uint8)  # create lots of air!

        # The blocks array is indexed (y,z,x) for indev levels, so reshape the blocks
        mapTag["Blocks"].value.shape = (h, l, w)

        # Replace the bottom layer of the indev level with wood
        mapTag["Blocks"].value[0, :, :] = 5

        # This is a great way to learn the power of numpy array slicing and indexing.

        mapTag["Data"] = nbt.TAG_Byte_Array()
        mapTag["Data"].value = numpy.zeros(l * w * h, dtype=numpy.uint8)

        # Save a few more tag types for completeness

        level["ShortArray"] = nbt.TAG_Short_Array(numpy.zeros((16, 16), dtype='uint16'))
        level["IntArray"] = nbt.TAG_Int_Array(numpy.zeros((16, 16), dtype='uint32'))
        level["Float"] = nbt.TAG_Float(0.3)

        return level