Support changing gamemode in GUI and fixed spectator flight controls

This commit is contained in:
Dylan K. Taylor 2016-10-12 15:55:34 +01:00
parent a45e232829
commit d6fcc59a49
2 changed files with 34 additions and 7 deletions

View File

@ -23,6 +23,7 @@ namespace pocketmine;
use pocketmine\block\Air; use pocketmine\block\Air;
use pocketmine\block\Block; use pocketmine\block\Block;
use pocketmine\command\Command;
use pocketmine\command\CommandSender; use pocketmine\command\CommandSender;
use pocketmine\entity\Arrow; use pocketmine\entity\Arrow;
use pocketmine\entity\Effect; use pocketmine\entity\Effect;
@ -1080,13 +1081,19 @@ class Player extends Human implements CommandSender, InventoryHolder, ChunkLoade
* *
* @return bool * @return bool
*/ */
public function setGamemode($gm){ public function setGamemode($gm, $client = false){
if($gm < 0 or $gm > 3 or $this->gamemode === $gm){ if($gm < 0 or $gm > 3 or $this->gamemode === $gm){
return false; return false;
} }
$this->server->getPluginManager()->callEvent($ev = new PlayerGameModeChangeEvent($this, (int) $gm)); $this->server->getPluginManager()->callEvent($ev = new PlayerGameModeChangeEvent($this, (int) $gm));
if($ev->isCancelled()){ if($ev->isCancelled()){
if($client){ //gamemode change by client in the GUI
$pk = new SetPlayerGameTypePacket();
$pk->gamemode = $this->gamemode & 0x01;
$this->dataPacket($pk);
$this->sendSettings();
}
return false; return false;
} }
@ -1096,6 +1103,11 @@ class Player extends Human implements CommandSender, InventoryHolder, ChunkLoade
if($this->isSpectator()){ if($this->isSpectator()){
$this->isFlying = true; $this->isFlying = true;
$this->despawnFromAll(); $this->despawnFromAll();
// Client automatically turns off flight controls when on the ground.
// A combination of this hack and a new AdventureSettings flag FINALLY
// fixes spectator flight controls. Thank @robske110 for this hack.
$this->teleport($this->temporalVector->setComponents($this->x, $this->y + 0.1, $this->z));
}else{ }else{
if($this->isSurvival()){ if($this->isSurvival()){
$this->isFlying = false; $this->isFlying = false;
@ -1106,11 +1118,14 @@ class Player extends Human implements CommandSender, InventoryHolder, ChunkLoade
$this->resetFallDistance(); $this->resetFallDistance();
$this->namedtag->playerGameType = new IntTag("playerGameType", $this->gamemode); $this->namedtag->playerGameType = new IntTag("playerGameType", $this->gamemode);
if(!$client){ //Gamemode changed by server, do not send for client changes
$pk = new SetPlayerGameTypePacket(); $pk = new SetPlayerGameTypePacket();
$pk->gamemode = $this->gamemode & 0x01; $pk->gamemode = $this->gamemode & 0x01;
$this->dataPacket($pk); $this->dataPacket($pk);
$this->sendSettings(); $this->sendSettings();
}else{
Command::broadcastCommandMessage($this, new TranslationContainer("commands.gamemode.success.self", [Server::getGamemodeString($gm)]));
}
$this->inventory->sendContents($this); $this->inventory->sendContents($this);
$this->inventory->sendContents($this->getViewers()); $this->inventory->sendContents($this->getViewers());
@ -2816,6 +2831,18 @@ class Player extends Human implements CommandSender, InventoryHolder, ChunkLoade
$pk->radius = $packet->radius; $pk->radius = $packet->radius;
$this->dataPacket($pk); $this->dataPacket($pk);
break; break;
case ProtocolInfo::SET_PLAYER_GAME_TYPE_PACKET:
if($packet->gamemode !== $this->gamemode){
if(!$this->hasPermission("pocketmine.command.gamemode")){
$pk = new SetPlayerGameTypePacket();
$pk->gamemode = $this->gamemode & 0x01;
$this->dataPacket($pk);
$this->sendSettings();
break;
}
$this->setGamemode($packet->gamemode, true);
}
break;
default: default:
break; break;
} }

View File

@ -30,7 +30,7 @@ class SetPlayerGameTypePacket extends DataPacket{
public $gamemode; public $gamemode;
public function decode(){ public function decode(){
$this->gamemode = $this->getVarInt();
} }
public function encode(){ public function encode(){