def test_break_block(self): chunk = decode_chunk(self.data) base = Vector3(0, 0, 0) height = chunk.get_height(base.x, base.z) for y in range(height): self.assertNotEqual(BlockType.AIR, chunk.get_block(base.copy(y=y)).type) for y in range(height, 127): self.assertEqual(BlockType.AIR, chunk.get_block(base.copy(y=y)).type) chunk.set_block(base.copy(y=height - 1), Block.create(BlockType.AIR, 0)) expected_height = height - 1 height = chunk.get_height(base.x, base.z) self.assertEqual(expected_height, height) self.assertNotEqual(BlockType.AIR, chunk.get_block(base.copy(y=height - 1)).type) for y in range(height, 127): self.assertEqual(BlockType.AIR, chunk.get_block(base.copy(y=y)).type) chunk.set_block(base.copy(y=height - 2), Block.create(BlockType.AIR, 0)) expected_height = height height = chunk.get_height(base.x, base.z) self.assertEqual(expected_height, height) self.assertNotEqual(BlockType.AIR, chunk.get_block(base.copy(y=height - 1)).type) for y in range(height, 127): self.assertEqual(BlockType.AIR, chunk.get_block(base.copy(y=y)).type)
def get_block(self, position: Vector3[int]) -> Block: sub_chunk_index = position.y // self._Y_UNIT if sub_chunk_index >= len(self._sub_chunk): block_type = BlockType.AIR return Block.create(block_type, 0) # TODO check data or aux_value else: sub_chunk = self._sub_chunk[sub_chunk_index] y_in_sub = position.y % self._Y_UNIT block_type = sub_chunk.get_block_type(position.x, y_in_sub, position.z) block_data = sub_chunk.get_block_data(position.x, y_in_sub, position.z) return Block.create(block_type, block_data)
def stack_layer(self, base_block: Block, stacked_block: Block, face: Face) -> Optional[Block]: """ >>> spec = SlabBlockSpec(None, BlockType.DOUBLE_WOODEN_SLAB) >>> block_type = BlockType.WOODEN_SLAB >>> spec.stack_layer(Block.create(block_type, 0), Block.create(block_type, 8), Face.TOP) Block(type=<BlockType.DOUBLE_WOODEN_SLAB: 157>, aux_value=0) >>> spec.stack_layer(Block.create(block_type, 8), Block.create(block_type, 0), Face.BOTTOM) Block(type=<BlockType.DOUBLE_WOODEN_SLAB: 157>, aux_value=0) >>> spec.stack_layer(Block.create(block_type, 8), Block.create(block_type, 0), Face.TOP) >>> spec.stack_layer(Block.create(block_type, 0), Block.create(block_type, 8), Face.BOTTOM) >>> spec.stack_layer(Block.create(block_type, 0, neighbors=True), Block.create(block_type, 8), Face.TOP) Block(type=<BlockType.DOUBLE_WOODEN_SLAB: 157>, aux_value=0) >>> spec.stack_layer(Block.create(block_type, 0), Block.create(block_type, 8, neighbors=True), Face.TOP) Block(type=<BlockType.DOUBLE_WOODEN_SLAB: 157>, aux_value=16) >>> spec.stack_layer(\\ ... Block.create(block_type, 0, neighbors=True), Block.create(block_type, 8, neighbors=False), Face.TOP) Block(type=<BlockType.DOUBLE_WOODEN_SLAB: 157>, aux_value=0) """ slab_type = stacked_block.data & self._SLAB_TYPE_MASK if slab_type != base_block.data & self._SLAB_TYPE_MASK: return base_block is_upper = stacked_block.data & self._IS_UPPER_MASK if is_upper != base_block.data & self._IS_UPPER_MASK: if (face is Face.BOTTOM and is_upper) or (face is Face.TOP and not is_upper): return None return Block.create(self._full_stacked_block_type, slab_type, **stacked_block.flags) return None
def get_additional_blocks(self, block: Block, linked_blocks: Sequence[Block]) -> Tuple[PlacedBlock, ...]: assert len(linked_blocks) == 2 left_side_lower_block, left_side_upper_block = linked_blocks right_side_mask = 0 if left_side_lower_block.type == block.type and self._get_face(left_side_lower_block) == self._get_face(block): if not self._is_right_side(left_side_upper_block): right_side_mask = self._IS_RIGHT_SIDE_MASK data = self._IS_UPPER_MASK | right_side_mask return PlacedBlock(Vector3(0, 0, 0), block), PlacedBlock(Vector3(0, 1, 0), block.copy(data=data))
def stack_layer(self, base_block: Block, stacked_block: Block, face: Face) -> Optional[Block]: """ >>> spec = SnowLayerBlockSpec() >>> block_type = BlockType.SNOW_LAYER >>> spec.stack_layer(Block.create(block_type, 0), Block.create(block_type, 0), Face.TOP) Block(type=<BlockType.SNOW_LAYER: 78>, aux_value=1) >>> spec.stack_layer(Block.create(block_type, 1), Block.create(block_type, 0), Face.TOP) Block(type=<BlockType.SNOW_LAYER: 78>, aux_value=2) >>> spec.stack_layer(Block.create(block_type, 5), Block.create(block_type, 0), Face.TOP) Block(type=<BlockType.SNOW_LAYER: 78>, aux_value=6) >>> spec.stack_layer(Block.create(block_type, 6), Block.create(block_type, 0), Face.TOP) Block(type=<BlockType.SNOW: 80>, aux_value=0) """ layer_index = base_block.data + 1 if layer_index != self.max_layer_num - 1: return Block.create(BlockType.SNOW_LAYER, layer_index, **stacked_block.flags) else: return Block.create(BlockType.SNOW, 0, **stacked_block.flags)
def set_data(x: int, z: int) -> None: y = 0 chunk.set_block(Vector3(x, y, z), Block.create(BlockType.BEDROCK, 0)) y += 1 while y < height - 6: chunk.set_block(Vector3(x, y, z), Block.create(BlockType.STONE, 0)) y += 1 while y < height - 1: chunk.set_block(Vector3(x, y, z), Block.create(BlockType.STONE, 0)) y += 1 chunk.set_block(Vector3(x, y, z), Block.create(BlockType.GRASS, 0)) y += 1 assert y == height chunk.set_height(x, z, height) chunk.set_biome_id(x, z, BiomeType.PLAINS)
def get_additional_blocks(self, block: Block, linked_blocks: Sequence[Block]) -> Tuple[PlacedBlock, ...]: network = _RailNetwork(zip(_SURROUNDING, linked_blocks)) data = self._get_block_data(network, block.type == BlockType.RAIL) blocks = [PlacedBlock(Vector3(0, 0, 0), block.copy(data=data))] rail_type = _RAIL_TYPE[data] for connector in rail_type.connector: updated = self._update_neighbour(network, connector) if updated: blocks.append(updated) return tuple(blocks)
def to_block( self, item_data: int, attached_face: Face, player_yaw: float, click_position: Vector3[float], **flags: bool ) -> Optional[Block]: block_type = self.to_block_type(item_data, attached_face) if block_type is None or not self.is_attachable(attached_face): return None block_data = self.to_block_data(item_data, attached_face, player_yaw, click_position) return Block.create(block_type, block_data, **flags)
from typing import Callable, Dict, Iterator, List, NamedTuple, Optional, Tuple from pyminehub.mcpe.block import FunctionalBlock from pyminehub.mcpe.chunk import Chunk from pyminehub.mcpe.const import BlockType from pyminehub.mcpe.datastore import DataStore from pyminehub.mcpe.geometry import * from pyminehub.mcpe.value import Item, Block, PlacedBlock from pyminehub.mcpe.world.generator import SpaceGenerator __all__ = [ 'BLOCK_AIR', 'Space', ] BLOCK_AIR = Block(BlockType.AIR, 0) _UpdateAction = NamedTuple('UpdateAction', [('block', PlacedBlock), ('update', Callable[[], None])]) class _Transaction: def __init__(self) -> None: self._action = [] # type: List[_UpdateAction] def append(self, position: Vector3[int], block: Block, update: Callable[[], None]) -> None: self._action.append(_UpdateAction(PlacedBlock(position, block), update)) def clear(self) -> None:
def switch(self, block: Block) -> Block: block_type = BlockType.DAYLIGHT_DETECTOR_INVERTED \ if block.type is BlockType.DAYLIGHT_DETECTOR else BlockType.DAYLIGHT_DETECTOR return block.copy(block_type=block_type)
def switch(self, block: Block) -> Block: return block.copy(data=block.data ^ self._TOGGLE_MASK)
def get_additional_blocks(self, block: Block, linked_blocks: Sequence[Block]) -> Tuple[PlacedBlock, ...]: assert len(linked_blocks) == 1 base_side_block = linked_blocks[0] if base_side_block.type == block.type and base_side_block.data == block.data: block = block.copy(data=block.data ^ 1) return PlacedBlock(Vector3(0, 0, 0), block),
def switch(self, block: Block) -> Block: return block.copy(data=block.data ^ self._DOES_OPEN_MASK)
def get_additional_blocks(self, block: Block, linked_blocks: Sequence[Block]) -> Tuple[PlacedBlock, ...]: return PlacedBlock(Vector3(0, 0, 0), block), PlacedBlock(Vector3(0, 1, 0), block.copy(data=self._IS_UPPER_MASK))
from typing import Dict, List from unittest import TestCase # noinspection PyProtectedMember from pyminehub.mcpe.block.spec import RailBlockSpec, _SURROUNDING from pyminehub.mcpe.const import BlockType from pyminehub.mcpe.geometry import Vector3 from pyminehub.mcpe.value import Block, PlacedBlock AIR = Block.create(BlockType.AIR, 0) RAIL = Block.create(BlockType.RAIL, 0) POWERED_RAIL = Block.create(BlockType.GOLDEN_RAIL, 0) LINKED_BLOCKS = tuple((position, AIR) for position in _SURROUNDING) class RailTest(TestCase): def setUp(self): self.spec = RailBlockSpec(None) def _get_additional_blocks( self, block: Block, linked_blocks: Dict[Vector3[int], Block]) -> List[PlacedBlock]: linked_blocks = tuple(linked_blocks[p] for p in _SURROUNDING) return list(self.spec.get_additional_blocks(block, linked_blocks)) def test_rail_0(self): linked_blocks = dict(LINKED_BLOCKS) blocks = self._get_additional_blocks(RAIL, linked_blocks) self.assertEqual(1, len(blocks)) self.assertEqual(PlacedBlock(Vector3(0, 0, 0), RAIL), blocks.pop(0))
def set_data(x: int, z: int) -> None: chunk.set_block(Vector3(x, 0, z), Block.create(BlockType.BEDROCK, 0)) chunk.set_block(Vector3(x, 1, z), Block.create(BlockType.WATER, 0)) chunk.set_height(x, z, 2) chunk.set_biome_id(x, z, BiomeType.OCEAN)