From 998dcb421e8fe69ea61f0ae1982ee6ea02a5a382 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 23 Feb 2019 18:19:31 +0000 Subject: [PATCH] Flatten Item Frame implementation into its block (mostly) This exposes nice API on the ItemFrame class, while keeping the tile bullshit out of sight so that we can remove it later on. --- src/pocketmine/Player.php | 19 +++-- src/pocketmine/block/ItemFrame.php | 117 +++++++++++++++++++++++++---- src/pocketmine/tile/ItemFrame.php | 4 + 3 files changed, 115 insertions(+), 25 deletions(-) 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";