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 if($item["Slot"] >= 0 and $item["Slot"] < 9){ //Hotbar
$this->inventory->setHotbarSlotIndex($item["Slot"], isset($item["TrueSlot"]) ? $item["TrueSlot"] : -1); $this->inventory->setHotbarSlotIndex($item["Slot"], isset($item["TrueSlot"]) ? $item["TrueSlot"] : -1);
}elseif($item["Slot"] >= 100 and $item["Slot"] < 104){ //Armor }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{ }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){ if($hotbarSlot !== -1){
$item = $this->inventory->getItem($hotbarSlot); $item = $this->inventory->getItem($hotbarSlot);
if($item->getId() !== 0 and $item->getCount() > 0){ if($item->getId() !== 0 and $item->getCount() > 0){
$this->namedtag->Inventory[$slot] = new Compound("", [ $tag = NBT::putItemHelper($item, $slot);
new Byte("Count", $item->getCount()), $tag->TrueSlot = new Byte("TrueSlot", $hotbarSlot);
new Short("Damage", $item->getDamage()), $this->namedtag->Inventory[$slot] = $tag;
new Byte("Slot", $slot),
new Byte("TrueSlot", $hotbarSlot),
new Short("id", $item->getId()),
]);
continue; continue;
} }
} }
$this->namedtag->Inventory[$slot] = new Compound("", [ $this->namedtag->Inventory[$slot] = new Compound("", [
new Byte("Count", 0), new Byte("Count", 0),
new Short("Damage", 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; //$slotCount = (($this instanceof Player and ($this->gamemode & 0x01) === 1) ? Player::CREATIVE_SLOTS : Player::SURVIVAL_SLOTS) + 9;
for($slot = 9; $slot < $slotCount; ++$slot){ for($slot = 9; $slot < $slotCount; ++$slot){
$item = $this->inventory->getItem($slot - 9); $item = $this->inventory->getItem($slot - 9);
$this->namedtag->Inventory[$slot] = new Compound("", [ $this->namedtag->Inventory[$slot] = NBT::putItemHelper($item, $slot);
new Byte("Count", $item->getCount()),
new Short("Damage", $item->getDamage()),
new Byte("Slot", $slot),
new Short("id", $item->getId()),
]);
} }
//Armor //Armor
for($slot = 100; $slot < 104; ++$slot){ for($slot = 100; $slot < 104; ++$slot){
$item = $this->inventory->getItem($this->inventory->getSize() + $slot - 100); $item = $this->inventory->getItem($this->inventory->getSize() + $slot - 100);
if($item instanceof ItemItem and $item->getId() !== ItemItem::AIR){ if($item instanceof ItemItem and $item->getId() !== ItemItem::AIR){
$this->namedtag->Inventory[$slot] = new Compound("", [ $this->namedtag->Inventory[$slot] = NBT::putItemHelper($item, $slot);
new Byte("Count", $item->getCount()),
new Short("Damage", $item->getDamage()),
new Byte("Slot", $slot),
new Short("id", $item->getId()),
]);
} }
} }
} }

View File

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

View File

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

View File

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

View File

@@ -24,6 +24,7 @@
*/ */
namespace pocketmine\nbt; namespace pocketmine\nbt;
use pocketmine\item\Item;
use pocketmine\nbt\tag\Byte; use pocketmine\nbt\tag\Byte;
use pocketmine\nbt\tag\ByteArray; use pocketmine\nbt\tag\ByteArray;
use pocketmine\nbt\tag\Compound; use pocketmine\nbt\tag\Compound;
@@ -73,6 +74,48 @@ class NBT{
public $endianness; public $endianness;
private $data; 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){ public function get($len){
if($len < 0){ if($len < 0){
$this->offset = strlen($this->buffer) - 1; $this->offset = strlen($this->buffer) - 1;

View File

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

View File

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

View File

@@ -24,24 +24,24 @@ namespace pocketmine\nbt\tag;
abstract class NamedTag extends Tag{ abstract class NamedTag extends Tag{
protected $name; public $__name;
/** /**
* @param string $name * @param string $name
* @param bool|float|double|int|byte|short|array|Compound|Enum|string $value * @param bool|float|double|int|byte|short|array|Compound|Enum|string $value
*/ */
public function __construct($name = "", $value = null){ 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){ if($value !== null){
$this->value = $value; $this->value = $value;
} }
} }
public function getName(){ public function getName(){
return $this->name; return $this->__name;
} }
public function setName($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){ if($i < 0){
return Item::get(Item::AIR, 0, 0); return Item::get(Item::AIR, 0, 0);
}else{ }else{
$item = Item::get($this->namedtag->Items[$i]["id"], $this->namedtag->Items[$i]["Damage"], $this->namedtag->Items[$i]["Count"]); return NBT::getItemHelper($this->namedtag->Items[$i]);
if(isset($this->namedtag->Items[$i]["tag"])){
$item->setNamedTag($this->namedtag->Items[$i]["tag"]);
}
return $item;
} }
} }
@@ -130,17 +126,7 @@ class Chest extends Spawnable implements InventoryHolder, Container{
public function setItem($index, Item $item){ public function setItem($index, Item $item){
$i = $this->getSlotIndex($index); $i = $this->getSlotIndex($index);
$d = new Compound("", [ $d = NBT::putItemHelper($item, $index);
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;
}
if($item->getId() === Item::AIR or $item->getCount() <= 0){ if($item->getId() === Item::AIR or $item->getCount() <= 0){
if($i >= 0){ if($i >= 0){

View File

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