diff --git a/src/pocketmine/Player.php b/src/pocketmine/Player.php index 3aaa1ee37..bb32dc89c 100644 --- a/src/pocketmine/Player.php +++ b/src/pocketmine/Player.php @@ -26,6 +26,7 @@ namespace pocketmine; use pocketmine\block\Bed; use pocketmine\block\Block; use pocketmine\block\BlockFactory; +use pocketmine\block\ItemFrame; use pocketmine\block\UnknownBlock; use pocketmine\command\Command; use pocketmine\command\CommandSender; @@ -135,7 +136,6 @@ use pocketmine\permission\PermissionAttachment; use pocketmine\permission\PermissionAttachmentInfo; use pocketmine\permission\PermissionManager; use pocketmine\plugin\Plugin; -use pocketmine\tile\ItemFrame; use pocketmine\tile\Spawnable; use pocketmine\tile\Tile; use pocketmine\timings\Timings; @@ -2491,25 +2491,24 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, } public function handleItemFrameDropItem(ItemFrameDropItemPacket $packet) : bool{ - $tile = $this->level->getTileAt($packet->x, $packet->y, $packet->z); - if($tile instanceof ItemFrame){ - //TODO: use facing blockstate property instead of damage value - $ev = new PlayerInteractEvent($this, $this->inventory->getItemInHand(), $tile->getBlock(), null, 5 - $tile->getBlock()->getDamage(), PlayerInteractEvent::LEFT_CLICK_BLOCK); + $block = $this->level->getBlockAt($packet->x, $packet->y, $packet->z); + if($block instanceof ItemFrame){ + $ev = new PlayerInteractEvent($this, $this->inventory->getItemInHand(), $block, null, $block->getFacing(), PlayerInteractEvent::LEFT_CLICK_BLOCK); if($this->isSpectator()){ $ev->setCancelled(); } $ev->call(); if($ev->isCancelled()){ - $this->level->sendBlocks([$this], [$tile]); + $this->level->sendBlocks([$this], [$block]); return true; } - if(lcg_value() <= $tile->getItemDropChance()){ - $this->level->dropItem($tile->getBlock(), $tile->getItem()); + if(lcg_value() <= $block->getItemDropChance()){ + $this->level->dropItem($block->add(0.5, 0.5, 0.5), $block->getFramedItem()); } - $tile->setItem(null); - $tile->setItemRotation(0); + $block->setFramedItem(null); + $this->level->setBlock($block, $block); } return true; diff --git a/src/pocketmine/block/ItemFrame.php b/src/pocketmine/block/ItemFrame.php index 1c862fb0b..770a1cd4c 100644 --- a/src/pocketmine/block/ItemFrame.php +++ b/src/pocketmine/block/ItemFrame.php @@ -37,6 +37,12 @@ class ItemFrame extends Flowable{ protected $facing = Facing::NORTH; /** @var bool */ protected $hasMap = false; //makes frame appear large if set + /** @var Item|null */ + protected $framedItem = null; + /** @var int */ + protected $itemRotation = 0; + /** @var float */ + protected $itemDropChance = 1.0; protected function writeStateToMeta() : int{ return (5 - $this->facing) | ($this->hasMap ? 0x04 : 0); @@ -47,19 +53,105 @@ class ItemFrame extends Flowable{ $this->hasMap = ($stateMeta & 0x04) !== 0; } + public function readStateFromWorld() : void{ + parent::readStateFromWorld(); + $tile = $this->level->getTile($this); + if($tile instanceof TileItemFrame){ + $this->framedItem = $tile->getItem(); + if($this->framedItem->isNull()){ + $this->framedItem = null; + } + $this->itemRotation = $tile->getItemRotation() % 8; + $this->itemDropChance = $tile->getItemDropChance(); + } + } + + public function writeStateToWorld() : void{ + parent::writeStateToWorld(); + $tile = $this->level->getTile($this); + if($tile instanceof TileItemFrame){ + $tile->setItem($this->framedItem); + $tile->setItemRotation($this->itemRotation); + $tile->setItemDropChance($this->itemDropChance); + } + } + public function getStateBitmask() : int{ return 0b111; } - public function onActivate(Item $item, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ - $tile = $this->level->getTile($this); - if($tile instanceof TileItemFrame){ - if($tile->hasItem()){ - $tile->setItemRotation(($tile->getItemRotation() + 1) % 8); - }elseif(!$item->isNull()){ - $tile->setItem($item->pop()); - } + /** + * @return int + */ + public function getFacing() : int{ + return $this->facing; + } + + /** + * @param int $facing + */ + public function setFacing(int $facing) : void{ + $this->facing = $facing; + } + + /** + * @return Item|null + */ + public function getFramedItem() : ?Item{ + return clone $this->framedItem; + } + + /** + * @param Item|null $item + */ + public function setFramedItem(?Item $item) : void{ + if($item === null or $item->isNull()){ + $this->framedItem = null; + $this->itemRotation = 0; + }else{ + $this->framedItem = clone $item; } + } + + /** + * @return int + */ + public function getItemRotation() : int{ + return $this->itemRotation; + } + + /** + * @param int $itemRotation + */ + public function setItemRotation(int $itemRotation) : void{ + $this->itemRotation = $itemRotation; + } + + /** + * @return float + */ + public function getItemDropChance() : float{ + return $this->itemDropChance; + } + + /** + * @param float $itemDropChance + */ + public function setItemDropChance(float $itemDropChance) : void{ + $this->itemDropChance = $itemDropChance; + } + + public function onActivate(Item $item, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ + if($this->framedItem !== null){ + $this->itemRotation = ($this->itemRotation + 1) % 8; + $this->itemRotation %= 8; + }elseif(!$item->isNull()){ + $this->framedItem = $item->pop(); + }else{ + return true; + } + + $this->level->setBlock($this, $this); return true; } @@ -82,13 +174,8 @@ class ItemFrame extends Flowable{ public function getDropsForCompatibleTool(Item $item) : array{ $drops = parent::getDropsForCompatibleTool($item); - - $tile = $this->level->getTile($this); - if($tile instanceof TileItemFrame){ - $tileItem = $tile->getItem(); - if(lcg_value() <= $tile->getItemDropChance() and !$tileItem->isNull()){ - $drops[] = $tileItem; - } + if($this->framedItem !== null and lcg_value() <= $this->itemDropChance){ + $drops[] = clone $this->framedItem; } return $drops; diff --git a/src/pocketmine/tile/ItemFrame.php b/src/pocketmine/tile/ItemFrame.php index cd75daeaf..cc831a4d0 100644 --- a/src/pocketmine/tile/ItemFrame.php +++ b/src/pocketmine/tile/ItemFrame.php @@ -29,6 +29,10 @@ use pocketmine\level\Level; use pocketmine\math\Vector3; use pocketmine\nbt\tag\CompoundTag; +/** + * @deprecated + * @see \pocketmine\block\ItemFrame + */ class ItemFrame extends Spawnable{ public const TAG_ITEM_ROTATION = "ItemRotation"; public const TAG_ITEM_DROP_CHANCE = "ItemDropChance";