mirror of
https://github.com/pmmp/PocketMine-MP.git
synced 2025-06-12 06:25:32 +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;
|
use pocketmine\utils\TextFormat;
|
||||||
|
|
||||||
class Bed extends Transparent{
|
class Bed extends Transparent{
|
||||||
|
const BITFLAG_OCCUPIED = 0x04;
|
||||||
|
const BITFLAG_HEAD = 0x08;
|
||||||
|
|
||||||
protected $id = self::BED_BLOCK;
|
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;
|
$time = $this->getLevel()->getTime() % Level::TIME_FULL;
|
||||||
|
|
||||||
$isNight = ($time >= Level::TIME_NIGHT and $time < Level::TIME_SUNRISE);
|
$isNight = ($time >= Level::TIME_NIGHT and $time < Level::TIME_SUNRISE);
|
||||||
@ -75,31 +131,19 @@ class Bed extends Transparent{
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
$blockNorth = $this->getSide(2); //Gets the blocks around them
|
$other = $this->getOtherHalf();
|
||||||
$blockSouth = $this->getSide(3);
|
if($other === null){
|
||||||
$blockEast = $this->getSide(5);
|
if($player instanceof Player){
|
||||||
$blockWest = $this->getSide(4);
|
$player->sendMessage(TextFormat::GRAY . "This bed is incomplete");
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$b = ($this->isHeadPart() ? $this : $other);
|
||||||
|
|
||||||
if($player instanceof Player and $player->sleepOn($b) === false){
|
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"));
|
$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){
|
public function place(Item $item, Block $block, Block $target, $face, $fx, $fy, $fz, Player $player = null){
|
||||||
$down = $this->getSide(Vector3::SIDE_DOWN);
|
$down = $this->getSide(Vector3::SIDE_DOWN);
|
||||||
if($down->isTransparent() === false){
|
if(!$down->isTransparent()){
|
||||||
$faces = [
|
$meta = (($player instanceof Player ? $player->getDirection() : 0) - 1) & 0x03;
|
||||||
0 => 3,
|
$next = $this->getSide(self::getOtherHalfSide($meta));
|
||||||
1 => 4,
|
if($next->canBeReplaced() === true and !$next->getSide(Vector3::SIDE_DOWN)->isTransparent()){
|
||||||
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;
|
|
||||||
$this->getLevel()->setBlock($block, Block::get($this->id, $meta), true, true);
|
$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("", [
|
$nbt = new CompoundTag("", [
|
||||||
new StringTag("id", Tile::BED),
|
new StringTag("id", Tile::BED),
|
||||||
@ -146,47 +182,28 @@ class Bed extends Transparent{
|
|||||||
}
|
}
|
||||||
|
|
||||||
public function onBreak(Item $item){
|
public function onBreak(Item $item){
|
||||||
$blockNorth = $this->getSide(2); //Gets the blocks around them
|
$this->getLevel()->setBlock($this, Block::get(Block::AIR), true, true);
|
||||||
$blockSouth = $this->getSide(3);
|
if(($other = $this->getOtherHalf()) !== null){
|
||||||
$blockEast = $this->getSide(5);
|
$this->getLevel()->useBreakOn($other); //make sure tiles get removed
|
||||||
$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, new Air(), true, true);
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getDrops(Item $item){
|
public function getDrops(Item $item){
|
||||||
$tile = $this->getLevel()->getTile($this);
|
if($this->isHeadPart()){
|
||||||
if($tile instanceof TileBed){
|
$tile = $this->getLevel()->getTile($this);
|
||||||
return [
|
if($tile instanceof TileBed){
|
||||||
[Item::BED, $tile->getColor(), 1]
|
return [
|
||||||
];
|
[Item::BED, $tile->getColor(), 1]
|
||||||
|
];
|
||||||
|
}else{
|
||||||
|
return [
|
||||||
|
[Item::BED, 14, 1] //Red
|
||||||
|
];
|
||||||
|
}
|
||||||
}else{
|
}else{
|
||||||
return [
|
return [];
|
||||||
[Item::BED, 14, 1] //Red
|
|
||||||
];
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user