diff --git a/src/permission/DefaultPermissionNames.php b/src/permission/DefaultPermissionNames.php index bb86c134c..b3bf46a8c 100644 --- a/src/permission/DefaultPermissionNames.php +++ b/src/permission/DefaultPermissionNames.php @@ -100,6 +100,7 @@ final class DefaultPermissionNames{ public const GAME_ITEM_DROP = "pocketmine.game.item.drop"; public const GAME_ITEM_PICKUP = "pocketmine.game.item.pickup"; public const GAME_ITEM_USE = "pocketmine.game.item.use"; + public const GAME_NOCOLLISION = "pocketmine.game.nocollision"; public const GAME_PLAYER_ATTACK = "pocketmine.game.player.attack"; public const GAME_PLAYER_INTERACT = "pocketmine.game.player.interact"; public const GROUP_CONSOLE = "pocketmine.group.console"; diff --git a/src/permission/DefaultPermissions.php b/src/permission/DefaultPermissions.php index 650fe1ae9..d370594d5 100644 --- a/src/permission/DefaultPermissions.php +++ b/src/permission/DefaultPermissions.php @@ -120,7 +120,7 @@ abstract class DefaultPermissions{ $survivalRoot = self::registerPermission(new Permission(Names::GROUP_GAMEMODE_SURVIVAL)); $creativeRoot = self::registerPermission(new Permission(Names::GROUP_GAMEMODE_CREATIVE)); $adventureRoot = self::registerPermission(new Permission(Names::GROUP_GAMEMODE_ADVENTURE)); - self::registerPermission(new Permission(Names::GROUP_GAMEMODE_SPECTATOR)); //not currently used, but will be in the future + $spectatorRoot = self::registerPermission(new Permission(Names::GROUP_GAMEMODE_SPECTATOR)); self::registerPermission(new Permission(Names::GAME_BLOCK_INTERACT, "Allows the user to interact with blocks"), [$survivalRoot, $creativeRoot, $adventureRoot]); self::registerPermission(new Permission(Names::GAME_BLOCK_MINE, "Allows the user to mine blocks"), [$survivalRoot, $creativeRoot, $adventureRoot]); @@ -141,5 +141,7 @@ abstract class DefaultPermissions{ self::registerPermission(new Permission(Names::GAME_BLOCK_DELETE, "Allows the user to delete any block without delay, including indestructible blocks"), [$creativeRoot]); self::registerPermission(new Permission(Names::GAME_ITEM_CREATE, "Allows the user to use the creative inventory"), [$creativeRoot]); self::registerPermission(new Permission(Names::GAME_FLIGHT, "Allows the user to toggle flight mode"), [$creativeRoot]); + + self::registerPermission(new Permission(Names::GAME_NOCOLLISION, "Allows the user to pass through blocks"), [$spectatorRoot]); } } diff --git a/src/player/Player.php b/src/player/Player.php index d5ad1744c..ad5fe851c 100644 --- a/src/player/Player.php +++ b/src/player/Player.php @@ -275,7 +275,6 @@ class Player extends Human implements CommandSender, ChunkListener, IPlayer{ //TODO: Abilities protected bool $autoJump = true; - protected bool $blockCollision = true; protected bool $flying = false; /** @phpstan-var positive-int|null */ @@ -481,12 +480,13 @@ class Player extends Human implements CommandSender, ChunkListener, IPlayer{ * Note: Enabling flight mode in conjunction with this is recommended. A non-flying player will simply fall through * the ground into the void. * @see Player::setFlying() + * + * @deprecated This is now controlled by setting a permission, which allows more fine-tuned control. + * @see DefaultPermissionNames::GAME_NOCOLLISION */ public function setHasBlockCollision(bool $value) : void{ - if($this->blockCollision !== $value){ - $this->blockCollision = $value; - $this->getNetworkSession()->syncAbilities($this); - } + $this->setBasePermission(DefaultPermissionNames::GAME_NOCOLLISION, !$value); + $this->getNetworkSession()->syncAbilities($this); } /** @@ -494,7 +494,7 @@ class Player extends Human implements CommandSender, ChunkListener, IPlayer{ * If false, the player can move through any block unobstructed. */ public function hasBlockCollision() : bool{ - return $this->blockCollision; + return !$this->hasPermission(DefaultPermissionNames::GAME_NOCOLLISION); } public function setFlying(bool $value) : void{ @@ -1127,14 +1127,16 @@ class Player extends Human implements CommandSender, ChunkListener, IPlayer{ $this->gamemode = $gameMode; $this->setBasePermission($this->gamemode->getPermissionGroupName(), true); - //TODO: this preserves old behaviour of gamemode changes overriding setAllowFlight - //we should get rid of this when setAllowFlight is removed + + //TODO: this preserves old behaviour of gamemode changes overriding setAllowFlight and setHasBlockCollision + //we should get rid of these when the deprecated setters are removed $this->unsetBasePermission(DefaultPermissionNames::GAME_FLIGHT); + $this->unsetBasePermission(DefaultPermissionNames::GAME_NOCOLLISION); + $this->hungerManager->setEnabled($this->isSurvival()); if($this->isSpectator()){ $this->setFlying(true); - $this->setHasBlockCollision(false); $this->setSilent(); $this->onGround = false; @@ -1145,7 +1147,6 @@ class Player extends Human implements CommandSender, ChunkListener, IPlayer{ if(!$this->hasPermission(DefaultPermissionNames::GAME_FLIGHT)){ $this->setFlying(false); } - $this->setHasBlockCollision(true); $this->setSilent(false); $this->checkGroundState(0, 0, 0, 0, 0, 0); }