44 use HorizontalFacingTrait;
46 private BellAttachmentType $attachmentType = BellAttachmentType::FLOOR;
49 $w->enum($this->attachmentType);
50 $w->
enum($this->facing);
54 $realFacing = $this->facing->toFacing();
55 if($this->attachmentType === BellAttachmentType::FLOOR){
57 AxisAlignedBB::one()->squashedCopy(Facing::axis($realFacing), 1 / 4)->trimmedCopy(Facing::UP, 3 / 16)
60 if($this->attachmentType === BellAttachmentType::CEILING){
62 AxisAlignedBB::one()->contractedCopy(1 / 4, 0, 1 / 4)->trimmedCopy(Facing::DOWN, 1 / 4)
66 $box = AxisAlignedBB::one()
67 ->squashedCopy(Facing::axis(Facing::rotateY($realFacing,
true)), 1 / 4)
68 ->trimmedCopy(Facing::UP, 1 / 16)
69 ->trimmedCopy(Facing::DOWN, 1 / 4);
72 $this->attachmentType === BellAttachmentType::ONE_WALL ? $box->trimmedCopy($realFacing, 3 / 16) : $box
77 return SupportType::NONE;
80 public function getAttachmentType() : BellAttachmentType{ return $this->attachmentType; }
84 $this->attachmentType = $attachmentType;
88 private function canBeSupportedAt(
Block $block,
Facing $face) : bool{
89 return $block->getAdjacentSupportType($face) !== SupportType::NONE;
93 if(!$this->canBeSupportedAt($blockReplace,
Facing::opposite($face))){
96 if($face === Facing::UP){
98 $this->setFacing(HorizontalFacingOption::fromFacing(Facing::opposite($player->getHorizontalFacing())));
100 $this->setAttachmentType(BellAttachmentType::FLOOR);
101 }elseif($face === Facing::DOWN){
102 $this->setAttachmentType(BellAttachmentType::CEILING);
104 $this->setFacing(HorizontalFacingOption::fromFacing($face));
105 $this->setAttachmentType(
106 $this->canBeSupportedAt($blockReplace, $face) ?
107 BellAttachmentType::TWO_WALLS :
108 BellAttachmentType::ONE_WALL
111 return parent::place($tx, $item, $blockReplace, $blockClicked, $face, $clickVector, $player);
115 foreach(match($this->attachmentType){
116 BellAttachmentType::CEILING => [Facing::UP],
117 BellAttachmentType::FLOOR => [Facing::DOWN],
118 BellAttachmentType::ONE_WALL => [Facing::opposite($this->facing->toFacing())],
119 BellAttachmentType::TWO_WALLS => [$this->facing->toFacing(), Facing::opposite($this->facing->toFacing())]
120 } as $supportBlockDirection){
121 if(!$this->canBeSupportedAt($this, $supportBlockDirection)){
122 $this->position->getWorld()->useBreakOn($this->position);
129 if($player !== null){
130 $faceHit = Facing::opposite($player->getHorizontalFacing());
131 if($this->isValidFaceToRing($faceHit)){
132 $this->ring($faceHit);
141 $faceHit =
Facing::opposite($projectile->getHorizontalFacing());
142 if($this->isValidFaceToRing($faceHit)){
143 $this->ring($faceHit);
147 public function ring(Facing $faceHit) : void{
148 $world = $this->position->getWorld();
149 $world->addSound($this->position,
new BellRingSound());
150 $tile = $world->getTile($this->position);
151 if($tile instanceof TileBell){
152 $world->broadcastPacketToViewers($this->position, $tile->createFakeUpdatePacket($faceHit));
157 return [$this->asItem()];
160 private function isValidFaceToRing(
Facing $faceHit) : bool{
161 return match($this->attachmentType){
162 BellAttachmentType::CEILING =>
true,
163 BellAttachmentType::FLOOR => Facing::axis($faceHit) === Facing::axis($this->facing->toFacing()),
164 BellAttachmentType::ONE_WALL, BellAttachmentType::TWO_WALLS => $faceHit === Facing::rotateY($this->facing->toFacing(),
false) || $faceHit === Facing::rotateY($this->facing->toFacing(),
true),
place(BlockTransaction $tx, Item $item, Block $blockReplace, Block $blockClicked, Facing $face, Vector3 $clickVector, ?Player $player=null)