Ejemplo n.º 1
0
    def encode(
        self,
        chunk: "Chunk",
        palette: AnyNDArray,
        max_world_version: Tuple[str, Union[int, Tuple[int, int, int]]],
        boxes: List[SelectionBox] = None,
    ) -> List[ConstructionSection]:
        sections = []
        for box in boxes:
            cx, cz = chunk.cx, chunk.cz
            for cy in box.chunk_y_locations():
                sub_box = box.intersection(
                    SelectionBox.create_sub_chunk_box(cx, cy, cz))
                entities = [e for e in chunk.entities if e.location in sub_box]
                if cy in chunk.blocks:
                    sections.append(
                        ConstructionSection(
                            sub_box.min,
                            sub_box.shape,
                            chunk.blocks[sub_box.chunk_slice(cx, cz)],
                            list(palette),
                            entities,
                            [
                                e for e in chunk.block_entities
                                if e.location in sub_box
                            ],
                        ))
                elif entities:
                    sections.append(
                        ConstructionSection(sub_box.min, sub_box.shape, None,
                                            [], entities, []))

        return sections
Ejemplo n.º 2
0
    def _sub_chunks(
        self, blocks: Blocks
    ) -> List[Tuple[numpy.ndarray, Tuple[int, int, int]]]:
        """Create sub-chunk arrays that extend into the neighbour sub-chunks by one block.

        :param blocks: The Blocks array for the chunk.
        :return: A list of tuples containing the larger block array and the location of the sub-chunk
        """
        sub_chunks = []
        neighbour_chunks = {}
        for dx, dz in ((-1, 0), (1, 0), (0, -1), (0, 1)):
            try:
                neighbour_chunks[(dx, dz)] = self._level.get_chunk(
                    self.cx + dx, self.cz + dz, self.dimension
                ).blocks
            except ChunkLoadError:
                continue

        for cy in blocks.sub_chunks:
            sub_chunk = blocks.get_sub_chunk(cy)
            larger_blocks = numpy.zeros(
                sub_chunk.shape + numpy.array((2, 2, 2)), sub_chunk.dtype
            )
            sub_chunk_box = SelectionBox.create_sub_chunk_box(self.cx, cy, self.cz)
            if self._level.selection_bounds.intersects(sub_chunk_box):
                boxes = self._level.selection_bounds.intersection(sub_chunk_box)
                for box in boxes.selection_boxes:
                    larger_blocks[1:-1, 1:-1, 1:-1][
                        box.sub_chunk_slice(self.cx, cy, self.cz)
                    ] = sub_chunk[box.sub_chunk_slice(self.cx, cy, self.cz)]
                for chunk_offset, neighbour_blocks in neighbour_chunks.items():
                    if cy not in neighbour_blocks:
                        continue
                    if chunk_offset == (-1, 0):
                        larger_blocks[0, 1:-1, 1:-1] = neighbour_blocks.get_sub_chunk(
                            cy
                        )[-1, :, :]
                    elif chunk_offset == (1, 0):
                        larger_blocks[-1, 1:-1, 1:-1] = neighbour_blocks.get_sub_chunk(
                            cy
                        )[0, :, :]
                    elif chunk_offset == (0, -1):
                        larger_blocks[1:-1, 1:-1, 0] = neighbour_blocks.get_sub_chunk(
                            cy
                        )[:, :, -1]
                    elif chunk_offset == (0, 1):
                        larger_blocks[1:-1, 1:-1, -1] = neighbour_blocks.get_sub_chunk(
                            cy
                        )[:, :, 0]
                if cy - 1 in blocks:
                    larger_blocks[1:-1, 0, 1:-1] = blocks.get_sub_chunk(cy - 1)[
                        :, -1, :
                    ]
                if cy + 1 in blocks:
                    larger_blocks[1:-1, -1, 1:-1] = blocks.get_sub_chunk(cy + 1)[
                        :, 0, :
                    ]
                sub_chunks.append((larger_blocks, (0, cy * 16, 0)))
        return sub_chunks
Ejemplo n.º 3
0
    def _sub_chunks(
        self, blocks: Blocks
    ) -> List[Tuple[numpy.ndarray, numpy.ndarray, Tuple[int, int, int]]]:
        sub_chunks = []
        neighbour_chunks = {}
        for dx, dz in ((-1, 0), (1, 0), (0, -1), (0, 1)):
            try:
                neighbour_chunks[(dx, dz)] = self._level.get_chunk(
                    self.cx + dx, self.cz + dz, self.dimension).blocks
            except ChunkLoadError:
                continue

        for cy in blocks.sub_chunks:
            sub_chunk = blocks.get_sub_chunk(cy)
            larger_blocks = numpy.zeros(
                sub_chunk.shape + numpy.array((2, 2, 2)), sub_chunk.dtype)
            sub_chunk_box = SelectionBox.create_sub_chunk_box(
                self.cx, cy, self.cz)
            if self._level.selection_bounds.intersects(sub_chunk_box):
                boxes = self._level.selection_bounds.intersection(
                    sub_chunk_box)
                for box in boxes.selection_boxes:
                    larger_blocks[1:-1, 1:-1, 1:-1][box.sub_chunk_slice(
                        self.cx, cy, self.cz)] = sub_chunk[box.sub_chunk_slice(
                            self.cx, cy, self.cz)]
                for chunk_offset, neighbour_blocks in neighbour_chunks.items():
                    if cy not in neighbour_blocks:
                        continue
                    if chunk_offset == (-1, 0):
                        larger_blocks[0, 1:-1,
                                      1:-1] = neighbour_blocks.get_sub_chunk(
                                          cy)[-1, :, :]
                    elif chunk_offset == (1, 0):
                        larger_blocks[-1, 1:-1,
                                      1:-1] = neighbour_blocks.get_sub_chunk(
                                          cy)[0, :, :]
                    elif chunk_offset == (0, -1):
                        larger_blocks[1:-1, 1:-1,
                                      0] = neighbour_blocks.get_sub_chunk(
                                          cy)[:, :, -1]
                    elif chunk_offset == (0, 1):
                        larger_blocks[1:-1, 1:-1,
                                      -1] = neighbour_blocks.get_sub_chunk(
                                          cy)[:, :, 0]
                if cy - 1 in blocks:
                    larger_blocks[1:-1, 0,
                                  1:-1] = blocks.get_sub_chunk(cy - 1)[:,
                                                                       -1, :]
                if cy + 1 in blocks:
                    larger_blocks[1:-1, -1,
                                  1:-1] = blocks.get_sub_chunk(cy + 1)[:, 0, :]
                unique_blocks = numpy.unique(larger_blocks)
                sub_chunks.append(
                    (larger_blocks, unique_blocks, (0, cy * 16, 0)))
        return sub_chunks
Ejemplo n.º 4
0
    def encode(
        self,
        chunk: "Chunk",
        palette: AnyNDArray,
        max_world_version: VersionIdentifierType,
        boxes: List[SelectionBox],
    ) -> List[ConstructionSection]:
        """
        Take a version-specific chunk and encode it to raw data for the format to store.
        :param chunk: The already translated version-specfic chunk to encode.
        :param palette: The block_palette the ids in the chunk correspond to.
        :type palette: numpy.ndarray[Block]
        :param max_world_version: The key to use to find the encoder.
        :param boxes: The volume(s) of the chunk to pack.
        :return: Raw data to be stored by the Format.
        """
        sections = []
        for box in boxes:
            cx, cz = chunk.cx, chunk.cz
            for cy in box.chunk_y_locations():
                sub_box = box.intersection(
                    SelectionBox.create_sub_chunk_box(cx, cy, cz))
                entities = [e for e in chunk.entities if e.location in sub_box]
                if cy in chunk.blocks:
                    sections.append(
                        ConstructionSection(
                            sub_box.min,
                            sub_box.shape,
                            numpy.asarray(chunk.blocks[sub_box.chunk_slice(
                                cx, cz)]),
                            list(palette),
                            entities,
                            [
                                e for e in chunk.block_entities
                                if e.location in sub_box
                            ],
                        ))
                elif entities:
                    sections.append(
                        ConstructionSection(sub_box.min, sub_box.shape, None,
                                            [], entities, []))

        return sections