Exemplo n.º 1
0
    def test_hash(self):
        stone = Block.from_string_blockstate("minecraft:stone")
        water = Block.from_string_blockstate("minecraft:water[level=1]")
        granite = Block.from_string_blockstate("minecraft:granite")
        dirt = Block.from_string_blockstate("minecraft:dirt")

        conglomerate_1 = stone + water + dirt
        conglomerate_2 = stone + dirt + water

        self.assertNotEqual(conglomerate_1, conglomerate_2)
        self.assertNotEqual(hash(conglomerate_1), hash(conglomerate_2))

        conglomerate_3 = dirt + water + dirt
        conglomerate_4 = dirt + dirt + water

        self.assertNotEqual(conglomerate_3, conglomerate_4)
        self.assertNotEqual(hash(conglomerate_3), hash(conglomerate_4))

        conglomerate_5 = conglomerate_1 + granite
        conglomerate_6 = conglomerate_3 + granite

        self.assertNotEqual(conglomerate_1, conglomerate_5)
        self.assertNotEqual(conglomerate_3, conglomerate_6)
        self.assertNotEqual(conglomerate_5, conglomerate_6)
        self.assertNotEqual(hash(conglomerate_5), hash(conglomerate_6))
Exemplo n.º 2
0
        def test_replace_single_block(self):
            subbox1 = SelectionBox((1, 70, 3), (5, 71, 6))
            box1 = SelectionGroup((subbox1, ))

            self.assertEqual(
                "universal_minecraft:stone",
                self.world.get_block(1, 70, 3, OVERWORLD).blockstate,
            )
            self.assertEqual(
                "universal_minecraft:granite[polished=false]",
                self.world.get_block(1, 70, 5, OVERWORLD).blockstate,
            )

            replace(
                self.world,
                OVERWORLD,
                box1,
                {
                    "original_blocks": [
                        Block.from_string_blockstate(
                            "universal_minecraft:granite[polished=false]")
                    ],
                    "replacement_blocks": [
                        Block.from_string_blockstate(
                            "universal_minecraft:stone")
                    ],
                },
            )
            self.world.create_undo_point()

            self.assertEqual(
                "universal_minecraft:stone",
                self.world.get_block(1, 70, 3, OVERWORLD).blockstate,
            )
            self.assertEqual(
                "universal_minecraft:stone",
                self.world.get_block(1, 70, 5, OVERWORLD).blockstate,
            )

            self.world.undo()

            self.assertEqual(
                "universal_minecraft:stone",
                self.world.get_block(1, 70, 3, OVERWORLD).blockstate,
            )
            self.assertEqual(
                "universal_minecraft:granite[polished=false]",
                self.world.get_block(1, 70, 5, OVERWORLD).blockstate,
            )

            self.world.redo()

            self.assertEqual(
                "universal_minecraft:stone",
                self.world.get_block(1, 70, 3, OVERWORLD).blockstate,
            )
            self.assertEqual(
                "universal_minecraft:stone",
                self.world.get_block(1, 70, 5, OVERWORLD).blockstate,
            )
Exemplo n.º 3
0
def paste_iter(
    dst: "BaseLevel",
    dst_dimension: Dimension,
    src: "BaseLevel",
    src_dimension: Dimension,
    location: BlockCoordinates,
    scale: FloatTriplet,
    rotation: FloatTriplet,
    copy_air=True,
    copy_water=True,
    copy_lava=True,
):
    yield from dst.paste_iter(
        src,
        src_dimension,
        src.bounds(src_dimension),
        dst_dimension,
        location,
        scale,
        rotation,
        True,
        True,
        tuple(UniversalAirLikeBlocks) * bool(not copy_air) +
        (Block("universal_minecraft", "water"), ) * bool(not copy_water) +
        (Block("universal_minecraft", "lava"), ) * bool(not copy_lava),
        True,
    )
Exemplo n.º 4
0
    def decode(
        self, cx: int, cz: int, section: MCStructureChunk
    ) -> Tuple["Chunk", AnyNDArray]:
        palette = numpy.empty(len(section.palette) + 1, dtype=numpy.object)
        palette[0] = (
            (
                17563649,
                Block(
                    namespace="minecraft",
                    base_name="air",
                    properties={"block_data": amulet_nbt.TAG_Int(0)},
                ),
            ),
        )

        for index, blocks in enumerate(section.palette):
            block_layers: List[Tuple[Optional[int], Block]] = []
            for block in blocks:
                namespace, base_name = block["name"].value.split(":", 1)
                if "version" in block:
                    version: Optional[int] = block["version"].value
                else:
                    version = None

                if "states" in block:  # 1.13 format
                    properties = block["states"].value
                    if version is None:
                        version = 17694720  # 1, 14, 0, 0
                else:
                    properties = {"block_data": amulet_nbt.TAG_Int(block["val"].value)}
                block_layers.append(
                    (
                        version,
                        Block(
                            namespace=namespace,
                            base_name=base_name,
                            properties=properties,
                        ),
                    )
                )
            palette[index + 1] = block_layers

        chunk = Chunk(cx, cz)
        box = section.selection.create_moved_box((cx * 16, 0, cz * 16), subtract=True)
        chunk.blocks[box.slice] = section.blocks + 1
        for b in section.block_entities:
            b = self._decode_block_entity(
                b, self._block_entity_id_type, self._block_entity_coord_type
            )
            if b is not None:
                chunk.block_entities.insert(b)
        for b in section.entities:
            b = self._decode_entity(
                b, self._block_entity_id_type, self._block_entity_coord_type
            )
            if b is not None:
                chunk.entities.append(b)

        return chunk, palette
Exemplo n.º 5
0
    def test_extra_blocks_immutable(self):
        stone = Block.from_string_blockstate("minecraft:stone")
        dirt = Block.from_string_blockstate("minecraft:dirt")

        stone2 = stone
        self.assertIs(stone, stone2)
        stone2 += dirt
        self.assertIsNot(stone, stone2)

        stone3 = stone2
        self.assertIs(stone2, stone3)
        stone3 -= dirt
        self.assertIsNot(stone, stone3)
Exemplo n.º 6
0
    def test_get_block_from_manager(self):
        dirt = Block.from_string_blockstate("minecraft:dirt")
        stone = Block.from_string_blockstate("minecraft:stone")
        granite = Block.from_string_blockstate("minecraft:granite")
        water = Block.from_string_blockstate("minecraft:water")
        dirt_water = dirt + water

        self.assertEqual(dirt, self.manager[0])
        self.assertEqual(stone, self.manager[1])
        self.assertEqual(granite, self.manager[2])
        self.assertEqual(dirt_water, self.manager[3])

        with self.assertRaises(KeyError):
            brain_coral = Block.from_string_blockstate("minecraft:brain_coral")
            internal_id = self.manager[brain_coral]
Exemplo n.º 7
0
    def setUp(self):
        self.manager = BlockManager()

        initial_dirt = Block.from_string_blockstate("minecraft:dirt")
        initial_stone = Block.from_string_blockstate("minecraft:stone")
        initial_granite = Block.from_string_blockstate("minecraft:granite")

        initial_dirt_water = initial_dirt + Block.from_string_blockstate(
            "minecraft:water"
        )

        # Partially populate the manager
        self.manager.get_add_block(initial_dirt)
        self.manager.get_add_block(initial_stone)
        self.manager.get_add_block(initial_granite)
        self.manager.get_add_block(initial_dirt_water)
Exemplo n.º 8
0
    def _pack_block_palette(
        self, version: "Version", palette: BlockNDArray
    ) -> AnyNDArray:
        """
        Packs a numpy array of Block objects into an object array containing one more more pairs of version number and Block objects.
        :param version:
        :param palette:
        :return: numpy.ndarray[Tuple[Tuple[Optional[VersionNumber], Block], ...]]
        """
        palette_ = numpy.empty(len(palette), dtype=object)
        for palette_index, block in enumerate(palette):
            block: "Block"
            # TODO: perhaps check that all properties are NBT objects user interaction if not
            blocks = []
            for b in block.block_tuple:
                if "__version__" in b.properties:
                    properties = b.properties
                    version_number = properties.pop("__version__").value
                    b = Block(b.namespace, b.base_name, properties, b.extra_blocks)
                else:
                    version_number = None
                blocks.append((version_number, b))
            palette_[palette_index] = tuple(blocks)

        return palette_
Exemplo n.º 9
0
    def __init__(self,
                 directory: str,
                 world_wrapper: "WorldFormatWrapper",
                 temp_dir: str = None):
        self._directory = directory
        if temp_dir is None:
            self._temp_directory = get_temp_dir(self._directory)
        else:
            self._temp_directory = temp_dir

        self._world_wrapper = world_wrapper
        self._world_wrapper.open()

        self._block_palette = BlockManager()
        self._block_palette.get_add_block(
            Block(namespace="universal_minecraft",
                  base_name="air"))  # ensure that index 0 is always air

        self._biome_palette = BiomeManager()
        self._biome_palette.get_add_biome("universal_minecraft:plains")

        self._history_manager = MetaHistoryManager()

        self._chunks: ChunkManager = ChunkManager(
            os.path.join(self._temp_directory, "chunks"), self)

        self._history_manager.register(self._chunks, True)
    def _decode_blocks(
        self, chunk_sections: amulet_nbt.TAG_List
    ) -> Tuple[Dict[int, SubChunkNDArray], AnyNDArray]:
        blocks: Dict[int, numpy.ndarray] = {}
        palette = [Block(namespace="minecraft", base_name="air")]

        for section in chunk_sections:
            if "Palette" not in section:  # 1.14 makes block_palette/blocks optional.
                continue
            cy = section["Y"].value
            if self.features["long_array_format"] == "compact":
                decoded = decode_long_array(section["BlockStates"].value, 4096)
            elif self.features["long_array_format"] == "1.16":
                decoded = decode_long_array(
                    section["BlockStates"].value, 4096, dense=False
                )
            else:
                raise Exception("long_array_format", self.features["long_array_format"])
            blocks[cy] = numpy.transpose(
                decoded.reshape((16, 16, 16)) + len(palette), (2, 0, 1)
            )

            palette += self._decode_palette(section["Palette"])

        np_palette, inverse = numpy.unique(palette, return_inverse=True)
        np_palette: numpy.ndarray
        inverse: numpy.ndarray
        for cy in blocks:
            blocks[cy] = inverse[blocks[cy]].astype(
                numpy.uint32
            )  # TODO: find a way to make the new blocks format change dtype
        return blocks, np_palette
Exemplo n.º 11
0
    def decode(self, cx: int, cz: int,
               data: SpongeSchemChunk) -> Tuple["Chunk", AnyNDArray]:
        """
        Create an amulet.api.chunk.Chunk object from raw data given by the format
        :param cx: chunk x coordinate
        :param cz: chunk z coordinate
        :param data: Raw chunk data provided by the format.
        :return: Chunk object in version-specific format, along with the block_palette for that chunk.
        """
        palette = numpy.empty(len(data.palette) + 1, dtype=object)
        palette[0] = Block(namespace="minecraft", base_name="air")
        palette[1:] = data.palette[:]

        chunk = Chunk(cx, cz)
        box = data.selection.create_moved_box((cx * 16, 0, cz * 16),
                                              subtract=True)
        chunk.blocks[box.slice] = data.blocks + 1
        for b in data.block_entities:
            b = self._decode_block_entity(b, self._block_entity_id_type,
                                          self._block_entity_coord_type)
            if b is not None:
                chunk.block_entities.insert(b)
        for e in data.entities:
            e = self._decode_entity(e, self._block_entity_id_type,
                                    self._block_entity_coord_type)
            if e is not None:
                chunk.entities.append(e)

        return chunk, palette
Exemplo n.º 12
0
def unpack_palette(raw_palette: amulet_nbt.TAG_List) -> List[Block]:
    block_palette = []
    extra_block_map = {}
    for block_index, block_nbt in enumerate(raw_palette):
        block_nbt: amulet_nbt.TAG_Compound
        block_namespace = block_nbt["namespace"].value
        block_basename = block_nbt["blockname"].value
        block = Block(
            namespace=block_namespace,
            base_name=block_basename,
            properties=block_nbt["properties"].value,
        )

        if block_nbt["extra_blocks"].value:
            extra_block_map[block_index] = block_nbt["extra_blocks"].value

        block_palette.append(block)

    for block_index, extra_blocks in extra_block_map.items():
        extra_block_objects = [block_palette[i.value] for i in extra_blocks]

        resulting_block = block_palette[block_index]
        for extra_block in extra_block_objects:
            resulting_block = resulting_block + extra_block

        block_palette[block_index] = resulting_block
    return block_palette
Exemplo n.º 13
0
    def _unpack_blocks(
        translation_manager: "TranslationManager",
        version_identifier: VersionIdentifierType,
        chunk: Chunk,
        block_palette: AnyNDArray,
    ):
        """
        Unpack the version-specific block_palette into the stringified version where needed.

        :return: The block_palette converted to block objects.
        """
        version = translation_manager.get_version(*version_identifier)
        for index, block in enumerate(block_palette):
            block: Block
            if version.block.is_waterloggable(block.namespaced_name):
                properties = block.properties
                if "waterlogged" in properties:
                    waterlogged = properties["waterlogged"]
                    del properties["waterlogged"]
                    block = Block(
                        namespace=block.namespace,
                        base_name=block.base_name,
                        properties=properties,
                    )
                else:
                    waterlogged = amulet_nbt.TAG_String("false")

                if waterlogged == amulet_nbt.TAG_String("true"):
                    block_palette[index] = block + water
                else:
                    block_palette[index] = block
            elif version.block.is_waterloggable(block.namespaced_name, True):
                block_palette[index] = block + water

        chunk._block_palette = BlockManager(block_palette)
Exemplo n.º 14
0
def delete(world: "World", dimension: Dimension, selection: SelectionGroup):
    yield from fill(
        world, dimension, selection, {
            "fill_block":
            world.translation_manager.get_version(
                'java',
                (1, 15, 2)).block.to_universal(Block("minecraft", "air"))[0]
        })
Exemplo n.º 15
0
 def block(self) -> Block:
     if self._wildcard:
         raise Exception('block property cannot be used when BlockDefine is in wildcard mode')
     else:
         return Block(
             self.namespace,
             self.base_name,
             {key: amulet_nbt.from_snbt(value) for key, value in self.properties.items()}
         )
 def _decode_palette(palette: amulet_nbt.TAG_List) -> list:
     blockstates = []
     for entry in palette:
         namespace, base_name = entry["Name"].value.split(":", 1)
         properties = entry.get("Properties", amulet_nbt.TAG_Compound({})).value
         block = Block(
             namespace=namespace, base_name=base_name, properties=properties
         )
         blockstates.append(block)
     return blockstates
Exemplo n.º 17
0
    def test_get_index_from_manager(self):
        dirt = Block.from_string_blockstate("minecraft:dirt")
        stone = Block.from_string_blockstate("minecraft:stone")
        granite = Block.from_string_blockstate("minecraft:granite")

        self.assertEqual(0, self.manager[dirt])
        self.assertEqual(1, self.manager[stone])
        self.assertEqual(2, self.manager[granite])

        water = Block.from_string_blockstate("minecraft:water")

        dirt_water = dirt + water

        self.assertNotEqual(dirt, dirt_water)
        self.assertIsNot(dirt, dirt_water)
        self.assertEqual(3, self.manager[dirt_water])

        with self.assertRaises(KeyError):
            random_block = self.manager[10000]
Exemplo n.º 18
0
    def test_extra_blocks(self):
        stone = Block.from_string_blockstate("minecraft:stone")
        water = Block.from_string_blockstate("minecraft:water[level=1]")
        granite = Block.from_string_blockstate("minecraft:granite")
        dirt = Block.from_string_blockstate("minecraft:dirt")

        conglomerate_1 = stone + water + dirt
        self.assertIsInstance(conglomerate_1, Block)
        self.assertEqual("minecraft", conglomerate_1.namespace)
        self.assertEqual("stone", conglomerate_1.base_name)
        self.assertEqual({}, conglomerate_1.properties)
        self.assertEqual(2, len(conglomerate_1.extra_blocks))
        for block_1, block_2 in zip(conglomerate_1.extra_blocks, (water, dirt)):
            self.assertEqual(block_1, block_2)
            self.assertEqual(0, len(block_1.extra_blocks))

        conglomerate_2 = conglomerate_1 + granite
        self.assertIsInstance(conglomerate_2, Block)
        self.assertEqual("minecraft", conglomerate_2.namespace)
        self.assertEqual("stone", conglomerate_2.base_name)
        self.assertEqual({}, conglomerate_2.properties)
        self.assertEqual(3, len(conglomerate_2.extra_blocks))
        for block_1, block_2 in zip(
            conglomerate_2.extra_blocks, (water, dirt, granite)
        ):
            self.assertEqual(block_1, block_2)
            self.assertEqual(0, len(block_1.extra_blocks))

        self.assertNotEqual(conglomerate_1, conglomerate_2)

        conglomerate_3 = conglomerate_2 - dirt
        self.assertIsInstance(conglomerate_3, Block)
        self.assertEqual("minecraft", conglomerate_3.namespace)
        self.assertEqual("stone", conglomerate_3.base_name)
        self.assertEqual({}, conglomerate_3.properties)
        self.assertEqual(2, len(conglomerate_3.extra_blocks))
        for block_1, block_2 in zip(conglomerate_3.extra_blocks, (water, granite)):
            self.assertEqual(block_1, block_2)
            self.assertEqual(0, len(block_1.extra_blocks))

        self.assertRaises(TypeError, lambda: stone + 1)
        self.assertRaises(TypeError, lambda: stone - 1)
Exemplo n.º 19
0
def delete(
    world: "World", dimension: Dimension, selection: SelectionGroup
) -> OperationReturnType:
    yield from fill(
        world,
        dimension,
        selection,
        world.translation_manager.get_version("java", (1, 15, 2)).block.to_universal(
            Block("minecraft", "air")
        )[0],
    )
Exemplo n.º 20
0
def set_block_property(block, key, val):
    p = block.properties.copy()
    nbt_val = None
    if isinstance(val, str):
        nbt_val = amulet_nbt.TAG_String(val)
    #TODO: can blocks actually have non-string properties?
    # Why are things like glass panes facings stored as strings?
    else:
        assert False, "Bad Property"
    p[key] = nbt_val
    block2 = Block(block.namespace, block.base_name, p)
    return block2
Exemplo n.º 21
0
    def _blockstates(
        specification: dict, namespace_str: str, base_name: str
    ) -> Generator[Block, None, None]:
        properties = specification.get("properties", {})
        if properties:
            keys, values = zip(*properties.items())
        else:
            keys, values = (), ()
        values = tuple([amulet_nbt.from_snbt(val) for val in prop] for prop in values)

        for spec_ in itertools.product(*values):
            spec = dict(zip(keys, spec_))
            yield Block(namespace=namespace_str, base_name=base_name, properties=spec)
Exemplo n.º 22
0
        def test_fill_operation(self):
            subbox_1 = SelectionBox((1, 70, 3), (5, 71, 5))
            selection = SelectionGroup((subbox_1, ))

            # Start sanity check
            self.assertEqual(
                "universal_minecraft:stone",
                self.world.get_block(1, 70, 3, OVERWORLD).blockstate,
            )
            self.assertEqual(
                "universal_minecraft:granite[polished=false]",
                self.world.get_block(1, 70, 5, OVERWORLD).blockstate,
            )
            # End sanity check

            generator_unpacker(
                fill(
                    self.world,
                    OVERWORLD,
                    selection,
                    Block.from_string_blockstate("universal_minecraft:stone"),
                ))
            self.world.create_undo_point()

            for x, y, z in selection.blocks:
                self.assertEqual(
                    "universal_minecraft:stone",
                    self.world.get_block(x, y, z, OVERWORLD).blockstate,
                    f"Failed at coordinate ({x},{y},{z})",
                )

            self.world.undo()

            self.assertEqual(
                "universal_minecraft:stone",
                self.world.get_block(1, 70, 3, OVERWORLD).blockstate,
            )

            self.assertEqual(
                "universal_minecraft:granite[polished=false]",
                self.world.get_block(1, 70, 5, OVERWORLD).blockstate,
            )

            self.world.redo()

            for x, y, z in selection.blocks:
                self.assertEqual(
                    "universal_minecraft:stone",
                    self.world.get_block(x, y, z, OVERWORLD).blockstate,
                    f"Failed at coordinate ({x},{y},{z})",
                )
Exemplo n.º 23
0
    def _unpack_blocks(
        translation_manager: "TranslationManager",
        version_identifier: VersionIdentifierType,
        chunk: Chunk,
        block_palette: AnyNDArray,
    ):
        """
        Unpacks an object array of block data into a numpy object array containing Block objects.
        :param translation_manager:
        :param version_identifier:
        :param chunk:
        :param block_palette:
        :type block_palette: numpy.ndarray[
            Tuple[
                Union[
                    Tuple[None, Tuple[int, int]],
                    Tuple[None, Block],
                    Tuple[int, Block]
                ], ...
            ]
        ]
        :return:
        """
        palette_ = BlockManager()
        for palette_index, entry in enumerate(block_palette):
            entry: BedrockInterfaceBlockType
            block = None
            for version_number, b in entry:
                version_number: Optional[int]
                if isinstance(b, tuple):
                    version = translation_manager.get_version(
                        version_identifier[0], version_number or 17563649)
                    b = version.block.ints_to_block(*b)
                elif isinstance(b, Block):
                    if version_number is not None:
                        properties = b.properties
                        properties["__version__"] = amulet_nbt.TAG_Int(
                            version_number)
                        b = Block(b.namespace, b.base_name, properties,
                                  b.extra_blocks)
                else:
                    raise Exception(f"Unsupported type {b}")
                if block is None:
                    block = b
                else:
                    block += b
            if block is None:
                raise Exception(f"Empty tuple")

            palette_.get_add_block(block)
        chunk._block_palette = palette_
Exemplo n.º 24
0
        def translate_block(
            input_object: Block,
            get_block_callback: Optional[GetBlockCallback],
            block_location: BlockCoordinates,
        ) -> TranslateBlockCallbackReturn:
            final_block = None
            final_block_entity = None
            final_entities = []
            final_extra = False

            for depth, block in enumerate(input_object.block_tuple):
                (
                    output_object,
                    output_block_entity,
                    extra,
                ) = version.block.from_universal(
                    block,
                    get_block_callback=get_block_callback,
                    block_location=block_location,
                )

                if isinstance(output_object, Block):
                    if __debug__ and output_object.namespace.startswith(
                            "universal"):
                        log.debug(
                            f"Error translating {input_object.full_blockstate} from universal. Got {output_object.full_blockstate}"
                        )
                    if version.data_version > 0:
                        properties = output_object.properties
                        properties["__version__"] = amulet_nbt.TAG_Int(
                            version.data_version)
                        output_object = Block(
                            output_object.namespace,
                            output_object.base_name,
                            properties,
                            output_object.extra_blocks,
                        )
                    if final_block is None:
                        final_block = output_object
                    else:
                        final_block += output_object
                    if depth == 0:
                        final_block_entity = output_block_entity

                elif isinstance(output_object, Entity):
                    final_entities.append(output_object)
                    # TODO: offset entity coords

                final_extra |= extra

            return final_block, final_block_entity, final_entities, final_extra
Exemplo n.º 25
0
    def decode(self, cx: int, cz: int,
               data: List[ConstructionSection]) -> Tuple["Chunk", AnyNDArray]:
        """
        Create an amulet.api.chunk.Chunk object from raw data given by the format
        :param cx: chunk x coordinate
        :param cz: chunk z coordinate
        :param data: Raw chunk data provided by the format.
        :return: Chunk object in version-specific format, along with the block_palette for that chunk.
        """
        chunk = Chunk(cx, cz)
        palette = []
        for section in data:
            if any(s == 0 for s in section.shape):
                continue
            if section.blocks is not None:
                shapex, shapey, shapez = section.shape
                sx = section.sx % 16
                sy = section.sy
                sz = section.sz % 16
                chunk.blocks[sx:sx + shapex, sy:sy + shapey,
                             sz:sz + shapez, ] = section.blocks.astype(
                                 numpy.uint32) + len(palette)
                chunk.block_entities.update(section.block_entities)
            chunk.entities.extend(section.entities)
            palette += section.palette

        np_palette, inverse = numpy.unique(palette, return_inverse=True)
        np_palette = numpy.insert(
            np_palette,
            0,
            Block(
                namespace="minecraft",
                base_name="air",
                properties={"block_data": amulet_nbt.TAG_Int(0)},
            ),
        )
        inverse += 1
        np_palette: AnyNDArray
        inverse: numpy.ndarray
        for cy in chunk.blocks.sub_chunks:
            chunk.blocks.add_sub_chunk(
                cy,
                inverse[chunk.blocks.get_sub_chunk(cy)].astype(numpy.uint32))
        return chunk, np_palette
Exemplo n.º 26
0
    def _decode_blocks(self, chunk: Chunk,
                       chunk_sections: Dict[int, TAG_Compound]) -> AnyNDArray:
        blocks: Dict[int, numpy.ndarray] = {}
        palette = [Block(namespace="minecraft", base_name="air")]

        for cy, section in chunk_sections.items():
            data = self._decode_block_section(section)
            if data is not None:
                arr, section_palette = data
                blocks[cy] = arr + len(palette)
                palette += section_palette

        np_palette, inverse = numpy.unique(palette, return_inverse=True)
        np_palette: numpy.ndarray
        inverse: numpy.ndarray
        inverse = inverse.astype(numpy.uint32)
        for cy in blocks:
            blocks[cy] = inverse[blocks[cy]]
        chunk.blocks = blocks
        return np_palette
Exemplo n.º 27
0
def copy_selection(
    world: "World",
    dimension: Dimension,
    selection: SelectionGroup
):
    structure = Structure.from_world(
        world, selection, dimension
    )
    structure_buffer.append(structure)
    yield from fill(
        world,
        dimension,
        selection,
        {
            "fill_block": world.translation_manager.get_version(
                'java', (1, 15, 2)
            ).block.to_universal(
                Block("minecraft", "air")
            )[0]
        }
    )
Exemplo n.º 28
0
 def _pack_block_palette(self, version: "Version",
                         palette: BlockNDArray) -> AnyNDArray:
     """
     Translate the list of block objects into a version-specific block_palette.
     :return: The block_palette converted into version-specific blocks (ie id, data tuples for 1.12)
     """
     for index, block in enumerate(palette):
         block: Block
         if version.block.is_waterloggable(block.namespaced_name):
             properties = block.properties
             extra_blocks = block.extra_blocks
             if (extra_blocks and extra_blocks[0].namespaced_name
                     == water.namespaced_name):
                 properties["waterlogged"] = amulet_nbt.TAG_String("true")
             else:
                 properties["waterlogged"] = amulet_nbt.TAG_String("false")
             palette[index] = Block(
                 namespace=block.namespace,
                 base_name=block.base_name,
                 properties=properties,
             )
     return palette
Exemplo n.º 29
0
def createBlocks(world):
    """generates all needed Block objects"""

    barrel = getBlock(
        world,
        Block(
            "minecraft", "barrel", {
                "facing": amulet_nbt.TAG_String("up"),
                "open": amulet_nbt.TAG_String("false")
            }))

    wool = getBlock(world, Block("minecraft", "red_wool"))

    air = getBlock(world, Block("minecraft", "air"))

    stone = getBlock(world, Block("minecraft", "stone"))

    glowstone = getBlock(world, Block("minecraft", "glowstone"))

    lantern = getBlock(
        world,
        Block("minecraft", "lantern",
              {"hanging": amulet_nbt.TAG_String("false")}))

    sign_north = getBlock(
        world,
        Block("minecraft", "acacia_wall_sign",
              {"facing": amulet_nbt.TAG_String("north")}))
    sign_south = getBlock(
        world,
        Block("minecraft", "acacia_wall_sign",
              {"facing": amulet_nbt.TAG_String("south")}))

    return [
        barrel, wool, glowstone, sign_north, sign_south, air, stone, lantern
    ]
Exemplo n.º 30
0
    def decode(
        self, cx: int, cz: int, data: List[ConstructionSection]
    ) -> Tuple["Chunk", AnyNDArray]:
        chunk = Chunk(cx, cz)
        palette = []
        for section in data:
            if any(s == 0 for s in section.shape):
                continue
            if section.blocks is not None:
                shapex, shapey, shapez = section.shape
                sx = section.sx - ((section.sx >> 4) << 4)
                sy = section.sy
                sz = section.sz - ((section.sz >> 4) << 4)
                chunk.blocks[
                    sx : sx + shapex, sy : sy + shapey, sz : sz + shapez,
                ] = section.blocks.astype(numpy.uint32) + len(palette)
                chunk.block_entities.update(section.block_entities)
            chunk.entities.extend(section.entities)
            palette += section.palette

        np_palette, inverse = numpy.unique(palette, return_inverse=True)
        np_palette = numpy.insert(
            np_palette,
            0,
            Block(
                namespace="minecraft",
                base_name="air",
                properties={"block_data": amulet_nbt.TAG_Int(0)},
            ),
        )
        inverse += 1
        np_palette: AnyNDArray
        inverse: numpy.ndarray
        for cy in chunk.blocks.sub_chunks:
            chunk.blocks.add_sub_chunk(
                cy, inverse[chunk.blocks.get_sub_chunk(cy)].astype(numpy.uint32)
            )
        return chunk, np_palette