diff --git a/src/block/Block.php b/src/block/Block.php index 41983df64..73e1b1ccb 100644 --- a/src/block/Block.php +++ b/src/block/Block.php @@ -78,25 +78,47 @@ class Block{ $this->position = clone $this->position; } + /** + * Returns an object containing information about how to identify and store this block type, such as its legacy + * numeric ID(s), tile type (if any), and legacy variant metadata. + */ public function getIdInfo() : BlockIdentifier{ return $this->idInfo; } + /** + * Returns the printable English name of the block. + */ public function getName() : string{ return $this->fallbackName; } + /** + * @deprecated + * + * Returns the legacy numeric Minecraft block ID. + */ public function getId() : int{ return $this->idInfo->getBlockId(); } /** * @internal + * + * Returns the full blockstate ID of this block. This is a compact way of representing a blockstate used to store + * blocks in chunks at runtime. + * + * This ID can be used to later obtain a copy of this block using {@link BlockFactory::get()}. */ public function getFullId() : int{ return ($this->getId() << self::INTERNAL_METADATA_BITS) | $this->getMeta(); } + /** + * Returns the block as an item. + * State information such as facing, powered/unpowered, open/closed, etc., is discarded. + * Type information such as colour, wood type, etc. is preserved. + */ public function asItem() : Item{ return ItemFactory::getInstance()->get( $this->idInfo->getItemId(), @@ -104,6 +126,12 @@ class Block{ ); } + /** + * @deprecated + * + * Returns the legacy Minecraft block meta value. This is a mixed-purpose value, which is used to store different + * things for different blocks. + */ public function getMeta() : int{ $stateMeta = $this->writeStateToMeta(); assert(($stateMeta & ~$this->getStateBitmask()) === 0); @@ -116,6 +144,7 @@ class Block{ /** * Returns a bitmask used to extract state bits from block metadata. + * This is used to remove unwanted information from the legacy meta value when getting the block as an item. */ public function getStateBitmask() : int{ return 0; @@ -143,6 +172,12 @@ class Block{ $this->collisionBoxes = null; } + /** + * Writes information about the block into the world. This writes the blockstate ID into the chunk, and creates + * and/or removes tiles as necessary. + * + * Note: Do not call this directly. Pass the block to {@link World::setBlock()} instead. + */ public function writeStateToWorld() : void{ $this->position->getWorld()->getOrLoadChunkAtPosition($this->position)->setFullBlock($this->position->x & Chunk::COORD_MASK, $this->position->y, $this->position->z & Chunk::COORD_MASK, $this->getFullId()); @@ -167,7 +202,7 @@ class Block{ } /** - * Returns a type ID that identifies this type of block. This does not include information like facing, colour, + * Returns a type ID that identifies this type of block. This does not include information like facing, open/closed, * powered/unpowered, etc. */ public function getTypeId() : int{ @@ -198,22 +233,36 @@ class Block{ return true; } + /** + * Returns whether this block can be replaced by another block placed in the same position. + */ public function canBeReplaced() : bool{ return false; } + /** + * Returns whether this block can replace the given block in the given placement conditions. + * This is used to allow slabs of the same type to combine into double slabs. + */ public function canBePlacedAt(Block $blockReplace, Vector3 $clickVector, int $face, bool $isClickedBlock) : bool{ return $blockReplace->canBeReplaced(); } /** - * Places the Block, using block space and block target, and side. Returns if the block has been placed. + * Generates a block transaction to set all blocks affected by placing this block. Usually this is just the block + * itself, but may be multiple blocks in some cases (such as doors). + * + * @return bool whether the placement should go ahead */ public function place(BlockTransaction $tx, Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ $tx->addBlock($blockReplace->position, $this); return true; } + /** + * Called immediately after the block has been placed in the world. Since placement uses a block transaction, some + * things may not be possible until after the transaction has been executed. + */ public function onPostPlace() : void{ } @@ -252,7 +301,7 @@ class Block{ /** * Called when this block is randomly updated due to chunk ticking. - * WARNING: This will not be called if ticksRandomly() does not return true! + * WARNING: This will not be called if {@link Block::ticksRandomly()} does not return true! */ public function onRandomTick() : void{ @@ -273,8 +322,7 @@ class Block{ } /** - * Called when this block is attacked (left-clicked). This is called when a player left-clicks the block to try and - * start to break it in survival mode. + * Called when this block is attacked (left-clicked) by a player attempting to start breaking it in survival. * * @return bool if an action took place, prevents starting to break the block if true. */ @@ -293,6 +341,8 @@ class Block{ } /** + * Returns the amount of light emitted by this block. + * * @return int 0-15 */ public function getLightLevel() : int{ @@ -424,6 +474,7 @@ class Block{ /** * Returns the item that players will equip when middle-clicking on this block. + * If addUserData is true, additional data may be added, such as banner patterns, chest contents, etc. */ public function getPickedItem(bool $addUserData = false) : Item{ $item = $this->asItem(); @@ -547,7 +598,7 @@ class Block{ } /** - * Checks for collision against an AxisAlignedBB + * Returns whether any of the block's collision boxes intersect with the given AxisAlignedBB. */ public function collidesWithBB(AxisAlignedBB $bb) : bool{ foreach($this->getCollisionBoxes() as $bb2){ @@ -603,6 +654,13 @@ class Block{ } /** + * Returns an array of collision bounding boxes for this block. + * These are used for: + * - entity movement collision checks (to ensure entities can't clip through blocks) + * - projectile flight paths + * - block placement (to ensure the player can't place blocks inside itself or another entity) + * - anti-cheat checks in plugins + * * @return AxisAlignedBB[] */ final public function getCollisionBoxes() : array{ @@ -633,6 +691,10 @@ class Block{ return [AxisAlignedBB::one()]; } + /** + * Returns the type of support that the block can provide on the given face. This is used to determine whether + * blocks placed on the given face can be supported by this block. + */ public function getSupportType(int $facing) : SupportType{ return SupportType::FULL(); } @@ -643,6 +705,10 @@ class Block{ return count($bb) === 1 && $bb[0]->getAverageEdgeLength() >= 1 && $bb[0]->isCube(); } + /** + * Performs a ray trace along the line between the two positions using the block's collision boxes. + * Returns the intersection point closest to pos1, or null if no intersection occurred. + */ public function calculateIntercept(Vector3 $pos1, Vector3 $pos2) : ?RayTraceResult{ $bbs = $this->getCollisionBoxes(); if(count($bbs) === 0){