Stem: implement facing property

fixes #5858

technically speaking, the sideways states for non-fully-grown stems shouldn't exist, but they do in Bedrock, and changing this code to split non-fully-grown stems from fully grown ones would likely require BC breaks.
This was the minimum necessary to achieve the desired functionality.
This commit is contained in:
Dylan K. Taylor 2023-07-13 14:50:02 +01:00
parent 259cc305df
commit dca752c72f
No known key found for this signature in database
GPG Key ID: 8927471A91CAFD3D
4 changed files with 40 additions and 7 deletions

View File

@ -23,6 +23,7 @@ declare(strict_types=1);
namespace pocketmine\block;
use pocketmine\data\runtime\RuntimeDataDescriber;
use pocketmine\event\block\BlockGrowEvent;
use pocketmine\item\Item;
use pocketmine\math\Facing;
@ -30,11 +31,34 @@ use function array_rand;
use function mt_rand;
abstract class Stem extends Crops{
protected int $facing = Facing::UP;
protected function describeBlockOnlyState(RuntimeDataDescriber $w) : void{
parent::describeBlockOnlyState($w);
$w->facingExcept($this->facing, Facing::DOWN);
}
public function getFacing() : int{ return $this->facing; }
/** @return $this */
public function setFacing(int $facing) : self{
if($facing === Facing::DOWN){
throw new \InvalidArgumentException("DOWN is not a valid facing for this block");
}
$this->facing = $facing;
return $this;
}
abstract protected function getPlant() : Block;
public function onNearbyBlockChange() : void{
if($this->facing !== Facing::UP && !$this->getSide($this->facing)->hasSameTypeId($this->getPlant())){
$this->position->getWorld()->setBlock($this->position, $this->setFacing(Facing::UP));
}
}
public function onRandomTick() : void{
if(mt_rand(0, 2) === 1){
if($this->facing === Facing::UP && mt_rand(0, 2) === 1){
$world = $this->position->getWorld();
if($this->age < self::MAX_AGE){
$block = clone $this;
@ -52,11 +76,13 @@ abstract class Stem extends Crops{
}
}
$side = $this->getSide(Facing::HORIZONTAL[array_rand(Facing::HORIZONTAL)]);
$facing = Facing::HORIZONTAL[array_rand(Facing::HORIZONTAL)];
$side = $this->getSide($facing);
if($side->getTypeId() === BlockTypeIds::AIR && $side->getSide(Facing::DOWN)->hasTypeTag(BlockTypeTags::DIRT)){
$ev = new BlockGrowEvent($side, $grow);
$ev->call();
if(!$ev->isCancelled()){
$world->setBlock($this->position, $this->setFacing($facing));
$world->setBlock($side->position, $ev->getNewState());
}
}

View File

@ -236,9 +236,12 @@ final class BlockStateDeserializerHelper{
/** @throws BlockStateDeserializeException */
public static function decodeStem(Stem $block, BlockStateReader $in) : Stem{
//TODO: our stems don't support facings yet (facing_direction)
$in->todo(BlockStateNames::FACING_DIRECTION);
return self::decodeCrops($block, $in);
//In PM, we use Facing::UP to indicate that the stem is not attached to a pumpkin/melon, since this makes the
//most intuitive sense (the stem is pointing at the sky). However, Bedrock uses the DOWN state for this, which
//is absurd, and I refuse to make our API similarly absurd.
$facing = $in->readFacingWithoutUp();
return self::decodeCrops($block, $in)
->setFacing($facing === Facing::DOWN ? Facing::UP : $facing);
}
/** @throws BlockStateDeserializeException */

View File

@ -223,8 +223,12 @@ final class BlockStateSerializerHelper{
}
public static function encodeStem(Stem $block, BlockStateWriter $out) : BlockStateWriter{
//In PM, we use Facing::UP to indicate that the stem is not attached to a pumpkin/melon, since this makes the
//most intuitive sense (the stem is pointing at the sky). However, Bedrock uses the DOWN state for this, which
//is absurd, and I refuse to make our API similarly absurd.
$facing = $block->getFacing();
return self::encodeCrops($block, $out)
->writeHorizontalFacing(Facing::NORTH); //TODO: PM impl doesn't support this yet
->writeFacingWithoutUp($facing === Facing::UP ? Facing::DOWN : $facing);
}
public static function encodeStone(string $type) : BlockStateWriter{

File diff suppressed because one or more lines are too long