diff --git a/src/network/mcpe/NetworkSession.php b/src/network/mcpe/NetworkSession.php index c93ee50b1..25035c4c7 100644 --- a/src/network/mcpe/NetworkSession.php +++ b/src/network/mcpe/NetworkSession.php @@ -1039,7 +1039,7 @@ class NetworkSession{ AbilitiesLayer::ABILITY_NO_CLIP => !$for->hasBlockCollision(), AbilitiesLayer::ABILITY_OPERATOR => $isOp, AbilitiesLayer::ABILITY_TELEPORT => $for->hasPermission(DefaultPermissionNames::COMMAND_TELEPORT_SELF), - AbilitiesLayer::ABILITY_INVULNERABLE => $for->isCreative(), + AbilitiesLayer::ABILITY_INVULNERABLE => $for->hasPermission(DefaultPermissionNames::GAME_INVULNERABLE), AbilitiesLayer::ABILITY_MUTED => !$for->hasPermission(DefaultPermissionNames::GAME_CHAT), AbilitiesLayer::ABILITY_WORLD_BUILDER => false, AbilitiesLayer::ABILITY_INFINITE_RESOURCES => !$for->hasFiniteResources(), diff --git a/src/permission/DefaultPermissionNames.php b/src/permission/DefaultPermissionNames.php index ba986a489..ef6a73cdf 100644 --- a/src/permission/DefaultPermissionNames.php +++ b/src/permission/DefaultPermissionNames.php @@ -97,6 +97,7 @@ final class DefaultPermissionNames{ public const GAME_FLIGHT = "pocketmine.game.flight"; public const GAME_ITEM_BYPASS_CANDESTROY = "pocketmine.game.item.bypass.candestroy"; public const GAME_ITEM_BYPASS_CANPLACEON = "pocketmine.game.item.bypass.canplaceon"; + public const GAME_INVULNERABLE = "pocketmine.game.invulnerable"; public const GAME_ITEM_CREATE = "pocketmine.game.item.create"; public const GAME_ITEM_DROP = "pocketmine.game.item.drop"; public const GAME_ITEM_PICKUP = "pocketmine.game.item.pickup"; diff --git a/src/permission/DefaultPermissions.php b/src/permission/DefaultPermissions.php index 36cba3b77..57503af9c 100644 --- a/src/permission/DefaultPermissions.php +++ b/src/permission/DefaultPermissions.php @@ -144,5 +144,6 @@ abstract class DefaultPermissions{ 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]); + self::registerPermission(new Permission(Names::GAME_INVULNERABLE, "Allows the user to ignore all incoming damage (except suicide)"), [$creativeRoot, $spectatorRoot]); } } diff --git a/src/player/Player.php b/src/player/Player.php index ae3251582..208980d63 100644 --- a/src/player/Player.php +++ b/src/player/Player.php @@ -1454,7 +1454,7 @@ class Player extends Human implements CommandSender, ChunkListener, IPlayer{ $this->entityBaseTick($tickDiff); Timings::$entityBaseTick->stopTiming(); - if($this->isCreative() && $this->fireTicks > 1){ + if($this->hasPermission(DefaultPermissionNames::GAME_INVULNERABLE) && $this->fireTicks > 1){ $this->fireTicks = 1; } @@ -1475,7 +1475,7 @@ class Player extends Human implements CommandSender, ChunkListener, IPlayer{ } public function canBreathe() : bool{ - return $this->isCreative() || parent::canBreathe(); + return $this->hasPermission(DefaultPermissionNames::GAME_INVULNERABLE) || parent::canBreathe(); } /** @@ -2518,7 +2518,7 @@ class Player extends Human implements CommandSender, ChunkListener, IPlayer{ return; } - if($this->isCreative() + if($this->hasPermission(DefaultPermissionNames::GAME_INVULNERABLE) && $source->getCause() !== EntityDamageEvent::CAUSE_SUICIDE ){ $source->cancel();