mirror of
https://github.com/pmmp/PocketMine-MP.git
synced 2025-04-22 00:33:59 +00:00
Improved Beds, fixed bed tiles not getting removed for other halves
relates to #880
This commit is contained in:
parent
253db40a11
commit
2d626d1d90
@ -38,6 +38,8 @@ use pocketmine\tile\Tile;
|
||||
use pocketmine\utils\TextFormat;
|
||||
|
||||
class Bed extends Transparent{
|
||||
const BITFLAG_OCCUPIED = 0x04;
|
||||
const BITFLAG_HEAD = 0x08;
|
||||
|
||||
protected $id = self::BED_BLOCK;
|
||||
|
||||
@ -64,8 +66,62 @@ class Bed extends Transparent{
|
||||
);
|
||||
}
|
||||
|
||||
public function onActivate(Item $item, Player $player = null){
|
||||
public function isHeadPart() : bool{
|
||||
return ($this->meta & self::BITFLAG_HEAD) !== 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function isOccupied() : bool{
|
||||
return ($this->meta & self::BITFLAG_OCCUPIED) !== 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $meta
|
||||
* @param bool $isHead
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public static function getOtherHalfSide(int $meta, bool $isHead = false) : int{
|
||||
$rotation = $meta & 0x03;
|
||||
$side = -1;
|
||||
|
||||
switch($rotation){
|
||||
case 0x00: //South
|
||||
$side = Vector3::SIDE_SOUTH;
|
||||
break;
|
||||
case 0x01: //West
|
||||
$side = Vector3::SIDE_WEST;
|
||||
break;
|
||||
case 0x02: //North
|
||||
$side = Vector3::SIDE_NORTH;
|
||||
break;
|
||||
case 0x03: //East
|
||||
$side = Vector3::SIDE_EAST;
|
||||
break;
|
||||
}
|
||||
|
||||
if($isHead){
|
||||
$side = Vector3::getOppositeSide($side);
|
||||
}
|
||||
|
||||
return $side;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Bed|null
|
||||
*/
|
||||
public function getOtherHalf(){
|
||||
$other = $this->getSide(self::getOtherHalfSide($this->meta, $this->isHeadPart()));
|
||||
if($other instanceof Bed and $other->getId() === $this->getId() and $other->isHeadPart() !== $this->isHeadPart() and (($other->getDamage() & 0x03) === ($this->getDamage() & 0x03))){
|
||||
return $other;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public function onActivate(Item $item, Player $player = null){
|
||||
$time = $this->getLevel()->getTime() % Level::TIME_FULL;
|
||||
|
||||
$isNight = ($time >= Level::TIME_NIGHT and $time < Level::TIME_SUNRISE);
|
||||
@ -75,31 +131,19 @@ class Bed extends Transparent{
|
||||
return true;
|
||||
}
|
||||
|
||||
$blockNorth = $this->getSide(2); //Gets the blocks around them
|
||||
$blockSouth = $this->getSide(3);
|
||||
$blockEast = $this->getSide(5);
|
||||
$blockWest = $this->getSide(4);
|
||||
if(($this->meta & 0x08) === 0x08){ //This is the Top part of bed
|
||||
$b = $this;
|
||||
}else{ //Bottom Part of Bed
|
||||
if($blockNorth->getId() === $this->id and ($blockNorth->meta & 0x08) === 0x08){
|
||||
$b = $blockNorth;
|
||||
}elseif($blockSouth->getId() === $this->id and ($blockSouth->meta & 0x08) === 0x08){
|
||||
$b = $blockSouth;
|
||||
}elseif($blockEast->getId() === $this->id and ($blockEast->meta & 0x08) === 0x08){
|
||||
$b = $blockEast;
|
||||
}elseif($blockWest->getId() === $this->id and ($blockWest->meta & 0x08) === 0x08){
|
||||
$b = $blockWest;
|
||||
}else{
|
||||
if($player instanceof Player){
|
||||
$player->sendMessage(TextFormat::GRAY . "This bed is incomplete");
|
||||
}
|
||||
|
||||
return true;
|
||||
$other = $this->getOtherHalf();
|
||||
if($other === null){
|
||||
if($player instanceof Player){
|
||||
$player->sendMessage(TextFormat::GRAY . "This bed is incomplete");
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
$b = ($this->isHeadPart() ? $this : $other);
|
||||
|
||||
if($player instanceof Player and $player->sleepOn($b) === false){
|
||||
//TODO: change this to use the meta bitflags
|
||||
$player->sendMessage(new TranslationContainer(TextFormat::GRAY . "%tile.bed.occupied"));
|
||||
}
|
||||
|
||||
@ -108,20 +152,12 @@ class Bed extends Transparent{
|
||||
|
||||
public function place(Item $item, Block $block, Block $target, $face, $fx, $fy, $fz, Player $player = null){
|
||||
$down = $this->getSide(Vector3::SIDE_DOWN);
|
||||
if($down->isTransparent() === false){
|
||||
$faces = [
|
||||
0 => 3,
|
||||
1 => 4,
|
||||
2 => 2,
|
||||
3 => 5,
|
||||
];
|
||||
$d = $player instanceof Player ? $player->getDirection() : 0;
|
||||
$next = $this->getSide($faces[($d + 3) % 4]);
|
||||
$downNext = $next->getSide(Vector3::SIDE_DOWN);
|
||||
if($next->canBeReplaced() === true and $downNext->isTransparent() === false){
|
||||
$meta = (($d + 3) % 4) & 0x03;
|
||||
if(!$down->isTransparent()){
|
||||
$meta = (($player instanceof Player ? $player->getDirection() : 0) - 1) & 0x03;
|
||||
$next = $this->getSide(self::getOtherHalfSide($meta));
|
||||
if($next->canBeReplaced() === true and !$next->getSide(Vector3::SIDE_DOWN)->isTransparent()){
|
||||
$this->getLevel()->setBlock($block, Block::get($this->id, $meta), true, true);
|
||||
$this->getLevel()->setBlock($next, Block::get($this->id, $meta | 0x08), true, true);
|
||||
$this->getLevel()->setBlock($next, Block::get($this->id, $meta | self::BITFLAG_HEAD), true, true);
|
||||
|
||||
$nbt = new CompoundTag("", [
|
||||
new StringTag("id", Tile::BED),
|
||||
@ -146,47 +182,28 @@ class Bed extends Transparent{
|
||||
}
|
||||
|
||||
public function onBreak(Item $item){
|
||||
$blockNorth = $this->getSide(2); //Gets the blocks around them
|
||||
$blockSouth = $this->getSide(3);
|
||||
$blockEast = $this->getSide(5);
|
||||
$blockWest = $this->getSide(4);
|
||||
|
||||
if(($this->meta & 0x08) === 0x08){ //This is the Top part of bed
|
||||
if($blockNorth->getId() === $this->id and $blockNorth->meta !== 0x08){ //Checks if the block ID and meta are right
|
||||
$this->getLevel()->setBlock($blockNorth, new Air(), true, true);
|
||||
}elseif($blockSouth->getId() === $this->id and $blockSouth->meta !== 0x08){
|
||||
$this->getLevel()->setBlock($blockSouth, new Air(), true, true);
|
||||
}elseif($blockEast->getId() === $this->id and $blockEast->meta !== 0x08){
|
||||
$this->getLevel()->setBlock($blockEast, new Air(), true, true);
|
||||
}elseif($blockWest->getId() === $this->id and $blockWest->meta !== 0x08){
|
||||
$this->getLevel()->setBlock($blockWest, new Air(), true, true);
|
||||
}
|
||||
}else{ //Bottom Part of Bed
|
||||
if($blockNorth->getId() === $this->id and ($blockNorth->meta & 0x08) === 0x08){
|
||||
$this->getLevel()->setBlock($blockNorth, new Air(), true, true);
|
||||
}elseif($blockSouth->getId() === $this->id and ($blockSouth->meta & 0x08) === 0x08){
|
||||
$this->getLevel()->setBlock($blockSouth, new Air(), true, true);
|
||||
}elseif($blockEast->getId() === $this->id and ($blockEast->meta & 0x08) === 0x08){
|
||||
$this->getLevel()->setBlock($blockEast, new Air(), true, true);
|
||||
}elseif($blockWest->getId() === $this->id and ($blockWest->meta & 0x08) === 0x08){
|
||||
$this->getLevel()->setBlock($blockWest, new Air(), true, true);
|
||||
}
|
||||
$this->getLevel()->setBlock($this, Block::get(Block::AIR), true, true);
|
||||
if(($other = $this->getOtherHalf()) !== null){
|
||||
$this->getLevel()->useBreakOn($other); //make sure tiles get removed
|
||||
}
|
||||
$this->getLevel()->setBlock($this, new Air(), true, true);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public function getDrops(Item $item){
|
||||
$tile = $this->getLevel()->getTile($this);
|
||||
if($tile instanceof TileBed){
|
||||
return [
|
||||
[Item::BED, $tile->getColor(), 1]
|
||||
];
|
||||
if($this->isHeadPart()){
|
||||
$tile = $this->getLevel()->getTile($this);
|
||||
if($tile instanceof TileBed){
|
||||
return [
|
||||
[Item::BED, $tile->getColor(), 1]
|
||||
];
|
||||
}else{
|
||||
return [
|
||||
[Item::BED, 14, 1] //Red
|
||||
];
|
||||
}
|
||||
}else{
|
||||
return [
|
||||
[Item::BED, 14, 1] //Red
|
||||
];
|
||||
return [];
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user