Save items properly on several places, added NBT::getItemHelper() and NBT::putItemHelper()

This commit is contained in:
Shoghi Cervantes 2015-08-06 21:44:00 +02:00
parent 554bfb4855
commit 02cb9d69a9
10 changed files with 84 additions and 65 deletions

View File

@ -123,9 +123,9 @@ class Human extends Creature implements ProjectileSource, InventoryHolder{
if($item["Slot"] >= 0 and $item["Slot"] < 9){ //Hotbar
$this->inventory->setHotbarSlotIndex($item["Slot"], isset($item["TrueSlot"]) ? $item["TrueSlot"] : -1);
}elseif($item["Slot"] >= 100 and $item["Slot"] < 104){ //Armor
$this->inventory->setItem($this->inventory->getSize() + $item["Slot"] - 100, ItemItem::get($item["id"], $item["Damage"], $item["Count"]));
$this->inventory->setItem($this->inventory->getSize() + $item["Slot"] - 100, NBT::getItemHelper($item));
}else{
$this->inventory->setItem($item["Slot"] - 9, ItemItem::get($item["id"], $item["Damage"], $item["Count"]));
$this->inventory->setItem($item["Slot"] - 9, NBT::getItemHelper($item));
}
}
}
@ -158,16 +158,14 @@ class Human extends Creature implements ProjectileSource, InventoryHolder{
if($hotbarSlot !== -1){
$item = $this->inventory->getItem($hotbarSlot);
if($item->getId() !== 0 and $item->getCount() > 0){
$this->namedtag->Inventory[$slot] = new Compound("", [
new Byte("Count", $item->getCount()),
new Short("Damage", $item->getDamage()),
new Byte("Slot", $slot),
new Byte("TrueSlot", $hotbarSlot),
new Short("id", $item->getId()),
]);
$tag = NBT::putItemHelper($item, $slot);
$tag->TrueSlot = new Byte("TrueSlot", $hotbarSlot);
$this->namedtag->Inventory[$slot] = $tag;
continue;
}
}
$this->namedtag->Inventory[$slot] = new Compound("", [
new Byte("Count", 0),
new Short("Damage", 0),
@ -182,24 +180,14 @@ class Human extends Creature implements ProjectileSource, InventoryHolder{
//$slotCount = (($this instanceof Player and ($this->gamemode & 0x01) === 1) ? Player::CREATIVE_SLOTS : Player::SURVIVAL_SLOTS) + 9;
for($slot = 9; $slot < $slotCount; ++$slot){
$item = $this->inventory->getItem($slot - 9);
$this->namedtag->Inventory[$slot] = new Compound("", [
new Byte("Count", $item->getCount()),
new Short("Damage", $item->getDamage()),
new Byte("Slot", $slot),
new Short("id", $item->getId()),
]);
$this->namedtag->Inventory[$slot] = NBT::putItemHelper($item, $slot);
}
//Armor
for($slot = 100; $slot < 104; ++$slot){
$item = $this->inventory->getItem($this->inventory->getSize() + $slot - 100);
if($item instanceof ItemItem and $item->getId() !== ItemItem::AIR){
$this->namedtag->Inventory[$slot] = new Compound("", [
new Byte("Count", $item->getCount()),
new Short("Damage", $item->getDamage()),
new Byte("Slot", $slot),
new Short("id", $item->getId()),
]);
$this->namedtag->Inventory[$slot] = NBT::putItemHelper($item, $slot);
}
}
}

View File

@ -27,6 +27,7 @@ use pocketmine\event\entity\ItemDespawnEvent;
use pocketmine\event\entity\ItemSpawnEvent;
use pocketmine\item\Item as ItemItem;
use pocketmine\math\Vector3;
use pocketmine\nbt\NBT;
use pocketmine\nbt\tag\Byte;
use pocketmine\nbt\tag\Compound;
use pocketmine\nbt\tag\Short;
@ -69,7 +70,7 @@ class Item extends Entity{
if(isset($this->namedtag->Thrower)){
$this->thrower = $this->namedtag["Thrower"];
}
$this->item = ItemItem::get($this->namedtag->Item["id"], $this->namedtag->Item["Damage"], $this->namedtag->Item["Count"]);
$this->item = NBT::getItemHelper($this->namedtag->Item);
$this->server->getPluginManager()->callEvent(new ItemSpawnEvent($this));
@ -154,11 +155,7 @@ class Item extends Entity{
public function saveNBT(){
parent::saveNBT();
$this->namedtag->Item = new Compound("Item", [
"id" => new Short("id", $this->item->getId()),
"Damage" => new Short("Damage", $this->item->getDamage()),
"Count" => new Byte("Count", $this->item->getCount())
]);
$this->namedtag->Item = NBT::putItemHelper($this->item);
$this->namedtag->Health = new Short("Health", $this->getHealth());
$this->namedtag->Age = new Short("Age", $this->age);
$this->namedtag->PickupDelay = new Short("PickupDelay", $this->pickupDelay);

View File

@ -1039,6 +1039,15 @@ class Item{
return $this;
}
public function getNamedTagEntry($name){
$tag = $this->getNamedTag();
if($tag !== null){
return isset($tag->{$name}) ? $tag->{$name} : null;
}
return null;
}
public function getNamedTag(){
if(!$this->hasCompoundTag()){

View File

@ -24,6 +24,7 @@ namespace pocketmine\item;
use pocketmine\block\Block;
use pocketmine\entity\Entity;
use pocketmine\nbt\tag\Byte;
abstract class Tool extends Item{
const TIER_WOODEN = 1;
@ -55,6 +56,10 @@ abstract class Tool extends Item{
* @return bool
*/
public function useOn($object){
if($this->isUnbreakable()){
return true;
}
if($this->isHoe()){
if(($object instanceof Block) and ($object->getId() === self::GRASS or $object->getId() === self::DIRT)){
$this->meta++;
@ -101,6 +106,11 @@ abstract class Tool extends Item{
return $levels[$type];
}
public function isUnbreakable(){
$tag = $this->getNamedTagEntry("Unbreakable");
return $tag instanceof Byte and $tag->getValue() > 0;
}
public function isPickaxe(){
return false;
}

View File

@ -24,6 +24,7 @@
*/
namespace pocketmine\nbt;
use pocketmine\item\Item;
use pocketmine\nbt\tag\Byte;
use pocketmine\nbt\tag\ByteArray;
use pocketmine\nbt\tag\Compound;
@ -73,6 +74,48 @@ class NBT{
public $endianness;
private $data;
/**
* @param Item $item
* @param int $slot
* @return Compound
*/
public static function putItemHelper(Item $item, $slot = null){
$tag = new Compound(null, [
"id" => new Short("id", $item->getId()),
"Count" => new Byte("Count", $item->getCount()),
"Damage" => new Short("Damage", $item->getDamage())
]);
if($slot !== null){
$tag->Slot = new Byte("Slot", (int) $slot);
}
if($item->hasCompoundTag()){
$tag->tag = clone $item->getNamedTag();
$tag->tag->setName("tag");
}
return $tag;
}
/**
* @param Compound $item
* @return Item
*/
public static function getItemHelper(Compound $item){
if(!isset($item->id) or !isset($item->Damage) or !isset($item->Count)){
return Item::get(0);
}
$item = Item::get($item->id->getValue(), $item->Damage->getValue(), $item->Count->getValue());
if(isset($item->tag)){
$item->setNamedTag($item->tag);
}
return $item;
}
public function get($len){
if($len < 0){
$this->offset = strlen($this->buffer) - 1;

View File

@ -32,7 +32,7 @@ class Compound extends NamedTag implements \ArrayAccess{
* @param NamedTag[] $value
*/
public function __construct($name = "", $value = []){
$this->name = $name;
$this->__name = $name;
foreach($value as $tag){
$this->{$tag->getName()} = $tag;
}

View File

@ -31,7 +31,7 @@ class Enum extends NamedTag implements \ArrayAccess, \Countable{
private $tagType;
public function __construct($name = "", $value = []){
$this->name = $name;
$this->__name = $name;
foreach($value as $k => $v){
$this->{$k} = $v;
}

View File

@ -24,24 +24,24 @@ namespace pocketmine\nbt\tag;
abstract class NamedTag extends Tag{
protected $name;
public $__name;
/**
* @param string $name
* @param bool|float|double|int|byte|short|array|Compound|Enum|string $value
*/
public function __construct($name = "", $value = null){
$this->name = ($name === null or $name === false) ? "" : $name;
$this->__name = ($name === null or $name === false) ? "" : $name;
if($value !== null){
$this->value = $value;
}
}
public function getName(){
return $this->name;
return $this->__name;
}
public function setName($name){
$this->name = $name;
$this->__name = $name;
}
}

View File

@ -111,11 +111,7 @@ class Chest extends Spawnable implements InventoryHolder, Container{
if($i < 0){
return Item::get(Item::AIR, 0, 0);
}else{
$item = Item::get($this->namedtag->Items[$i]["id"], $this->namedtag->Items[$i]["Damage"], $this->namedtag->Items[$i]["Count"]);
if(isset($this->namedtag->Items[$i]["tag"])){
$item->setNamedTag($this->namedtag->Items[$i]["tag"]);
}
return $item;
return NBT::getItemHelper($this->namedtag->Items[$i]);
}
}
@ -130,17 +126,7 @@ class Chest extends Spawnable implements InventoryHolder, Container{
public function setItem($index, Item $item){
$i = $this->getSlotIndex($index);
$d = new Compound("", [
new Byte("Count", $item->getCount()),
new Byte("Slot", $index),
new Short("id", $item->getId()),
new Short("Damage", $item->getDamage()),
]);
if($item->hasCompoundTag() and ($tag = $item->getNamedTag()) !== null){
$tag->setName("tag");
$d->tag = $tag;
}
$d = NBT::putItemHelper($item, $index);
if($item->getId() === Item::AIR or $item->getCount() <= 0){
if($i >= 0){

View File

@ -120,11 +120,7 @@ class Furnace extends Tile implements InventoryHolder, Container{
if($i < 0){
return Item::get(Item::AIR, 0, 0);
}else{
$item = Item::get($this->namedtag->Items[$i]["id"], $this->namedtag->Items[$i]["Damage"], $this->namedtag->Items[$i]["Count"]);
if(isset($this->namedtag->Items[$i]["tag"])){
$item->setNamedTag($this->namedtag->Items[$i]["tag"]);
}
return $item;
return NBT::getItemHelper($this->namedtag->Items[$i]);
}
}
@ -139,17 +135,7 @@ class Furnace extends Tile implements InventoryHolder, Container{
public function setItem($index, Item $item){
$i = $this->getSlotIndex($index);
$d = new Compound("", [
new Byte("Count", $item->getCount()),
new Byte("Slot", $index),
new Short("id", $item->getId()),
new Short("Damage", $item->getDamage()),
]);
if($item->hasCompoundTag() and ($tag = $item->getNamedTag()) !== null){
$tag->setName("tag");
$d->tag = $tag;
}
$d = NBT::putItemHelper($item, $index);
if($item->getId() === Item::AIR or $item->getCount() <= 0){
if($i >= 0){