mirror of
https://github.com/pmmp/PocketMine-MP.git
synced 2025-04-21 08:17:34 +00:00
Use occupied bitflag and added distance check for beds
must be < 2 blocks from either half of the bed
This commit is contained in:
parent
2d626d1d90
commit
8957dbf08e
@ -24,6 +24,7 @@ declare(strict_types=1);
|
||||
namespace pocketmine;
|
||||
|
||||
use pocketmine\block\Air;
|
||||
use pocketmine\block\Bed;
|
||||
use pocketmine\block\Block;
|
||||
use pocketmine\command\Command;
|
||||
use pocketmine\command\CommandSender;
|
||||
@ -250,7 +251,7 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{
|
||||
protected $iusername;
|
||||
protected $displayName;
|
||||
protected $startAction = -1;
|
||||
/** @var Vector3 */
|
||||
/** @var Vector3|null */
|
||||
protected $sleeping = null;
|
||||
protected $clientID = null;
|
||||
|
||||
@ -1125,19 +1126,17 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{
|
||||
return false;
|
||||
}
|
||||
|
||||
foreach($this->level->getNearbyEntities($this->boundingBox->grow(2, 1, 2), $this) as $p){
|
||||
if($p instanceof Player){
|
||||
if($p->sleeping !== null and $pos->distance($p->sleeping) <= 0.1){
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
$b = $this->level->getBlock($pos);
|
||||
|
||||
$this->server->getPluginManager()->callEvent($ev = new PlayerBedEnterEvent($this, $this->level->getBlock($pos)));
|
||||
$this->server->getPluginManager()->callEvent($ev = new PlayerBedEnterEvent($this, $b));
|
||||
if($ev->isCancelled()){
|
||||
return false;
|
||||
}
|
||||
|
||||
if($b instanceof Bed){
|
||||
$b->setOccupied();
|
||||
}
|
||||
|
||||
$this->sleeping = clone $pos;
|
||||
|
||||
$this->setDataProperty(self::DATA_PLAYER_BED_POSITION, self::DATA_TYPE_POS, [$pos->x, $pos->y, $pos->z]);
|
||||
@ -1174,7 +1173,11 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{
|
||||
|
||||
public function stopSleep(){
|
||||
if($this->sleeping instanceof Vector3){
|
||||
$this->server->getPluginManager()->callEvent($ev = new PlayerBedLeaveEvent($this, $this->level->getBlock($this->sleeping)));
|
||||
$b = $this->level->getBlock($this->sleeping);
|
||||
if($b instanceof Bed){
|
||||
$b->setOccupied(false);
|
||||
}
|
||||
$this->server->getPluginManager()->callEvent($ev = new PlayerBedLeaveEvent($this, $b));
|
||||
|
||||
$this->sleeping = null;
|
||||
$this->setDataProperty(self::DATA_PLAYER_BED_POSITION, self::DATA_TYPE_POS, [0, 0, 0]);
|
||||
@ -3409,6 +3412,7 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{
|
||||
*/
|
||||
final public function close($message = "", $reason = "generic reason", $notify = true){
|
||||
if($this->connected and !$this->closed){
|
||||
|
||||
try{
|
||||
if($notify and strlen((string) $reason) > 0){
|
||||
$pk = new DisconnectPacket();
|
||||
@ -3422,6 +3426,8 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{
|
||||
$this->server->getPluginManager()->unsubscribeFromPermission(Server::BROADCAST_CHANNEL_USERS, $this);
|
||||
$this->server->getPluginManager()->unsubscribeFromPermission(Server::BROADCAST_CHANNEL_ADMINISTRATIVE, $this);
|
||||
|
||||
$this->stopSleep();
|
||||
|
||||
if($this->joined){
|
||||
try{
|
||||
$this->save();
|
||||
|
@ -77,6 +77,20 @@ class Bed extends Transparent{
|
||||
return ($this->meta & self::BITFLAG_OCCUPIED) !== 0;
|
||||
}
|
||||
|
||||
public function setOccupied(bool $occupied = true){
|
||||
if($occupied){
|
||||
$this->meta |= self::BITFLAG_OCCUPIED;
|
||||
}else{
|
||||
$this->meta &= ~self::BITFLAG_OCCUPIED;
|
||||
}
|
||||
|
||||
$this->getLevel()->setBlock($this, $this, false, false);
|
||||
|
||||
if(($other = $this->getOtherHalf()) !== null and !$other->isOccupied()){
|
||||
$other->setOccupied($occupied);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $meta
|
||||
* @param bool $isHead
|
||||
@ -122,32 +136,40 @@ class Bed extends Transparent{
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
if($player instanceof Player and !$isNight){
|
||||
$player->sendMessage(new TranslationContainer(TextFormat::GRAY . "%tile.bed.noSleep"));
|
||||
return true;
|
||||
}
|
||||
|
||||
$other = $this->getOtherHalf();
|
||||
if($other === null){
|
||||
if($player instanceof Player){
|
||||
if($player !== null){
|
||||
$other = $this->getOtherHalf();
|
||||
if($other === null){
|
||||
$player->sendMessage(TextFormat::GRAY . "This bed is incomplete");
|
||||
|
||||
return true;
|
||||
}elseif($player->distanceSquared($this) > 4 and $player->distanceSquared($other) > 4){
|
||||
//MCPE doesn't have messages for bed too far away
|
||||
return true;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
$time = $this->getLevel()->getTime() % Level::TIME_FULL;
|
||||
|
||||
$b = ($this->isHeadPart() ? $this : $other);
|
||||
$isNight = ($time >= Level::TIME_NIGHT and $time < Level::TIME_SUNRISE);
|
||||
|
||||
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"));
|
||||
if(!$isNight){
|
||||
$player->sendMessage(new TranslationContainer(TextFormat::GRAY . "%tile.bed.noSleep"));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
$b = ($this->isHeadPart() ? $this : $other);
|
||||
|
||||
if($b->isOccupied()){
|
||||
$player->sendMessage(new TranslationContainer(TextFormat::GRAY . "%tile.bed.occupied"));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
$player->sleepOn($b);
|
||||
}
|
||||
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
public function place(Item $item, Block $block, Block $target, $face, $fx, $fy, $fz, Player $player = null){
|
||||
|
Loading…
x
Reference in New Issue
Block a user