43    use HorizontalFacingTrait;
 
   45    private BellAttachmentType $attachmentType = BellAttachmentType::FLOOR;
 
   48        $w->enum($this->attachmentType);
 
   49        $w->horizontalFacing($this->facing);
 
 
   53        if($this->attachmentType === BellAttachmentType::FLOOR){
 
   55                AxisAlignedBB::one()->squash(Facing::axis($this->facing), 1 / 4)->trim(Facing::UP, 3 / 16)
 
   58        if($this->attachmentType === BellAttachmentType::CEILING){
 
   60                AxisAlignedBB::one()->contract(1 / 4, 0, 1 / 4)->trim(Facing::DOWN, 1 / 4)
 
   64        $box = AxisAlignedBB::one()
 
   65            ->squash(Facing::axis(Facing::rotateY($this->facing, 
true)), 1 / 4)
 
   66            ->trim(Facing::UP, 1 / 16)
 
   67            ->trim(Facing::DOWN, 1 / 4);
 
   70            $this->attachmentType === BellAttachmentType::ONE_WALL ? $box->trim($this->facing, 3 / 16) : $box
 
 
   75        return SupportType::NONE;
 
 
   78    public function getAttachmentType() : BellAttachmentType{ return $this->attachmentType; }
 
   82        $this->attachmentType = $attachmentType;
 
 
   86    private function canBeSupportedAt(
Block $block, 
int $face) : bool{
 
   87        return $block->getAdjacentSupportType($face) !== SupportType::NONE;
 
   91        if(!$this->canBeSupportedAt($blockReplace, 
Facing::opposite($face))){
 
   94        if($face === Facing::UP){
 
   96                $this->setFacing(Facing::opposite($player->getHorizontalFacing()));
 
   98            $this->setAttachmentType(BellAttachmentType::FLOOR);
 
   99        }elseif($face === Facing::DOWN){
 
  100            $this->setAttachmentType(BellAttachmentType::CEILING);
 
  102            $this->setFacing($face);
 
  103            $this->setAttachmentType(
 
  104                $this->canBeSupportedAt($blockReplace, $face) ?
 
  105                    BellAttachmentType::TWO_WALLS :
 
  106                    BellAttachmentType::ONE_WALL
 
  109        return parent::place($tx, $item, $blockReplace, $blockClicked, $face, $clickVector, $player);
 
 
  113        foreach(match($this->attachmentType){
 
  114            BellAttachmentType::CEILING => [Facing::UP],
 
  115            BellAttachmentType::FLOOR => [Facing::DOWN],
 
  116            BellAttachmentType::ONE_WALL => [Facing::opposite($this->facing)],
 
  117            BellAttachmentType::TWO_WALLS => [$this->facing, Facing::opposite($this->facing)]
 
  118        } as $supportBlockDirection){
 
  119            if(!$this->canBeSupportedAt($this, $supportBlockDirection)){
 
  120                $this->position->getWorld()->useBreakOn($this->position);
 
 
  127        if($player !== null){
 
  128            $faceHit = Facing::opposite($player->getHorizontalFacing());
 
  129            if($this->isValidFaceToRing($faceHit)){
 
  130                $this->ring($faceHit);
 
 
  139        $faceHit = 
Facing::opposite($projectile->getHorizontalFacing());
 
  140        if($this->isValidFaceToRing($faceHit)){
 
  141            $this->ring($faceHit);
 
 
  145    public function ring(
int $faceHit) : void{
 
  146        $world = $this->position->getWorld();
 
  147        $world->addSound($this->position, 
new BellRingSound());
 
  148        $tile = $world->getTile($this->position);
 
  149        if($tile instanceof TileBell){
 
  150            $world->broadcastPacketToViewers($this->position, $tile->createFakeUpdatePacket($faceHit));
 
  155        return [$this->asItem()];
 
 
  158    private function isValidFaceToRing(
int $faceHit) : bool{
 
  159        return match($this->attachmentType){
 
  160            BellAttachmentType::CEILING => 
true,
 
  161            BellAttachmentType::FLOOR => Facing::axis($faceHit) === Facing::axis($this->facing),
 
  162            BellAttachmentType::ONE_WALL, BellAttachmentType::TWO_WALLS => $faceHit === Facing::rotateY($this->facing, 
false) || $faceHit === Facing::rotateY($this->facing, 
true),
 
 
place(BlockTransaction $tx, Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, ?Player $player=null)