shape = StairShape::STRAIGHT(); parent::__construct($idInfo, $name, $breakInfo); } protected function writeStateToMeta() : int{ return BlockDataSerializer::write5MinusHorizontalFacing($this->facing) | ($this->upsideDown ? BlockLegacyMetadata::STAIR_FLAG_UPSIDE_DOWN : 0); } public function readStateFromData(int $id, int $stateMeta) : void{ $this->facing = BlockDataSerializer::read5MinusHorizontalFacing($stateMeta); $this->upsideDown = ($stateMeta & BlockLegacyMetadata::STAIR_FLAG_UPSIDE_DOWN) !== 0; } public function getStateBitmask() : int{ return 0b111; } public function readStateFromWorld() : void{ parent::readStateFromWorld(); $clockwise = Facing::rotateY($this->facing, true); if(($backFacing = $this->getPossibleCornerFacing(false)) !== null){ $this->shape = $backFacing === $clockwise ? StairShape::OUTER_RIGHT() : StairShape::OUTER_LEFT(); }elseif(($frontFacing = $this->getPossibleCornerFacing(true)) !== null){ $this->shape = $frontFacing === $clockwise ? StairShape::INNER_RIGHT() : StairShape::INNER_LEFT(); }else{ $this->shape = StairShape::STRAIGHT(); } } protected function recalculateCollisionBoxes() : array{ $topStepFace = $this->upsideDown ? Facing::DOWN : Facing::UP; $bbs = [ AxisAlignedBB::one()->trim($topStepFace, 0.5) ]; $topStep = AxisAlignedBB::one() ->trim(Facing::opposite($topStepFace), 0.5) ->trim(Facing::opposite($this->facing), 0.5); if($this->shape->equals(StairShape::OUTER_LEFT()) or $this->shape->equals(StairShape::OUTER_RIGHT())){ $topStep->trim(Facing::rotateY($this->facing, $this->shape->equals(StairShape::OUTER_LEFT())), 0.5); }elseif($this->shape->equals(StairShape::INNER_LEFT()) or $this->shape->equals(StairShape::INNER_RIGHT())){ //add an extra cube $bbs[] = AxisAlignedBB::one() ->trim(Facing::opposite($topStepFace), 0.5) ->trim($this->facing, 0.5) //avoid overlapping with main step ->trim(Facing::rotateY($this->facing, $this->shape->equals(StairShape::INNER_LEFT())), 0.5); } $bbs[] = $topStep; return $bbs; } private function getPossibleCornerFacing(bool $oppositeFacing) : ?int{ $side = $this->getSide($oppositeFacing ? Facing::opposite($this->facing) : $this->facing); return ( $side instanceof Stair and $side->upsideDown === $this->upsideDown and Facing::axis($side->facing) !== Facing::axis($this->facing) //perpendicular ) ? $side->facing : null; } public function place(BlockTransaction $tx, Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ if($player !== null){ $this->facing = $player->getHorizontalFacing(); } $this->upsideDown = (($clickVector->y > 0.5 and $face !== Facing::UP) or $face === Facing::DOWN); return parent::place($tx, $item, $blockReplace, $blockClicked, $face, $clickVector, $player); } }