diff --git a/src/block/BaseBanner.php b/src/block/BaseBanner.php index 5b3f9acce..400b8a78e 100644 --- a/src/block/BaseBanner.php +++ b/src/block/BaseBanner.php @@ -112,7 +112,14 @@ abstract class BaseBanner extends Transparent{ return SupportType::NONE(); } + private function canBeSupportedBy(Block $block) : bool{ + return $block->isSolid(); + } + public function place(BlockTransaction $tx, Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ + if(!$this->canBeSupportedBy($blockReplace->getSide($this->getSupportingFace()))){ + return false; + } if($item instanceof ItemBanner){ $this->color = $item->getColor(); $this->setPatterns($item->getPatterns()); @@ -124,7 +131,7 @@ abstract class BaseBanner extends Transparent{ abstract protected function getSupportingFace() : int; public function onNearbyBlockChange() : void{ - if($this->getSide($this->getSupportingFace())->getId() === BlockLegacyIds::AIR){ + if(!$this->canBeSupportedBy($this->getSide($this->getSupportingFace()))){ $this->position->getWorld()->useBreakOn($this->position); } } diff --git a/src/block/Bell.php b/src/block/Bell.php index 70c78d027..00a53a9be 100644 --- a/src/block/Bell.php +++ b/src/block/Bell.php @@ -114,14 +114,13 @@ final class Bell extends Transparent{ return $this; } - private function canBeSupportedBy(Block $block) : bool{ - //TODO: this isn't the actual logic, but it's the closest approximation we can support for now - return $block->isSolid(); + private function canBeSupportedBy(Block $block, int $face) : bool{ + return !$block->getSupportType($face)->equals(SupportType::NONE()); } public function place(BlockTransaction $tx, Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ if($face === Facing::UP){ - if(!$this->canBeSupportedBy($tx->fetchBlock($this->position->down()))){ + if(!$this->canBeSupportedBy($tx->fetchBlock($this->position->down()), Facing::UP)){ return false; } if($player !== null){ @@ -129,18 +128,18 @@ final class Bell extends Transparent{ } $this->setAttachmentType(BellAttachmentType::FLOOR()); }elseif($face === Facing::DOWN){ - if(!$this->canBeSupportedBy($tx->fetchBlock($this->position->up()))){ + if(!$this->canBeSupportedBy($tx->fetchBlock($this->position->up()), Facing::DOWN)){ return false; } $this->setAttachmentType(BellAttachmentType::CEILING()); }else{ $this->setFacing($face); - if($this->canBeSupportedBy($tx->fetchBlock($this->position->getSide(Facing::opposite($face))))){ + if($this->canBeSupportedBy($tx->fetchBlock($this->position->getSide(Facing::opposite($face))), $face)){ $this->setAttachmentType(BellAttachmentType::ONE_WALL()); }else{ return false; } - if($this->canBeSupportedBy($tx->fetchBlock($this->position->getSide($face)))){ + if($this->canBeSupportedBy($tx->fetchBlock($this->position->getSide($face)), Facing::opposite($face))){ $this->setAttachmentType(BellAttachmentType::TWO_WALLS()); } } @@ -149,10 +148,10 @@ final class Bell extends Transparent{ public function onNearbyBlockChange() : void{ if( - ($this->attachmentType->equals(BellAttachmentType::CEILING()) && !$this->canBeSupportedBy($this->getSide(Facing::UP))) || - ($this->attachmentType->equals(BellAttachmentType::FLOOR()) && !$this->canBeSupportedBy($this->getSide(Facing::DOWN))) || - ($this->attachmentType->equals(BellAttachmentType::ONE_WALL()) && !$this->canBeSupportedBy($this->getSide(Facing::opposite($this->facing)))) || - ($this->attachmentType->equals(BellAttachmentType::TWO_WALLS()) && (!$this->canBeSupportedBy($this->getSide($this->facing)) || !$this->canBeSupportedBy($this->getSide(Facing::opposite($this->facing))))) + ($this->attachmentType->equals(BellAttachmentType::CEILING()) && !$this->canBeSupportedBy($this->getSide(Facing::UP), Facing::DOWN)) || + ($this->attachmentType->equals(BellAttachmentType::FLOOR()) && !$this->canBeSupportedBy($this->getSide(Facing::DOWN), Facing::UP)) || + ($this->attachmentType->equals(BellAttachmentType::ONE_WALL()) && !$this->canBeSupportedBy($this->getSide(Facing::opposite($this->facing)), $this->facing)) || + ($this->attachmentType->equals(BellAttachmentType::TWO_WALLS()) && (!$this->canBeSupportedBy($this->getSide($this->facing), Facing::opposite($this->facing)) || !$this->canBeSupportedBy($this->getSide(Facing::opposite($this->facing)), $this->facing))) ){ $this->position->getWorld()->useBreakOn($this->position); } @@ -161,21 +160,20 @@ final class Bell extends Transparent{ public function onInteract(Item $item, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ if($player !== null){ $faceHit = Facing::opposite($player->getHorizontalFacing()); - if($this->attachmentType->equals(BellAttachmentType::CEILING())){ - $this->ring($faceHit); - } - if($this->attachmentType->equals(BellAttachmentType::FLOOR()) && Facing::axis($faceHit) === Facing::axis($this->facing)){ - $this->ring($faceHit); - } if( - ($this->attachmentType->equals(BellAttachmentType::ONE_WALL()) || $this->attachmentType->equals(BellAttachmentType::TWO_WALLS())) && - ($faceHit === Facing::rotateY($this->facing, false) || $faceHit === Facing::rotateY($this->facing, true)) + $this->attachmentType->equals(BellAttachmentType::CEILING()) || + ($this->attachmentType->equals(BellAttachmentType::FLOOR()) && Facing::axis($faceHit) === Facing::axis($this->facing)) || + ( + ($this->attachmentType->equals(BellAttachmentType::ONE_WALL()) || $this->attachmentType->equals(BellAttachmentType::TWO_WALLS())) && + ($faceHit === Facing::rotateY($this->facing, false) || $faceHit === Facing::rotateY($this->facing, true)) + ) ){ $this->ring($faceHit); + return true; } } - return true; + return false; } public function ring(int $faceHit) : void{ diff --git a/src/block/Button.php b/src/block/Button.php index c447ddb8d..f86d8a579 100644 --- a/src/block/Button.php +++ b/src/block/Button.php @@ -61,7 +61,7 @@ abstract class Button extends Flowable{ } public function place(BlockTransaction $tx, Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ - if($this->canBeSupportedBy($blockClicked, $face)){ + if($this->canBeSupportedBy($blockReplace->getSide(Facing::opposite($face)), $face)){ $this->facing = $face; return parent::place($tx, $item, $blockReplace, $blockClicked, $face, $clickVector, $player); } diff --git a/src/block/ItemFrame.php b/src/block/ItemFrame.php index 8df62c72f..7a224c47b 100644 --- a/src/block/ItemFrame.php +++ b/src/block/ItemFrame.php @@ -175,7 +175,7 @@ class ItemFrame extends Flowable{ } public function place(BlockTransaction $tx, Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ - if($face === Facing::DOWN || $face === Facing::UP || !$blockClicked->isSolid()){ + if($face === Facing::DOWN || $face === Facing::UP || !$blockReplace->getSide(Facing::opposite($face))->isSolid()){ return false; } diff --git a/src/block/Ladder.php b/src/block/Ladder.php index fcf2be061..ccedb33bd 100644 --- a/src/block/Ladder.php +++ b/src/block/Ladder.php @@ -70,7 +70,7 @@ class Ladder extends Transparent{ } public function place(BlockTransaction $tx, Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ - if($this->canBeSupportedBy($blockClicked, $face) && Facing::axis($face) !== Axis::Y){ + if($this->canBeSupportedBy($blockReplace->getSide(Facing::opposite($face)), $face) && Facing::axis($face) !== Axis::Y){ $this->facing = $face; return parent::place($tx, $item, $blockReplace, $blockClicked, $face, $clickVector, $player); } diff --git a/src/block/Lever.php b/src/block/Lever.php index beec393b7..01512007b 100644 --- a/src/block/Lever.php +++ b/src/block/Lever.php @@ -95,7 +95,7 @@ class Lever extends Flowable{ } public function place(BlockTransaction $tx, Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ - if(!$this->canBeSupportedBy($blockClicked, $face)){ + if(!$this->canBeSupportedBy($blockReplace->getSide(Facing::opposite($face)), $face)){ return false; } diff --git a/src/block/PressurePlate.php b/src/block/PressurePlate.php index 5610b4e1a..7f9403b74 100644 --- a/src/block/PressurePlate.php +++ b/src/block/PressurePlate.php @@ -45,7 +45,7 @@ abstract class PressurePlate extends Transparent{ } public function place(BlockTransaction $tx, Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ - if($this->canBeSupportedBy($blockClicked)){ + if($this->canBeSupportedBy($blockReplace->getSide(Facing::DOWN))){ return parent::place($tx, $item, $blockReplace, $blockClicked, $face, $clickVector, $player); } return false; @@ -55,5 +55,11 @@ abstract class PressurePlate extends Transparent{ return !$block->getSupportType(Facing::UP)->equals(SupportType::NONE()); } + public function onNearbyBlockChange() : void{ + if(!$this->canBeSupportedBy($this->getSide(Facing::DOWN))){ + $this->position->getWorld()->useBreakOn($this->position); + } + } + //TODO } diff --git a/src/block/Torch.php b/src/block/Torch.php index ded081bcc..768c21223 100644 --- a/src/block/Torch.php +++ b/src/block/Torch.php @@ -65,7 +65,6 @@ class Torch extends Flowable{ } public function onNearbyBlockChange() : void{ - $below = $this->getSide(Facing::DOWN); $face = Facing::opposite($this->facing); if(!$this->canBeSupportedBy($this->getSide($face), $this->facing)){ @@ -74,10 +73,7 @@ class Torch extends Flowable{ } public function place(BlockTransaction $tx, Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ - if($blockClicked->canBeReplaced() && $this->canBeSupportedBy($blockClicked->getSide(Facing::DOWN), Facing::UP)){ - $this->facing = Facing::UP; - return parent::place($tx, $item, $blockReplace, $blockClicked, $face, $clickVector, $player); - }elseif($face !== Facing::DOWN && $this->canBeSupportedBy($blockClicked, $face)){ + if($face !== Facing::DOWN && $this->canBeSupportedBy($blockReplace->getSide(Facing::opposite($face)), $face)){ $this->facing = $face; return parent::place($tx, $item, $blockReplace, $blockClicked, $face, $clickVector, $player); }else{ diff --git a/src/block/Vine.php b/src/block/Vine.php index 9159315da..80943dc7c 100644 --- a/src/block/Vine.php +++ b/src/block/Vine.php @@ -116,7 +116,7 @@ class Vine extends Flowable{ } public function place(BlockTransaction $tx, Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ - if(!$blockClicked->isFullCube() || Facing::axis($face) === Axis::Y){ + if(!$blockReplace->getSide(Facing::opposite($face))->isFullCube() || Facing::axis($face) === Axis::Y){ return false; } diff --git a/src/block/WallCoralFan.php b/src/block/WallCoralFan.php index ee0dcc35a..fe8dc40a8 100644 --- a/src/block/WallCoralFan.php +++ b/src/block/WallCoralFan.php @@ -113,7 +113,7 @@ final class WallCoralFan extends BaseCoral{ public function place(BlockTransaction $tx, Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ $axis = Facing::axis($face); - if(($axis !== Axis::X && $axis !== Axis::Z) || !$this->canBeSupportedBy($blockClicked, $face)){ + if(($axis !== Axis::X && $axis !== Axis::Z) || !$this->canBeSupportedBy($blockReplace->getSide(Facing::opposite($face)), $face)){ return false; } $this->facing = $face; diff --git a/src/block/WaterLily.php b/src/block/WaterLily.php index 39b3c8cee..8263330f6 100644 --- a/src/block/WaterLily.php +++ b/src/block/WaterLily.php @@ -39,19 +39,23 @@ class WaterLily extends Flowable{ return [AxisAlignedBB::one()->contract(1 / 16, 0, 1 / 16)->trim(Facing::UP, 63 / 64)]; } - public function place(BlockTransaction $tx, Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ - if($blockClicked instanceof Water){ - $up = $blockClicked->getSide(Facing::UP); - if($up->canBeReplaced()){ - return parent::place($tx, $item, $up, $blockClicked, $face, $clickVector, $player); - } - } + public function canBePlacedAt(Block $blockReplace, Vector3 $clickVector, int $face, bool $isClickedBlock) : bool{ + return !$blockReplace instanceof Water && parent::canBePlacedAt($blockReplace, $clickVector, $face, $isClickedBlock); + } - return false; + private function canBeSupportedBy(Block $block) : bool{ + return $block instanceof Water; + } + + public function place(BlockTransaction $tx, Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ + if(!$this->canBeSupportedBy($blockReplace->getSide(Facing::DOWN))){ + return false; + } + return parent::place($tx, $item, $blockReplace, $blockClicked, $face, $clickVector, $player); } public function onNearbyBlockChange() : void{ - if(!($this->getSide(Facing::DOWN) instanceof Water)){ + if(!$this->canBeSupportedBy($this->getSide(Facing::DOWN))){ $this->position->getWorld()->useBreakOn($this->position); } } diff --git a/src/world/World.php b/src/world/World.php index c20fb0d00..f5e51b799 100644 --- a/src/world/World.php +++ b/src/world/World.php @@ -60,6 +60,7 @@ use pocketmine\item\StringToItemParser; use pocketmine\item\VanillaItems; use pocketmine\lang\KnownTranslationFactory; use pocketmine\math\AxisAlignedBB; +use pocketmine\math\Facing; use pocketmine\math\Vector3; use pocketmine\nbt\tag\IntTag; use pocketmine\nbt\tag\StringTag; @@ -1994,6 +1995,10 @@ class World implements ChunkManager{ if($hand->canBePlacedAt($blockClicked, $clickVector, $face, true)){ $blockReplace = $blockClicked; + //TODO: while this mimics the vanilla behaviour with replaceable blocks, we should really pass some other + //value like NULL and let place() deal with it. This will look like a bug to anyone who doesn't know about + //the vanilla behaviour. + $face = Facing::UP; $hand->position($this, $blockReplace->getPosition()->x, $blockReplace->getPosition()->y, $blockReplace->getPosition()->z); }elseif(!$hand->canBePlacedAt($blockReplace, $clickVector, $face, false)){ return false;