mirror of
https://github.com/pmmp/PocketMine-MP.git
synced 2025-09-06 17:59:48 +00:00
Use SplFixedArrays in inventory, added more typehints and cleaned up some duplicated code
This commit is contained in:
@ -36,13 +36,11 @@ abstract class BaseInventory implements Inventory{
|
||||
|
||||
/** @var int */
|
||||
protected $maxStackSize = Inventory::MAX_STACK;
|
||||
/** @var int */
|
||||
protected $size;
|
||||
/** @var string */
|
||||
protected $name;
|
||||
/** @var string */
|
||||
protected $title;
|
||||
/** @var Item[] */
|
||||
/** @var \SplFixedArray<Item> */
|
||||
protected $slots = [];
|
||||
/** @var Player[] */
|
||||
protected $viewers = [];
|
||||
@ -58,7 +56,7 @@ abstract class BaseInventory implements Inventory{
|
||||
public function __construct(InventoryHolder $holder, array $items = [], int $size = null, string $title = null){
|
||||
$this->holder = $holder;
|
||||
|
||||
$this->size = $size ?? $this->getDefaultSize();
|
||||
$this->slots = new \SplFixedArray($size ?? $this->getDefaultSize());
|
||||
$this->title = $title ?? $this->getName();
|
||||
|
||||
$this->setContents($items);
|
||||
@ -76,12 +74,22 @@ abstract class BaseInventory implements Inventory{
|
||||
*/
|
||||
abstract public function getNetworkType() : int;
|
||||
|
||||
/**
|
||||
* Returns the size of the inventory.
|
||||
* @return int
|
||||
*/
|
||||
public function getSize() : int{
|
||||
return $this->size;
|
||||
return $this->slots->getSize();
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the new size of the inventory.
|
||||
* WARNING: If the size is smaller, any items past the new size will be lost.
|
||||
*
|
||||
* @param int $size
|
||||
*/
|
||||
public function setSize(int $size){
|
||||
$this->size = $size;
|
||||
$this->slots->setSize($size);
|
||||
}
|
||||
|
||||
abstract public function getDefaultSize() : int;
|
||||
@ -91,41 +99,41 @@ abstract class BaseInventory implements Inventory{
|
||||
}
|
||||
|
||||
public function getItem(int $index) : Item{
|
||||
assert($index >= 0, "Inventory slot should not be negative");
|
||||
return isset($this->slots[$index]) ? clone $this->slots[$index] : Item::get(Item::AIR, 0, 0);
|
||||
return $this->slots[$index] !== null ? clone $this->slots[$index] : Item::get(Item::AIR, 0, 0);
|
||||
}
|
||||
|
||||
public function getContents() : array{
|
||||
return $this->slots;
|
||||
return $this->slots->toArray();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Item[] $items
|
||||
*/
|
||||
public function setContents(array $items){
|
||||
if(count($items) > $this->size){
|
||||
$items = array_slice($items, 0, $this->size, true);
|
||||
if(count($items) > $this->getSize()){
|
||||
$items = array_slice($items, 0, $this->getSize(), true);
|
||||
}
|
||||
|
||||
for($i = 0; $i < $this->size; ++$i){
|
||||
for($i = 0, $size = $this->getSize(); $i < $size; ++$i){
|
||||
if(!isset($items[$i])){
|
||||
if(isset($this->slots[$i])){
|
||||
$this->clear($i);
|
||||
if($this->slots[$i] !== null){
|
||||
$this->clear($i, false);
|
||||
}
|
||||
}else{
|
||||
if(!$this->setItem($i, $items[$i])){
|
||||
$this->clear($i);
|
||||
if(!$this->setItem($i, $items[$i], false)){
|
||||
$this->clear($i, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$this->sendContents($this->getViewers());
|
||||
}
|
||||
|
||||
public function setItem(int $index, Item $item) : bool{
|
||||
$item = clone $item;
|
||||
if($index < 0 or $index >= $this->size){
|
||||
return false;
|
||||
}elseif($item->getId() === 0 or $item->getCount() <= 0){
|
||||
return $this->clear($index);
|
||||
public function setItem(int $index, Item $item, bool $send = true) : bool{
|
||||
if($item->isNull()){
|
||||
$item = Item::get(Item::AIR, 0, 0);
|
||||
}else{
|
||||
$item = clone $item;
|
||||
}
|
||||
|
||||
$holder = $this->getHolder();
|
||||
@ -139,8 +147,8 @@ abstract class BaseInventory implements Inventory{
|
||||
}
|
||||
|
||||
$old = $this->getItem($index);
|
||||
$this->slots[$index] = clone $item;
|
||||
$this->onSlotChange($index, $old);
|
||||
$this->slots[$index] = $item->isNull() ? null : $item;
|
||||
$this->onSlotChange($index, $old, $send);
|
||||
|
||||
return true;
|
||||
}
|
||||
@ -200,8 +208,8 @@ abstract class BaseInventory implements Inventory{
|
||||
}
|
||||
|
||||
public function firstEmpty() : int{
|
||||
for($i = 0; $i < $this->size; ++$i){
|
||||
if($this->getItem($i)->getId() === Item::AIR){
|
||||
foreach($this->slots as $i => $slot){
|
||||
if($slot === null or $slot->isNull()){
|
||||
return $i;
|
||||
}
|
||||
}
|
||||
@ -324,35 +332,16 @@ abstract class BaseInventory implements Inventory{
|
||||
return $itemSlots;
|
||||
}
|
||||
|
||||
public function clear(int $index) : bool{
|
||||
if(isset($this->slots[$index])){
|
||||
$item = Item::get(Item::AIR, 0, 0);
|
||||
$old = $this->slots[$index];
|
||||
$holder = $this->getHolder();
|
||||
if($holder instanceof Entity){
|
||||
Server::getInstance()->getPluginManager()->callEvent($ev = new EntityInventoryChangeEvent($holder, $old, $item, $index));
|
||||
if($ev->isCancelled()){
|
||||
$this->sendSlot($index, $this->getViewers());
|
||||
return false;
|
||||
}
|
||||
$item = $ev->getNewItem();
|
||||
}
|
||||
if($item->getId() !== Item::AIR){
|
||||
$this->slots[$index] = clone $item;
|
||||
}else{
|
||||
unset($this->slots[$index]);
|
||||
}
|
||||
|
||||
$this->onSlotChange($index, $old);
|
||||
}
|
||||
|
||||
return true;
|
||||
public function clear(int $index, bool $send = true) : bool{
|
||||
return $this->setItem($index, Item::get(Item::AIR, 0, 0), $send);
|
||||
}
|
||||
|
||||
public function clearAll(){
|
||||
foreach($this->getContents() as $index => $i){
|
||||
$this->clear($index);
|
||||
for($i = 0, $size = $this->getSize(); $i < $size; ++$i){
|
||||
$this->clear($i, false);
|
||||
}
|
||||
|
||||
$this->sendContents($this->getViewers());
|
||||
}
|
||||
|
||||
/**
|
||||
@ -392,8 +381,10 @@ abstract class BaseInventory implements Inventory{
|
||||
unset($this->viewers[spl_object_hash($who)]);
|
||||
}
|
||||
|
||||
public function onSlotChange($index, $before){
|
||||
$this->sendSlot($index, $this->getViewers());
|
||||
public function onSlotChange(int $index, Item $before, bool $send){
|
||||
if($send){
|
||||
$this->sendSlot($index, $this->getViewers());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -424,7 +415,7 @@ abstract class BaseInventory implements Inventory{
|
||||
* @param int $index
|
||||
* @param Player|Player[] $target
|
||||
*/
|
||||
public function sendSlot($index, $target){
|
||||
public function sendSlot(int $index, $target){
|
||||
if($target instanceof Player){
|
||||
$target = [$target];
|
||||
}
|
||||
|
Reference in New Issue
Block a user