mirror of
https://github.com/pmmp/PocketMine-MP.git
synced 2025-06-16 08:25:29 +00:00
Added API for assigning permanent windows, fixed teleportation breaking inventory
This commit is contained in:
parent
f35ca147bb
commit
1f6d325328
@ -224,6 +224,8 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{
|
|||||||
protected $windows;
|
protected $windows;
|
||||||
/** @var Inventory[] */
|
/** @var Inventory[] */
|
||||||
protected $windowIndex = [];
|
protected $windowIndex = [];
|
||||||
|
/** @var bool[] */
|
||||||
|
protected $permanentWindows = [];
|
||||||
|
|
||||||
protected $messageCounter = 2;
|
protected $messageCounter = 2;
|
||||||
|
|
||||||
@ -3495,9 +3497,7 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{
|
|||||||
$this->hiddenPlayers = [];
|
$this->hiddenPlayers = [];
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach($this->windowIndex as $window){
|
$this->removeAllWindows(true);
|
||||||
$this->removeWindow($window);
|
|
||||||
}
|
|
||||||
$this->windows = null;
|
$this->windows = null;
|
||||||
$this->windowIndex = [];
|
$this->windowIndex = [];
|
||||||
|
|
||||||
@ -3789,12 +3789,7 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{
|
|||||||
public function teleport(Vector3 $pos, float $yaw = null, float $pitch = null) : bool{
|
public function teleport(Vector3 $pos, float $yaw = null, float $pitch = null) : bool{
|
||||||
if(parent::teleport($pos, $yaw, $pitch)){
|
if(parent::teleport($pos, $yaw, $pitch)){
|
||||||
|
|
||||||
foreach($this->windowIndex as $window){
|
$this->removeAllWindows();
|
||||||
if($window === $this->inventory){
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
$this->removeWindow($window);
|
|
||||||
}
|
|
||||||
|
|
||||||
$this->sendPosition($this, $this->yaw, $this->pitch, MovePlayerPacket::MODE_TELEPORT);
|
$this->sendPosition($this, $this->yaw, $this->pitch, MovePlayerPacket::MODE_TELEPORT);
|
||||||
$this->sendPosition($this, $this->yaw, $this->pitch, MovePlayerPacket::MODE_TELEPORT, $this->getViewers());
|
$this->sendPosition($this, $this->yaw, $this->pitch, MovePlayerPacket::MODE_TELEPORT, $this->getViewers());
|
||||||
@ -3828,10 +3823,10 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected function addDefaultWindows(){
|
protected function addDefaultWindows(){
|
||||||
$this->addWindow($this->getInventory(), ContainerIds::INVENTORY);
|
$this->addWindow($this->getInventory(), ContainerIds::INVENTORY, true);
|
||||||
|
|
||||||
$this->cursorInventory = new PlayerCursorInventory($this);
|
$this->cursorInventory = new PlayerCursorInventory($this);
|
||||||
$this->addWindow($this->cursorInventory, ContainerIds::CURSOR);
|
$this->addWindow($this->cursorInventory, ContainerIds::CURSOR, true);
|
||||||
|
|
||||||
//TODO: more windows
|
//TODO: more windows
|
||||||
}
|
}
|
||||||
@ -3841,19 +3836,26 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* Returns the window ID which the inventory has for this player, or -1 if the window is not open to the player.
|
||||||
|
*
|
||||||
* @param Inventory $inventory
|
* @param Inventory $inventory
|
||||||
*
|
*
|
||||||
* @return int
|
* @return int
|
||||||
*/
|
*/
|
||||||
public function getWindowId(Inventory $inventory){
|
public function getWindowId(Inventory $inventory){
|
||||||
if($this->windows->contains($inventory)){
|
if($this->windows->contains($inventory)){
|
||||||
return $this->windows[$inventory];
|
/** @var int $id */
|
||||||
|
$id = $this->windows[$inventory];
|
||||||
|
return $id;
|
||||||
}
|
}
|
||||||
|
|
||||||
return ContainerIds::NONE;
|
return ContainerIds::NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* Returns the inventory window open to the player with the specified window ID, or null if no window is open with
|
||||||
|
* that ID.
|
||||||
|
*
|
||||||
* @param int $windowId
|
* @param int $windowId
|
||||||
*
|
*
|
||||||
* @return Inventory|null
|
* @return Inventory|null
|
||||||
@ -3863,16 +3865,18 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the created/existing window id
|
* Opens an inventory window to the player. Returns the ID of the created window, or the existing window ID if the
|
||||||
|
* player is already viewing the specified inventory.
|
||||||
*
|
*
|
||||||
* @param Inventory $inventory
|
* @param Inventory $inventory
|
||||||
* @param int|null $forceId
|
* @param int|null $forceId Forces a special ID for the window
|
||||||
|
* @param bool $isPermanent Prevents the window being removed if true.
|
||||||
*
|
*
|
||||||
* @return int
|
* @return int
|
||||||
*/
|
*/
|
||||||
public function addWindow(Inventory $inventory, int $forceId = null) : int{
|
public function addWindow(Inventory $inventory, int $forceId = null, bool $isPermanent = false) : int{
|
||||||
if($this->windows->contains($inventory)){
|
if(($id = $this->getWindowId($inventory)) !== ContainerIds::NONE){
|
||||||
return $this->windows[$inventory];
|
return $id;
|
||||||
}
|
}
|
||||||
|
|
||||||
if($forceId === null){
|
if($forceId === null){
|
||||||
@ -3883,6 +3887,9 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{
|
|||||||
$this->windowIndex[$cnt] = $inventory;
|
$this->windowIndex[$cnt] = $inventory;
|
||||||
$this->windows->attach($inventory, $cnt);
|
$this->windows->attach($inventory, $cnt);
|
||||||
if($inventory->open($this)){
|
if($inventory->open($this)){
|
||||||
|
if($isPermanent){
|
||||||
|
$this->permanentWindows[$cnt] = true;
|
||||||
|
}
|
||||||
return $cnt;
|
return $cnt;
|
||||||
}else{
|
}else{
|
||||||
$this->removeWindow($inventory);
|
$this->removeWindow($inventory);
|
||||||
@ -3891,13 +3898,41 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public function removeWindow(Inventory $inventory){
|
/**
|
||||||
$inventory->close($this);
|
* Removes an inventory window from the player.
|
||||||
|
*
|
||||||
|
* @param Inventory $inventory
|
||||||
|
* @param bool $force Forces removal of permanent windows such as normal inventory, cursor
|
||||||
|
*
|
||||||
|
* @throws \BadMethodCallException if trying to remove a fixed inventory window without the `force` parameter as true
|
||||||
|
*/
|
||||||
|
public function removeWindow(Inventory $inventory, bool $force = false){
|
||||||
if($this->windows->contains($inventory)){
|
if($this->windows->contains($inventory)){
|
||||||
/** @var int $id */
|
/** @var int $id */
|
||||||
$id = $this->windows[$inventory];
|
$id = $this->windows[$inventory];
|
||||||
|
if(!$force and isset($this->permanentWindows[$id])){
|
||||||
|
throw new \BadMethodCallException("Cannot remove fixed window $id (" . get_class($inventory) . ") from " . $this->getName());
|
||||||
|
}
|
||||||
$this->windows->detach($this->windowIndex[$id]);
|
$this->windows->detach($this->windowIndex[$id]);
|
||||||
unset($this->windowIndex[$id]);
|
unset($this->windowIndex[$id]);
|
||||||
|
unset($this->permanentWindows[$id]);
|
||||||
|
}
|
||||||
|
|
||||||
|
$inventory->close($this);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Removes all inventory windows from the player. By default this WILL NOT remove permanent windows.
|
||||||
|
*
|
||||||
|
* @param bool $removePermanentWindows Whether to remove permanent windows.
|
||||||
|
*/
|
||||||
|
public function removeAllWindows(bool $removePermanentWindows = false){
|
||||||
|
foreach($this->windowIndex as $id => $window){
|
||||||
|
if(!$removePermanentWindows and isset($this->permanentWindows[$id])){
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->removeWindow($window, $removePermanentWindows);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user