24    public const LAYER_CACHE = 0;
 
   25    public const LAYER_BASE = 1;
 
   26    public const LAYER_SPECTATOR = 2;
 
   27    public const LAYER_COMMANDS = 3;
 
   28    public const LAYER_EDITOR = 4;
 
   29    public const LAYER_LOADING_SCREEN = 5;
 
   31    public const ABILITY_BUILD = 0;
 
   32    public const ABILITY_MINE = 1;
 
   33    public const ABILITY_DOORS_AND_SWITCHES = 2; 
 
   34    public const ABILITY_OPEN_CONTAINERS = 3;
 
   35    public const ABILITY_ATTACK_PLAYERS = 4;
 
   36    public const ABILITY_ATTACK_MOBS = 5;
 
   37    public const ABILITY_OPERATOR = 6;
 
   38    public const ABILITY_TELEPORT = 7;
 
   39    public const ABILITY_INVULNERABLE = 8;
 
   40    public const ABILITY_FLYING = 9;
 
   41    public const ABILITY_ALLOW_FLIGHT = 10;
 
   42    public const ABILITY_INFINITE_RESOURCES = 11; 
 
   43    public const ABILITY_LIGHTNING = 12; 
 
   44    private const ABILITY_FLY_SPEED = 13;
 
   45    private const ABILITY_WALK_SPEED = 14;
 
   46    public const ABILITY_MUTED = 15;
 
   47    public const ABILITY_WORLD_BUILDER = 16;
 
   48    public const ABILITY_NO_CLIP = 17;
 
   49    public const ABILITY_PRIVILEGED_BUILDER = 18;
 
   50    public const ABILITY_VERTICAL_FLY_SPEED = 19;
 
   52    public const NUMBER_OF_ABILITIES = 20;
 
   60        private array $boolAbilities,
 
   61        private ?
float $flySpeed,
 
   62        private ?
float $verticalFlySpeed,
 
   63        private ?
float $walkSpeed
 
 
   66    public function getLayerId() : int{ return $this->layerId; }
 
   75    public function getFlySpeed() : ?float{ return $this->flySpeed; }
 
   77    public function getVerticalFlySpeed() : ?float{ return $this->verticalFlySpeed; }
 
   79    public function getWalkSpeed() : ?float{ return $this->walkSpeed; }
 
   81    public static function decode(ByteBufferReader $in) : self{
 
   82        $layerId = LE::readUnsignedShort($in);
 
   83        $setAbilities = LE::readUnsignedInt($in);
 
   84        $setAbilityValues = LE::readUnsignedInt($in);
 
   85        $flySpeed = LE::readFloat($in);
 
   86        $verticalFlySpeed = LE::readFloat($in);
 
   87        $walkSpeed = LE::readFloat($in);
 
   90        for($i = 0; $i < self::NUMBER_OF_ABILITIES; $i++){
 
   91            if($i === self::ABILITY_FLY_SPEED || $i === self::ABILITY_WALK_SPEED){
 
   94            if(($setAbilities & (1 << $i)) !== 0){
 
   95                $boolAbilities[$i] = ($setAbilityValues & (1 << $i)) !== 0;
 
   98        if(($setAbilities & (1 << self::ABILITY_FLY_SPEED)) === 0){
 
   99            if($flySpeed !== 0.0){
 
  100                throw new PacketDecodeException(
"Fly speed should be zero if the layer does not set it");
 
  104        if(($setAbilities & (1 << self::ABILITY_VERTICAL_FLY_SPEED)) === 0){
 
  105            if($verticalFlySpeed !== 0.0){
 
  106                throw new PacketDecodeException(
"Vertical fly speed should be zero if the layer does not set it");
 
  108            $verticalFlySpeed = 
null;
 
  110        if(($setAbilities & (1 << self::ABILITY_WALK_SPEED)) === 0){
 
  111            if($walkSpeed !== 0.0){
 
  112                throw new PacketDecodeException(
"Walk speed should be zero if the layer does not set it");
 
  117        return new self($layerId, $boolAbilities, $flySpeed, $verticalFlySpeed, $walkSpeed);
 
  120    public function encode(ByteBufferWriter $out) : void{
 
  121        LE::writeUnsignedShort($out, $this->layerId);
 
  124        $setAbilityValues = 0;
 
  125        foreach($this->boolAbilities as $ability => $value){
 
  126            $setAbilities |= (1 << $ability);
 
  127            $setAbilityValues |= ($value ? 1 << $ability : 0);
 
  129        if($this->flySpeed !== 
null){
 
  130            $setAbilities |= (1 << self::ABILITY_FLY_SPEED);
 
  132        if($this->verticalFlySpeed !== 
null){
 
  133            $setAbilities |= (1 << self::ABILITY_VERTICAL_FLY_SPEED);
 
  135        if($this->walkSpeed !== 
null){
 
  136            $setAbilities |= (1 << self::ABILITY_WALK_SPEED);
 
  139        LE::writeUnsignedInt($out, $setAbilities);
 
  140        LE::writeUnsignedInt($out, $setAbilityValues);
 
  141        LE::writeFloat($out, $this->flySpeed ?? 0);
 
  142        LE::writeFloat($out, $this->verticalFlySpeed ?? 0);
 
  143        LE::writeFloat($out, $this->walkSpeed ?? 0);