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\Block;
use pocketmine\command\Command;
use pocketmine\command\CommandSender;
use pocketmine\entity\Arrow;
use pocketmine\entity\Effect;
@ -1080,13 +1081,19 @@ class Player extends Human implements CommandSender, InventoryHolder, ChunkLoade
*
* @return bool
*/
public function setGamemode($gm){
public function setGamemode($gm, $client = false){
if($gm < 0 or $gm > 3 or $this->gamemode === $gm){
return false;
}
$this->server->getPluginManager()->callEvent($ev = new PlayerGameModeChangeEvent($this, (int) $gm));
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;
}
@ -1096,6 +1103,11 @@ class Player extends Human implements CommandSender, InventoryHolder, ChunkLoade
if($this->isSpectator()){
$this->isFlying = true;
$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{
if($this->isSurvival()){
$this->isFlying = false;
@ -1106,11 +1118,14 @@ class Player extends Human implements CommandSender, InventoryHolder, ChunkLoade
$this->resetFallDistance();
$this->namedtag->playerGameType = new IntTag("playerGameType", $this->gamemode);
$pk = new SetPlayerGameTypePacket();
$pk->gamemode = $this->gamemode & 0x01;
$this->dataPacket($pk);
$this->sendSettings();
if(!$client){ //Gamemode changed by server, do not send for client changes
$pk = new SetPlayerGameTypePacket();
$pk->gamemode = $this->gamemode & 0x01;
$this->dataPacket($pk);
$this->sendSettings();
}else{
Command::broadcastCommandMessage($this, new TranslationContainer("commands.gamemode.success.self", [Server::getGamemodeString($gm)]));
}
$this->inventory->sendContents($this);
$this->inventory->sendContents($this->getViewers());
@ -2816,6 +2831,18 @@ class Player extends Human implements CommandSender, InventoryHolder, ChunkLoade
$pk->radius = $packet->radius;
$this->dataPacket($pk);
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:
break;
}

View File

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