diff --git a/src/block/Anvil.php b/src/block/Anvil.php index edfb9491d..ee8b25e38 100644 --- a/src/block/Anvil.php +++ b/src/block/Anvil.php @@ -51,7 +51,7 @@ class Anvil extends Transparent implements Fallable{ private int $damage = self::UNDAMAGED; - protected function describeType(RuntimeDataDescriber $w) : void{ + public function describeType(RuntimeDataDescriber $w) : void{ $w->boundedInt(2, self::UNDAMAGED, self::VERY_DAMAGED, $this->damage); } diff --git a/src/block/Block.php b/src/block/Block.php index d557411fe..be46de592 100644 --- a/src/block/Block.php +++ b/src/block/Block.php @@ -76,6 +76,8 @@ class Block{ */ private static array $stateDataBits = []; + private int $defaultStateData; + /** * @param string $name English name of the block type (TODO: implement translations) */ @@ -84,6 +86,8 @@ class Block{ $this->fallbackName = $name; $this->typeInfo = $typeInfo; $this->position = new Position(0, 0, 0, null); + + $this->defaultStateData = $this->computeStateData(); } public function __clone(){ @@ -174,7 +178,9 @@ class Block{ * Type information such as colour, wood type, etc. is preserved. */ public function asItem() : Item{ - return new ItemBlock($this); + $normalized = clone $this; + $normalized->decodeStateData($this->defaultStateData); + return new ItemBlock($normalized); } final public function getRequiredTypeDataBits() : int{ @@ -211,6 +217,17 @@ class Block{ } } + private function decodeStateData(int $data) : void{ + $stateBits = $this->getRequiredStateDataBits(); + $reader = new RuntimeDataReader($stateBits, $data); + + $this->describeState($reader); + $readBits = $reader->getOffset(); + if($stateBits !== $readBits){ + throw new \LogicException(get_class($this) . ": Exactly $stateBits bits of state data were provided, but $readBits were read"); + } + } + /** * @internal */ @@ -219,12 +236,7 @@ class Block{ $stateBits = $this->getRequiredStateDataBits(); $reader = new RuntimeDataReader($typeBits + $stateBits, $data); $this->decodeTypeData($reader->readInt($typeBits)); - - $this->describeState($reader); - $readBits = $reader->getOffset() - $typeBits; - if($stateBits !== $readBits){ - throw new \LogicException(get_class($this) . ": Exactly $stateBits bits of state data were provided, but $readBits were read"); - } + $this->decodeStateData($reader->readInt($stateBits)); } /** @@ -243,6 +255,19 @@ class Block{ return $writer->getValue(); } + private function computeStateData() : int{ + $stateBits = $this->getRequiredStateDataBits(); + $writer = new RuntimeDataWriter($stateBits); + + $this->describeState($writer); + $writtenBits = $writer->getOffset(); + if($stateBits !== $writtenBits){ + throw new \LogicException(get_class($this) . ": Exactly $stateBits bits of state data were expected, but $writtenBits were written"); + } + + return $writer->getValue(); + } + /** * @internal */ @@ -251,12 +276,7 @@ class Block{ $stateBits = $this->getRequiredStateDataBits(); $writer = new RuntimeDataWriter($typeBits + $stateBits); $writer->writeInt($typeBits, $this->computeTypeData()); - - $this->describeState($writer); - $writtenBits = $writer->getOffset() - $typeBits; - if($stateBits !== $writtenBits){ - throw new \LogicException(get_class($this) . ": Exactly $stateBits bits of state data were expected, but $writtenBits were written"); - } + $writer->writeInt($stateBits, $this->computeStateData()); return $writer->getValue(); } @@ -269,7 +289,7 @@ class Block{ * The method implementation must NOT use conditional logic to determine which properties are written. It must * always write the same properties in the same order, regardless of the current state of the block. */ - protected function describeType(RuntimeDataDescriber $w) : void{ + public function describeType(RuntimeDataDescriber $w) : void{ //NOOP } diff --git a/src/block/Dirt.php b/src/block/Dirt.php index 900879433..33f3800d7 100644 --- a/src/block/Dirt.php +++ b/src/block/Dirt.php @@ -45,7 +45,7 @@ class Dirt extends Opaque{ parent::__construct($idInfo, $name, $typeInfo); } - protected function describeType(RuntimeDataDescriber $w) : void{ + public function describeType(RuntimeDataDescriber $w) : void{ $w->dirtType($this->dirtType); } diff --git a/src/block/Froglight.php b/src/block/Froglight.php index 13b68e21e..dcd14c900 100644 --- a/src/block/Froglight.php +++ b/src/block/Froglight.php @@ -35,7 +35,7 @@ final class Froglight extends SimplePillar{ parent::__construct($idInfo, $name, $typeInfo); } - protected function describeType(RuntimeDataDescriber $w) : void{ + public function describeType(RuntimeDataDescriber $w) : void{ $w->froglightType($this->froglightType); } diff --git a/src/block/Light.php b/src/block/Light.php index 5ee7281c9..963c00385 100644 --- a/src/block/Light.php +++ b/src/block/Light.php @@ -34,7 +34,7 @@ final class Light extends Flowable{ private int $level = self::MAX_LIGHT_LEVEL; - protected function describeType(RuntimeDataDescriber $w) : void{ + public function describeType(RuntimeDataDescriber $w) : void{ $w->boundedInt(4, self::MIN_LIGHT_LEVEL, self::MAX_LIGHT_LEVEL, $this->level); } diff --git a/src/block/NetherVines.php b/src/block/NetherVines.php index 4a924b2be..d00580624 100644 --- a/src/block/NetherVines.php +++ b/src/block/NetherVines.php @@ -52,7 +52,7 @@ class NetherVines extends Flowable{ parent::__construct($idInfo, $name, $typeInfo); } - public function describeState(RuntimeDataDescriber $w) : void{ + protected function describeState(RuntimeDataDescriber $w) : void{ $w->boundedInt(5, 0, self::MAX_AGE, $this->age); } diff --git a/src/block/RedMushroomBlock.php b/src/block/RedMushroomBlock.php index dfa50e265..07afbfc21 100644 --- a/src/block/RedMushroomBlock.php +++ b/src/block/RedMushroomBlock.php @@ -36,7 +36,7 @@ class RedMushroomBlock extends Opaque{ parent::__construct($idInfo, $name, $typeInfo); } - protected function describeType(RuntimeDataDescriber $w) : void{ + public function describeType(RuntimeDataDescriber $w) : void{ //these blocks always drop as all-cap, but may exist in other forms in the inventory (particularly creative), //so this information needs to be kept in the type info $w->mushroomBlockType($this->mushroomBlockType); diff --git a/src/block/RuntimeBlockStateRegistry.php b/src/block/RuntimeBlockStateRegistry.php index ed3761b72..cdcd4b73a 100644 --- a/src/block/RuntimeBlockStateRegistry.php +++ b/src/block/RuntimeBlockStateRegistry.php @@ -151,18 +151,6 @@ class RuntimeBlockStateRegistry{ } } - /** - * @internal - * Returns the default state of the block type associated with the given type ID. - */ - public function fromTypeId(int $typeId) : Block{ - if(isset($this->typeIndex[$typeId])){ - return clone $this->typeIndex[$typeId]; - } - - throw new \InvalidArgumentException("Block ID $typeId is not registered"); - } - public function fromStateId(int $stateId) : Block{ if($stateId < 0){ throw new \InvalidArgumentException("Block state ID cannot be negative"); @@ -178,22 +166,6 @@ class RuntimeBlockStateRegistry{ return $block; } - /** - * Returns whether a specified block state is already registered in the block factory. - */ - public function isRegistered(int $typeId) : bool{ - $b = $this->typeIndex[$typeId] ?? null; - return $b !== null && !($b instanceof UnknownBlock); - } - - /** - * @return Block[] - * @phpstan-return array - */ - public function getAllKnownTypes() : array{ - return $this->typeIndex; - } - /** * @return Block[] */ diff --git a/src/block/Skull.php b/src/block/Skull.php index 10403ab6b..926c5cc80 100644 --- a/src/block/Skull.php +++ b/src/block/Skull.php @@ -49,7 +49,7 @@ class Skull extends Flowable{ parent::__construct($idInfo, $name, $typeInfo); } - protected function describeType(RuntimeDataDescriber $w) : void{ + public function describeType(RuntimeDataDescriber $w) : void{ $w->skullType($this->skullType); } diff --git a/src/block/Slab.php b/src/block/Slab.php index 4e25d15a4..fa5833d7c 100644 --- a/src/block/Slab.php +++ b/src/block/Slab.php @@ -37,8 +37,8 @@ class Slab extends Transparent{ protected SlabType $slabType; public function __construct(BlockIdentifier $idInfo, string $name, BlockTypeInfo $typeInfo){ - parent::__construct($idInfo, $name . " Slab", $typeInfo); $this->slabType = SlabType::BOTTOM(); + parent::__construct($idInfo, $name . " Slab", $typeInfo); } protected function describeState(RuntimeDataDescriber $w) : void{ diff --git a/src/block/Sponge.php b/src/block/Sponge.php index b4e523ffa..5b283d18b 100644 --- a/src/block/Sponge.php +++ b/src/block/Sponge.php @@ -28,7 +28,7 @@ use pocketmine\data\runtime\RuntimeDataDescriber; class Sponge extends Opaque{ protected bool $wet = false; - protected function describeType(RuntimeDataDescriber $w) : void{ + public function describeType(RuntimeDataDescriber $w) : void{ $w->bool($this->wet); } diff --git a/src/block/TNT.php b/src/block/TNT.php index 7012f7145..d50028f92 100644 --- a/src/block/TNT.php +++ b/src/block/TNT.php @@ -45,7 +45,7 @@ class TNT extends Opaque{ protected bool $unstable = false; //TODO: Usage unclear, seems to be a weird hack in vanilla protected bool $worksUnderwater = false; - protected function describeType(RuntimeDataDescriber $w) : void{ + public function describeType(RuntimeDataDescriber $w) : void{ $w->bool($this->worksUnderwater); } diff --git a/src/block/UnknownBlock.php b/src/block/UnknownBlock.php index 7c48b236f..4523fd7ec 100644 --- a/src/block/UnknownBlock.php +++ b/src/block/UnknownBlock.php @@ -38,7 +38,7 @@ class UnknownBlock extends Transparent{ $this->stateData = $stateData; } - protected function describeType(RuntimeDataDescriber $w) : void{ + public function describeType(RuntimeDataDescriber $w) : void{ //use type instead of state, so we don't lose any information like colour //this might be an improperly registered plugin block $w->int(Block::INTERNAL_STATE_DATA_BITS, $this->stateData); diff --git a/src/block/Wood.php b/src/block/Wood.php index 9a0c36e1d..3fbae40da 100644 --- a/src/block/Wood.php +++ b/src/block/Wood.php @@ -38,7 +38,7 @@ class Wood extends Opaque{ private bool $stripped = false; - protected function describeType(RuntimeDataDescriber $w) : void{ + public function describeType(RuntimeDataDescriber $w) : void{ $w->bool($this->stripped); } diff --git a/src/block/utils/ColoredTrait.php b/src/block/utils/ColoredTrait.php index 42abe64b9..b9a14bee1 100644 --- a/src/block/utils/ColoredTrait.php +++ b/src/block/utils/ColoredTrait.php @@ -31,7 +31,7 @@ trait ColoredTrait{ private $color; /** @see Block::describeType() */ - protected function describeType(RuntimeDataDescriber $w) : void{ + public function describeType(RuntimeDataDescriber $w) : void{ $w->dyeColor($this->color); } diff --git a/src/block/utils/CopperTrait.php b/src/block/utils/CopperTrait.php index ed230c6ba..11c0178f9 100644 --- a/src/block/utils/CopperTrait.php +++ b/src/block/utils/CopperTrait.php @@ -44,7 +44,7 @@ trait CopperTrait{ parent::__construct($identifier, $name, $typeInfo); } - protected function describeType(RuntimeDataDescriber $w) : void{ + public function describeType(RuntimeDataDescriber $w) : void{ $w->copperOxidation($this->oxidation); $w->bool($this->waxed); } diff --git a/src/block/utils/CoralTypeTrait.php b/src/block/utils/CoralTypeTrait.php index d2c96c8f4..4607831c8 100644 --- a/src/block/utils/CoralTypeTrait.php +++ b/src/block/utils/CoralTypeTrait.php @@ -31,7 +31,7 @@ trait CoralTypeTrait{ protected bool $dead = false; /** @see Block::describeType() */ - protected function describeType(RuntimeDataDescriber $w) : void{ + public function describeType(RuntimeDataDescriber $w) : void{ $w->coralType($this->coralType); $w->bool($this->dead); } diff --git a/src/item/ItemBlock.php b/src/item/ItemBlock.php index a7e14b5ce..ccd8793ef 100644 --- a/src/item/ItemBlock.php +++ b/src/item/ItemBlock.php @@ -35,47 +35,29 @@ use pocketmine\data\runtime\RuntimeDataDescriber; * just place wheat crops when used on the ground). */ final class ItemBlock extends Item{ - private int $blockTypeId; - private int $blockTypeData; - - private int $fuelTime; - private bool $fireProof; - private int $maxStackSize; - - public function __construct(Block $block){ + public function __construct( + private Block $block + ){ parent::__construct(ItemIdentifier::fromBlock($block), $block->getName()); - $this->blockTypeId = $block->getTypeId(); - $this->blockTypeData = $block->computeTypeData(); - - $this->fuelTime = $block->getFuelTime(); - $this->fireProof = $block->isFireProofAsItem(); - $this->maxStackSize = $block->getMaxStackSize(); } protected function describeType(RuntimeDataDescriber $w) : void{ - $w->int(Block::INTERNAL_STATE_DATA_BITS, $this->blockTypeData); + $this->block->describeType($w); } public function getBlock(?int $clickedFace = null) : Block{ - //TODO: HACKY MESS, CLEAN IT UP - $factory = RuntimeBlockStateRegistry::getInstance(); - if(!$factory->isRegistered($this->blockTypeId)){ - return VanillaBlocks::AIR(); - } - $blockType = $factory->fromTypeId($this->blockTypeId); - $blockType->decodeTypeData($this->blockTypeData); - return $blockType; + return clone $this->block; } public function getFuelTime() : int{ - return $this->fuelTime; + return $this->block->getFuelTime(); } public function isFireProof() : bool{ - return $this->fireProof; + return $this->block->isFireProofAsItem(); } public function getMaxStackSize() : int{ - return $this->maxStackSize; + return $this->block->getMaxStackSize(); } }