From c2b3f7cd7f286c38a3dfeb8c13af6c2729a99650 Mon Sep 17 00:00:00 2001 From: Shoghi Cervantes Date: Wed, 29 Apr 2015 12:29:59 +0200 Subject: [PATCH] Noclip in spectator mode, changed chunk format --- src/pocketmine/Player.php | 55 ++++++++++++------- .../level/format/anvil/ChunkRequestTask.php | 3 +- .../level/format/generic/BaseChunk.php | 16 ++++-- .../level/format/generic/BaseFullChunk.php | 36 +++++++----- .../level/format/leveldb/LevelDB.php | 2 + .../level/format/mcregion/McRegion.php | 2 + 6 files changed, 75 insertions(+), 39 deletions(-) diff --git a/src/pocketmine/Player.php b/src/pocketmine/Player.php index beb63c078..06e6eed3d 100644 --- a/src/pocketmine/Player.php +++ b/src/pocketmine/Player.php @@ -219,7 +219,6 @@ class Player extends Human implements CommandSender, InventoryHolder, IPlayer{ protected $allowFlight = false; - private $needACK = []; private $batchedPackets = []; @@ -311,7 +310,7 @@ class Player extends Human implements CommandSender, InventoryHolder, IPlayer{ * @param Player $player */ public function spawnTo(Player $player){ - if($this->spawned === true and $player->spawned === true and $this->dead !== true and $player->dead !== true and $player->getLevel() === $this->level and $player->canSee($this)){ + if($this->spawned === true and $player->spawned === true and $this->dead !== true and $player->dead !== true and $player->getLevel() === $this->level and $player->canSee($this) and !$this->isSpectator()){ parent::spawnTo($player); } } @@ -1000,6 +999,12 @@ class Player extends Human implements CommandSender, InventoryHolder, IPlayer{ $this->allowFlight = $this->isCreative(); + if($this->isSpectator()){ + $this->despawnFromAll(); + }else{ + $this->spawnToAll(); + } + $this->namedtag->playerGameType = new Int("playerGameType", $this->gamemode); $spawnPosition = $this->getSpawn(); @@ -1048,7 +1053,7 @@ class Player extends Human implements CommandSender, InventoryHolder, IPlayer{ 0x00000020 nametags_visible 0x00000040 auto_jump 0x00000080 allow_fly - 0x00000100 ? + 0x00000100 noclip 0x00000200 ? 0x00000400 ? 0x00000800 ? @@ -1090,6 +1095,10 @@ class Player extends Human implements CommandSender, InventoryHolder, IPlayer{ $flags |= 0x80; } + if($this->isSpectator()){ + $flags |= 0x100; + } + $pk = new AdventureSettingsPacket(); $pk->flags = $flags; $this->dataPacket($pk->setChannel(Network::CHANNEL_PRIORITY)); @@ -1103,6 +1112,10 @@ class Player extends Human implements CommandSender, InventoryHolder, IPlayer{ return ($this->gamemode & 0x01) > 0; } + public function isSpectator(){ + return $this->gamemode === 3; + } + public function isAdventure(){ return ($this->gamemode & 0x02) > 0; } @@ -1276,7 +1289,9 @@ class Player extends Human implements CommandSender, InventoryHolder, IPlayer{ } } - $this->checkNearEntities($tickDiff); + if(!$this->isSpectator()){ + $this->checkNearEntities($tickDiff); + } $this->speed = $from->subtract($to); }elseif($distanceSquared == 0){ @@ -1333,25 +1348,27 @@ class Player extends Human implements CommandSender, InventoryHolder, IPlayer{ $this->processMovement($tickDiff); - $this->entityBaseTick($tickDiff); + if(!$this->isSpectator()){ + $this->entityBaseTick($tickDiff); - if($this->onGround){ - $this->inAirTicks = 0; - }else{ - if(!$this->allowFlight and $this->inAirTicks > 10 and !$this->isSleeping() and $this->getDataProperty(self::DATA_NO_AI) !== 1){ - $expectedVelocity = (-$this->gravity) / $this->drag - ((-$this->gravity) / $this->drag) * exp(-$this->drag * ($this->inAirTicks - 5)); - $diff = sqrt(abs($this->speed->y - $expectedVelocity)); + if($this->onGround){ + $this->inAirTicks = 0; + }else{ + if(!$this->allowFlight and $this->inAirTicks > 10 and !$this->isSleeping() and $this->getDataProperty(self::DATA_NO_AI) !== 1){ + $expectedVelocity = (-$this->gravity) / $this->drag - ((-$this->gravity) / $this->drag) * exp(-$this->drag * ($this->inAirTicks - 5)); + $diff = sqrt(abs($this->speed->y - $expectedVelocity)); - if(!$this->hasEffect(Effect::JUMP) and $diff > 0.6 and $expectedVelocity < $this->speed->y and !$this->server->getAllowFlight()){ - if($this->inAirTicks < 100){ - $this->setMotion(new Vector3(0, $expectedVelocity, 0)); - }elseif($this->kick("Flying is not enabled on this server")){ - return false; + if(!$this->hasEffect(Effect::JUMP) and $diff > 0.6 and $expectedVelocity < $this->speed->y and !$this->server->getAllowFlight()){ + if($this->inAirTicks < 100){ + $this->setMotion(new Vector3(0, $expectedVelocity, 0)); + }elseif($this->kick("Flying is not enabled on this server")){ + return false; + } } } - } - ++$this->inAirTicks; + ++$this->inAirTicks; + } } } @@ -1517,7 +1534,7 @@ class Player extends Human implements CommandSender, InventoryHolder, IPlayer{ $this->gamemode = $this->server->getGamemode(); $nbt->playerGameType = new Int("playerGameType", $this->gamemode); } - + $this->allowFlight = $this->isCreative(); diff --git a/src/pocketmine/level/format/anvil/ChunkRequestTask.php b/src/pocketmine/level/format/anvil/ChunkRequestTask.php index 4c32cfcf9..39ea4e1d0 100644 --- a/src/pocketmine/level/format/anvil/ChunkRequestTask.php +++ b/src/pocketmine/level/format/anvil/ChunkRequestTask.php @@ -82,9 +82,10 @@ class ChunkRequestTask extends AsyncTask{ } } + $heightmap = pack("C*", ...$chunk->getHeightMapArray()); $biomeColors = pack("N*", ...$chunk->getBiomeColorArray()); - $ordered = $orderedIds . $orderedData . $orderedSkyLight . $orderedLight . $biomeColors . $this->tiles; + $ordered = $orderedIds . $orderedData . $orderedSkyLight . $orderedLight . $heightmap . $biomeColors . $this->tiles; $this->setResult($ordered, false); } diff --git a/src/pocketmine/level/format/generic/BaseChunk.php b/src/pocketmine/level/format/generic/BaseChunk.php index 74be57f9b..6ac6f45f8 100644 --- a/src/pocketmine/level/format/generic/BaseChunk.php +++ b/src/pocketmine/level/format/generic/BaseChunk.php @@ -62,18 +62,22 @@ abstract class BaseChunk extends BaseFullChunk implements Chunk{ } } - if(strlen($biomeIds) === 256){ - $this->biomeIds = $biomeIds; - }else{ - $this->biomeIds = str_repeat("\x01", 256); - } - if(count($biomeColors) === 256){ $this->biomeColors = $biomeColors; }else{ $this->biomeColors = array_fill(0, 256, Binary::readInt("\x00\x85\xb2\x4a")); } + + + if(strlen($biomeIds) !== 256){ + $biomeIds = str_repeat("\x01", 256); + } + + for($i = 0; $i < 256; ++$i){ + $this->biomeColors[$i] = ($this->biomeColors[$i] & 0xFFFFFF) | (ord($biomeIds{$i}) << 24); + } + if(count($heightMap) === 256){ $this->heightMap = $heightMap; }else{ diff --git a/src/pocketmine/level/format/generic/BaseFullChunk.php b/src/pocketmine/level/format/generic/BaseFullChunk.php index 0d20105c0..d7de59c0a 100644 --- a/src/pocketmine/level/format/generic/BaseFullChunk.php +++ b/src/pocketmine/level/format/generic/BaseFullChunk.php @@ -40,9 +40,6 @@ abstract class BaseFullChunk implements FullChunk{ /** @var Tile[] */ protected $tileList = []; - /** @var string */ - protected $biomeIds; - /** @var int[256] */ protected $biomeColors; @@ -92,18 +89,20 @@ abstract class BaseFullChunk implements FullChunk{ $this->skyLight = $skyLight; $this->blockLight = $blockLight; - if(strlen($biomeIds) === 256){ - $this->biomeIds = $biomeIds; - }else{ - $this->biomeIds = str_repeat("\x01", 256); - } - if(count($biomeColors) === 256){ $this->biomeColors = $biomeColors; }else{ $this->biomeColors = array_fill(0, 256, Binary::readInt("\x00\x85\xb2\x4a")); } + if(strlen($biomeIds) !== 256){ + $biomeIds = str_repeat("\x01", 256); + } + + for($i = 0; $i < 256; ++$i){ + $this->biomeColors[$i] = ($this->biomeColors[$i] & 0xFFFFFF) | (ord($biomeIds{$i}) << 24); + } + if(count($heightMap) === 256){ $this->heightMap = $heightMap; }else{ @@ -161,9 +160,16 @@ abstract class BaseFullChunk implements FullChunk{ $this->getProvider()->getLevel()->timings->syncChunkLoadTileEntitiesTimer->stopTiming(); + for($z = 0; $z < 16; ++$z){ + for($x = 0; $x < 16; ++$x){ + $this->setHeightMap($x, $z, $this->getHighestBlockAt($x, $z)); + } + } + $this->NBTentities = null; $this->NBTtiles = null; $this->hasChanged = false; + } } @@ -204,12 +210,12 @@ abstract class BaseFullChunk implements FullChunk{ } public function getBiomeId($x, $z){ - return ord($this->biomeIds{($z << 4) + $x}); + return ($this->biomeColors[($z << 4) + $x] & 0xFF000000) >> 24; } public function setBiomeId($x, $z, $biomeId){ $this->hasChanged = true; - $this->biomeIds{($z << 4) + $x} = chr($biomeId); + $this->biomeColors[($z << 4) + $x] = ($this->biomeColors[($z << 4) + $x] & 0xFFFFFF) | ($biomeId << 24); } public function getBiomeColor($x, $z){ @@ -220,7 +226,7 @@ abstract class BaseFullChunk implements FullChunk{ public function setBiomeColor($x, $z, $R, $G, $B){ $this->hasChanged = true; - $this->biomeColors[($z << 4) + $x] = 0 | (($R & 0xFF) << 16) | (($G & 0xFF) << 8) | ($B & 0xFF); + $this->biomeColors[($z << 4) + $x] = ($this->biomeColors[($z << 4) + $x] & 0xFF000000) | (($R & 0xFF) << 16) | (($G & 0xFF) << 8) | ($B & 0xFF); } public function getHeightMap($x, $z){ @@ -338,7 +344,11 @@ abstract class BaseFullChunk implements FullChunk{ } public function getBiomeIdArray(){ - return $this->biomeIds; + $ids = ""; + foreach($this->biomeColors as $d){ + $ids .= chr(($d & 0xFF000000) >> 24); + } + return $ids; } public function getBiomeColorArray(){ diff --git a/src/pocketmine/level/format/leveldb/LevelDB.php b/src/pocketmine/level/format/leveldb/LevelDB.php index 91e323b69..2aca23916 100644 --- a/src/pocketmine/level/format/leveldb/LevelDB.php +++ b/src/pocketmine/level/format/leveldb/LevelDB.php @@ -146,12 +146,14 @@ class LevelDB extends BaseLevelProvider{ } } + $heightmap = pack("C*", ...$chunk->getHeightMapArray()); $biomeColors = pack("N*", ...$chunk->getBiomeColorArray()); $ordered = $chunk->getBlockIdArray() . $chunk->getBlockDataArray() . $chunk->getBlockSkyLightArray() . $chunk->getBlockLightArray() . + $heightmap . $biomeColors . $tiles; diff --git a/src/pocketmine/level/format/mcregion/McRegion.php b/src/pocketmine/level/format/mcregion/McRegion.php index f1d87fb9f..49779af6e 100644 --- a/src/pocketmine/level/format/mcregion/McRegion.php +++ b/src/pocketmine/level/format/mcregion/McRegion.php @@ -128,12 +128,14 @@ class McRegion extends BaseLevelProvider{ } } + $heightmap = pack("C*", ...$chunk->getHeightMapArray()); $biomeColors = pack("N*", ...$chunk->getBiomeColorArray()); $ordered = $chunk->getBlockIdArray() . $chunk->getBlockDataArray() . $chunk->getBlockSkyLightArray() . $chunk->getBlockLightArray() . + $heightmap . $biomeColors . $tiles;