Skip to content

Commit

Permalink
Make chiseled bookshelves use their own items serialization
Browse files Browse the repository at this point in the history
  • Loading branch information
JavierLeon9966 committed Aug 24, 2024
1 parent 8d9e14d commit 6d47810
Show file tree
Hide file tree
Showing 2 changed files with 56 additions and 19 deletions.
54 changes: 52 additions & 2 deletions src/block/tile/ChiseledBookshelf.php
Original file line number Diff line number Diff line change
Expand Up @@ -23,11 +23,17 @@

namespace pocketmine\block\tile;

use pocketmine\block\tile\util\ContainerHelper;
use pocketmine\block\utils\ChiseledBookshelfSlot;
use pocketmine\data\bedrock\item\SavedItemData;
use pocketmine\data\bedrock\item\SavedItemStackData;
use pocketmine\data\SavedDataLoadingException;
use pocketmine\inventory\SimpleInventory;
use pocketmine\item\Item;
use pocketmine\math\Vector3;
use pocketmine\nbt\NBT;
use pocketmine\nbt\tag\CompoundTag;
use pocketmine\nbt\tag\ListTag;
use pocketmine\nbt\tag\StringTag;
use pocketmine\world\World;
use function count;

Expand Down Expand Up @@ -57,8 +63,52 @@ protected function writeSaveData(CompoundTag $nbt) : void{
$this->saveItems($nbt);
}

protected function loadItems(CompoundTag $tag) : void{
if(($inventoryTag = $tag->getTag(Container::TAG_ITEMS)) instanceof ListTag && $inventoryTag->getTagType() === NBT::TAG_Compound){
$inventory = $this->getRealInventory();
$listeners = $inventory->getListeners()->toArray();
$inventory->getListeners()->remove(...$listeners); //prevent any events being fired by initialization

$newContents = [];
/** @var CompoundTag $itemNBT */
foreach($inventoryTag as $slot => $itemNBT){
try{
$count = $itemNBT->getByte(SavedItemStackData::TAG_COUNT);
if($count === 0){
continue;
}
$newContents[$slot] = Item::nbtDeserialize($itemNBT);
}catch(SavedDataLoadingException $e){
//TODO: not the best solution
\GlobalLogger::get()->logException($e);
continue;
}
}
$inventory->setContents($newContents);

$inventory->getListeners()->add(...$listeners);
}

if(($lockTag = $tag->getTag(Container::TAG_LOCK)) instanceof StringTag){
$this->lock = $lockTag->getValue();
}
}

protected function saveItems(CompoundTag $tag) : void{
ContainerHelper::serializeContents($tag, $this->getRealInventory()->getContents(true), true);
$items = [];
foreach($this->getRealInventory()->getContents(true) as $slot => $item){
if($item->isNull()){
$items[$slot] = CompoundTag::create()
->setByte(SavedItemStackData::TAG_COUNT, 0)
->setShort(SavedItemData::TAG_DAMAGE, 0)
->setString(SavedItemData::TAG_NAME, "")
->setByte(SavedItemStackData::TAG_WAS_PICKED_UP, 0);
}else{
$items[$slot] = $item->nbtSerialize();
}
}

$tag->setTag(Container::TAG_ITEMS, new ListTag($items, NBT::TAG_Compound));

if($this->lock !== null){
$tag->setString(Container::TAG_LOCK, $this->lock);
Expand Down
21 changes: 4 additions & 17 deletions src/block/tile/util/ContainerHelper.php
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,6 @@
namespace pocketmine\block\tile\util;

use pocketmine\block\tile\Container;
use pocketmine\data\bedrock\item\SavedItemData;
use pocketmine\data\bedrock\item\SavedItemStackData;
use pocketmine\data\SavedDataLoadingException;
use pocketmine\item\Item;
Expand All @@ -46,13 +45,9 @@ public static function deserializeContents(CompoundTag $tag) : ?array{
if(($inventoryTag = $tag->getTag(Container::TAG_ITEMS)) instanceof ListTag && $inventoryTag->getTagType() === NBT::TAG_Compound){
$contents = [];
/** @var CompoundTag $itemNBT */
foreach($inventoryTag as $slot => $itemNBT){
foreach($inventoryTag as $itemNBT){
try{
$count = $itemNBT->getByte(SavedItemStackData::TAG_COUNT);
if($count === 0){
continue;
}
$contents[$slot] = Item::nbtDeserialize($itemNBT);
$contents[$itemNBT->getByte(SavedItemStackData::TAG_SLOT)] = Item::nbtDeserialize($itemNBT);
}catch(SavedDataLoadingException $e){
//TODO: not the best solution
\GlobalLogger::get()->logException($e);
Expand All @@ -70,18 +65,10 @@ public static function deserializeContents(CompoundTag $tag) : ?array{
* @param Item[] $contents
* @phpstan-param array<int, Item> $contents
*/
public static function serializeContents(CompoundTag $tag, array $contents, bool $includeEmpty = false) : void{
public static function serializeContents(CompoundTag $tag, array $contents) : void{
$items = [];
foreach($contents as $slot => $item){
if($includeEmpty && $item->isNull()){
$items[$slot] = CompoundTag::create()
->setByte(SavedItemStackData::TAG_COUNT, 0)
->setShort(SavedItemData::TAG_DAMAGE, 0)
->setString(SavedItemData::TAG_NAME, "")
->setByte(SavedItemStackData::TAG_WAS_PICKED_UP, 0);
}else{
$items[$slot] = $item->nbtSerialize();
}
$items[] = $item->nbtSerialize($slot);
}

$tag->setTag(Container::TAG_ITEMS, new ListTag($items, NBT::TAG_Compound));
Expand Down

0 comments on commit 6d47810

Please sign in to comment.