mirror of
https://github.com/pmmp/PocketMine-MP.git
synced 2025-08-29 06:25:16 +00:00
Fixed hanging signs placement criteria (#6775)
This commit is contained in:
parent
ac2c07c3fe
commit
db54c481aa
@ -31,4 +31,5 @@ final class BlockTypeTags{
|
||||
public const SAND = self::PREFIX . "sand";
|
||||
public const POTTABLE_PLANTS = self::PREFIX . "pottable";
|
||||
public const FIRE = self::PREFIX . "fire";
|
||||
public const HANGING_SIGN = self::PREFIX . "hanging_sign";
|
||||
}
|
||||
|
@ -25,6 +25,7 @@ namespace pocketmine\block;
|
||||
|
||||
use pocketmine\block\utils\SignLikeRotation;
|
||||
use pocketmine\block\utils\SignLikeRotationTrait;
|
||||
use pocketmine\block\utils\StaticSupportTrait;
|
||||
use pocketmine\item\Item;
|
||||
use pocketmine\math\Facing;
|
||||
use pocketmine\math\Vector3;
|
||||
@ -33,6 +34,7 @@ use pocketmine\world\BlockTransaction;
|
||||
|
||||
final class CeilingCenterHangingSign extends BaseSign implements SignLikeRotation{
|
||||
use SignLikeRotationTrait;
|
||||
use StaticSupportTrait;
|
||||
|
||||
protected function getSupportingFace() : int{
|
||||
return Facing::UP;
|
||||
@ -49,4 +51,11 @@ final class CeilingCenterHangingSign extends BaseSign implements SignLikeRotatio
|
||||
}
|
||||
return parent::place($tx, $item, $blockReplace, $blockClicked, $face, $clickVector, $player);
|
||||
}
|
||||
|
||||
private function canBeSupportedAt(Block $block) : bool{
|
||||
$supportBlock = $block->getSide(Facing::UP);
|
||||
return
|
||||
$supportBlock->getSupportType(Facing::DOWN)->hasCenterSupport() ||
|
||||
$supportBlock->hasTypeTag(BlockTypeTags::HANGING_SIGN);
|
||||
}
|
||||
}
|
||||
|
@ -25,6 +25,7 @@ namespace pocketmine\block;
|
||||
|
||||
use pocketmine\block\utils\HorizontalFacing;
|
||||
use pocketmine\block\utils\HorizontalFacingTrait;
|
||||
use pocketmine\block\utils\SupportType;
|
||||
use pocketmine\item\Item;
|
||||
use pocketmine\math\Facing;
|
||||
use pocketmine\math\Vector3;
|
||||
@ -45,7 +46,23 @@ final class CeilingEdgesHangingSign extends BaseSign implements HorizontalFacing
|
||||
if($player !== null){
|
||||
$this->facing = Facing::opposite($player->getHorizontalFacing());
|
||||
}
|
||||
if(!$this->canBeSupportedAt($blockReplace)){
|
||||
return false;
|
||||
}
|
||||
|
||||
return parent::place($tx, $item, $blockReplace, $blockClicked, $face, $clickVector, $player);
|
||||
}
|
||||
|
||||
public function onNearbyBlockChange() : void{
|
||||
if(!$this->canBeSupportedAt($this)){
|
||||
$this->position->getWorld()->useBreakOn($this->position);
|
||||
}
|
||||
}
|
||||
|
||||
private function canBeSupportedAt(Block $block) : bool{
|
||||
$supportBlock = $block->getSide(Facing::UP);
|
||||
return
|
||||
$supportBlock->getSupportType(Facing::DOWN) === SupportType::FULL ||
|
||||
(($supportBlock instanceof WallHangingSign || $supportBlock instanceof CeilingEdgesHangingSign) && Facing::axis($supportBlock->getFacing()) === Facing::axis($this->facing));
|
||||
}
|
||||
}
|
||||
|
@ -1391,6 +1391,7 @@ final class VanillaBlocks{
|
||||
private static function registerWoodenBlocks() : void{
|
||||
$planksBreakInfo = new Info(BreakInfo::axe(2.0, null, 15.0));
|
||||
$signBreakInfo = new Info(BreakInfo::axe(1.0));
|
||||
$hangingSignBreakInfo = new Info(BreakInfo::axe(1.0), [Tags::HANGING_SIGN]);
|
||||
$logBreakInfo = new Info(BreakInfo::axe(2.0));
|
||||
$woodenDoorBreakInfo = new Info(BreakInfo::axe(3.0, null, 15.0));
|
||||
$woodenButtonBreakInfo = new Info(BreakInfo::axe(0.5));
|
||||
@ -1444,9 +1445,9 @@ final class VanillaBlocks{
|
||||
WoodType::CHERRY => VanillaItems::CHERRY_HANGING_SIGN(...),
|
||||
WoodType::PALE_OAK => VanillaItems::PALE_OAK_HANGING_SIGN(...),
|
||||
};
|
||||
self::register($idName("ceiling_center_hanging_sign"), fn(BID $id) => new CeilingCenterHangingSign($id, $name . " Center Hanging Sign", $signBreakInfo, $woodType, $hangingSignAsItem), TileHangingSign::class);
|
||||
self::register($idName("ceiling_edges_hanging_sign"), fn(BID $id) => new CeilingEdgesHangingSign($id, $name . " Edges Hanging Sign", $signBreakInfo, $woodType, $hangingSignAsItem), TileHangingSign::class);
|
||||
self::register($idName("wall_hanging_sign"), fn(BID $id) => new WallHangingSign($id, $name . " Wall Hanging Sign", $signBreakInfo, $woodType, $hangingSignAsItem), TileHangingSign::class);
|
||||
self::register($idName("ceiling_center_hanging_sign"), fn(BID $id) => new CeilingCenterHangingSign($id, $name . " Center Hanging Sign", $hangingSignBreakInfo, $woodType, $hangingSignAsItem), TileHangingSign::class);
|
||||
self::register($idName("ceiling_edges_hanging_sign"), fn(BID $id) => new CeilingEdgesHangingSign($id, $name . " Edges Hanging Sign", $hangingSignBreakInfo, $woodType, $hangingSignAsItem), TileHangingSign::class);
|
||||
self::register($idName("wall_hanging_sign"), fn(BID $id) => new WallHangingSign($id, $name . " Wall Hanging Sign", $hangingSignBreakInfo, $woodType, $hangingSignAsItem), TileHangingSign::class);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -25,6 +25,7 @@ namespace pocketmine\block;
|
||||
|
||||
use pocketmine\block\utils\HorizontalFacing;
|
||||
use pocketmine\block\utils\HorizontalFacingTrait;
|
||||
use pocketmine\block\utils\SupportType;
|
||||
use pocketmine\item\Item;
|
||||
use pocketmine\math\Axis;
|
||||
use pocketmine\math\AxisAlignedBB;
|
||||
@ -50,16 +51,31 @@ final class WallHangingSign extends BaseSign implements HorizontalFacing{
|
||||
}
|
||||
|
||||
public function place(BlockTransaction $tx, Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, ?Player $player = null) : bool{
|
||||
if(Facing::axis($face) === Axis::Y){
|
||||
if($player === null){
|
||||
return false;
|
||||
}
|
||||
$attachFace = Facing::axis($face) === Axis::Y ? Facing::rotateY($player->getHorizontalFacing(), clockwise: true) : $face;
|
||||
|
||||
if($this->canBeSupportedAt($blockReplace->getSide($attachFace), $attachFace)){
|
||||
$direction = $attachFace;
|
||||
}elseif($this->canBeSupportedAt($blockReplace->getSide($opposite = Facing::opposite($attachFace)), $opposite)){
|
||||
$direction = $opposite;
|
||||
}else{
|
||||
return false;
|
||||
}
|
||||
|
||||
$this->facing = Facing::rotateY($face, clockwise: true);
|
||||
$this->facing = Facing::rotateY(Facing::opposite($direction), clockwise: true);
|
||||
//the front should always face the player if possible
|
||||
if($player !== null && $this->facing === $player->getHorizontalFacing()){
|
||||
if($this->facing === $player->getHorizontalFacing()){
|
||||
$this->facing = Facing::opposite($this->facing);
|
||||
}
|
||||
|
||||
return parent::place($tx, $item, $blockReplace, $blockClicked, $face, $clickVector, $player);
|
||||
}
|
||||
|
||||
private function canBeSupportedAt(Block $block, int $face) : bool{
|
||||
return
|
||||
($block instanceof WallHangingSign && Facing::axis(Facing::rotateY($block->getFacing(), clockwise: true)) === Facing::axis($face)) ||
|
||||
$block->getSupportType(Facing::opposite($face)) === SupportType::FULL;
|
||||
}
|
||||
}
|
||||
|
@ -24,9 +24,13 @@ declare(strict_types=1);
|
||||
namespace pocketmine\item;
|
||||
|
||||
use pocketmine\block\Block;
|
||||
use pocketmine\block\CeilingCenterHangingSign;
|
||||
use pocketmine\block\CeilingEdgesHangingSign;
|
||||
use pocketmine\block\utils\SupportType;
|
||||
use pocketmine\block\WallHangingSign;
|
||||
use pocketmine\math\Facing;
|
||||
use pocketmine\math\Vector3;
|
||||
use pocketmine\player\Player;
|
||||
|
||||
final class HangingSign extends Item{
|
||||
|
||||
@ -40,13 +44,26 @@ final class HangingSign extends Item{
|
||||
parent::__construct($identifier, $name);
|
||||
}
|
||||
|
||||
public function getPlacementBlock(Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector) : Block{
|
||||
public function getPlacementBlock(?Player $player, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector) : Block{
|
||||
//we don't verify valid placement conditions here, only decide which block to return
|
||||
$result = $face === Facing::DOWN ?
|
||||
$blockReplace->getSide(Facing::UP)->getSupportType(Facing::DOWN) === SupportType::CENTER ?
|
||||
$this->centerPointCeilingVariant :
|
||||
$this->edgePointCeilingVariant
|
||||
: $this->wallVariant;
|
||||
if($face === Facing::DOWN){
|
||||
if($player !== null && $player->isSneaking()){
|
||||
return clone $this->centerPointCeilingVariant;
|
||||
}
|
||||
|
||||
//we select the center variant when support is edge/wall sign with perpendicular player facing,
|
||||
//support is a center sign itself, or support provides center support.
|
||||
//otherwise use the edge variant.
|
||||
$support = $blockReplace->getSide(Facing::UP);
|
||||
$result =
|
||||
(($support instanceof CeilingEdgesHangingSign || $support instanceof WallHangingSign) && ($player === null || Facing::axis($player->getHorizontalFacing()) !== Facing::axis($support->getFacing()))) ||
|
||||
$support instanceof CeilingCenterHangingSign ||
|
||||
$support->getSupportType(Facing::DOWN) === SupportType::CENTER ?
|
||||
$this->centerPointCeilingVariant :
|
||||
$this->edgePointCeilingVariant;
|
||||
}else{
|
||||
$result = $this->wallVariant;
|
||||
}
|
||||
return clone $result;
|
||||
}
|
||||
|
||||
|
@ -485,7 +485,7 @@ class Item implements \JsonSerializable{
|
||||
return $this->getBlock()->canBePlaced();
|
||||
}
|
||||
|
||||
public function getPlacementBlock(Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector) : Block{
|
||||
public function getPlacementBlock(?Player $player, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector) : Block{
|
||||
return $this->getBlock($face);
|
||||
}
|
||||
|
||||
|
@ -2298,7 +2298,7 @@ class World implements ChunkManager{
|
||||
if($item->isNull() || !$item->canBePlaced()){
|
||||
return false;
|
||||
}
|
||||
$hand = $item->getPlacementBlock($blockReplace, $blockClicked, $face, $clickVector);
|
||||
$hand = $item->getPlacementBlock($player, $blockReplace, $blockClicked, $face, $clickVector);
|
||||
$hand->position($this, $blockReplace->getPosition()->x, $blockReplace->getPosition()->y, $blockReplace->getPosition()->z);
|
||||
|
||||
if($hand->canBePlacedAt($blockClicked, $clickVector, $face, true)){
|
||||
|
Loading…
x
Reference in New Issue
Block a user