From 8c772fe6719db86fc10a58df190670808cc2c6c8 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 14 Dec 2016 18:30:40 +0000 Subject: [PATCH] Working item frames --- src/pocketmine/Player.php | 22 ++++- src/pocketmine/block/Block.php | 12 ++- src/pocketmine/block/ItemFrame.php | 150 +++++++++++++++++++++++++++++ src/pocketmine/item/Item.php | 1 + src/pocketmine/item/ItemFrame.php | 31 ++++++ src/pocketmine/tile/ItemFrame.php | 8 +- 6 files changed, 211 insertions(+), 13 deletions(-) create mode 100644 src/pocketmine/block/ItemFrame.php create mode 100644 src/pocketmine/item/ItemFrame.php diff --git a/src/pocketmine/Player.php b/src/pocketmine/Player.php index 924e9f428..2367b3d04 100644 --- a/src/pocketmine/Player.php +++ b/src/pocketmine/Player.php @@ -133,6 +133,7 @@ use pocketmine\network\SourceInterface; use pocketmine\permission\PermissibleBase; use pocketmine\permission\PermissionAttachment; use pocketmine\plugin\Plugin; +use pocketmine\tile\ItemFrame; use pocketmine\tile\Sign; use pocketmine\tile\Spawnable; use pocketmine\tile\Tile; @@ -2930,6 +2931,25 @@ class Player extends Human implements CommandSender, InventoryHolder, ChunkLoade $this->dataPacket($pk); $this->sendSettings(); } + break; + case ProtocolInfo::ITEM_FRAME_DROP_ITEM_PACKET: + if($this->spawned === false or $this->blocked === true or !$this->isAlive()){ + break; + } + + if(($tile = $this->level->getTile($this->temporalVector->setComponents($packet->x, $packet->y, $packet->z))) instanceof ItemFrame){ + if(!$tile->getItem()->equals($packet->item) and !$this->isCreative(true)){ + $tile->spawnTo($this); + break; + } + + if(lcg_value() <= $tile->getItemDropChance() and $packet->item->getId() !== Item::AIR){ + $this->level->dropItem($tile->getBlock(), $packet->item); //Use the packet item to handle creative drops correctly + } + $tile->setItem(null); + $tile->setItemRotation(0); + } + break; default: break; @@ -3025,7 +3045,7 @@ class Player extends Human implements CommandSender, InventoryHolder, ChunkLoade $pk->message = $message; $this->dataPacket($pk); } - + /** * @param string $sender * @param string $message diff --git a/src/pocketmine/block/Block.php b/src/pocketmine/block/Block.php index ef1bfdced..a7aad0f82 100644 --- a/src/pocketmine/block/Block.php +++ b/src/pocketmine/block/Block.php @@ -2,11 +2,11 @@ /* * - * ____ _ _ __ __ _ __ __ ____ - * | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \ + * ____ _ _ __ __ _ __ __ ____ + * | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \ * | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) | - * | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/ - * |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_| + * | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/ + * |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_| * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by @@ -15,7 +15,7 @@ * * @author PocketMine Team * @link http://www.pocketmine.net/ - * + * * */ @@ -236,6 +236,8 @@ class Block extends Position implements BlockIds, Metadatable{ self::$list[self::FENCE_GATE_DARK_OAK] = FenceGateDarkOak::class; self::$list[self::FENCE_GATE_ACACIA] = FenceGateAcacia::class; + self::$list[self::ITEM_FRAME_BLOCK] = ItemFrame::class; + self::$list[self::GRASS_PATH] = GrassPath::class; self::$list[self::PODZOL] = Podzol::class; diff --git a/src/pocketmine/block/ItemFrame.php b/src/pocketmine/block/ItemFrame.php new file mode 100644 index 000000000..faf995af4 --- /dev/null +++ b/src/pocketmine/block/ItemFrame.php @@ -0,0 +1,150 @@ +meta = $meta; + } + + public function getName(){ + return "Item Frame"; + } + + public function canBeActivated(){ + return true; + } + + public function onActivate(Item $item, Player $player = null){ + if(!(($tile = $this->level->getTile($this)) instanceof TileItemFrame)){ + $nbt = new CompoundTag("", [ + new StringTag("id", Tile::ITEM_FRAME), + new IntTag("x", $block->x), + new IntTag("y", $block->y), + new IntTag("z", $block->z), + new FloatTag("ItemDropChance", 1.0), + new ByteTag("ItemRotation", 0) + ]); + $tile = Tile::createTile(Tile::ITEM_FRAME, $this->level->getChunk($this->x >> 4, $this->z >> 4), $nbt); + } + + if($tile->hasItem()){ + $tile->setItemRotation(($tile->getItemRotation() + 1) % 8); + }else{ + if($item->getCount() > 0){ + $frameItem = clone $item; + $frameItem->setCount(1); + $item->setCount($item->getCount() - 1); + $tile->setItem($frameItem); + if($player instanceof Player and $player->isSurvival()){ + $player->getInventory()->setItemInHand($item->getCount() <= 0 ? Item::get(Item::AIR) : $item); + } + } + } + + return true; + } + + public function onBreak(Item $item){ + if(($tile = $this->level->getTile($this)) instanceof TileItemFrame){ + //TODO: add events + if(lcg_value() <= $tile->getItemDropChance() and $tile->getItem()->getId() !== Item::AIR){ + $this->level->dropItem($tile->getBlock(), $tile->getItem()); + } + } + return parent::onBreak($item); + } + + public function onUpdate($type){ + if($type === Level::BLOCK_UPDATE_NORMAL){ + $sides = [ + 0 => 4, + 1 => 5, + 2 => 2, + 3 => 3 + ]; + if(!$this->getSide($sides[$this->meta])->isSolid()){ + $this->level->useBreakOn($this); + return Level::BLOCK_UPDATE_NORMAL; + } + } + return false; + } + + public function place(Item $item, Block $block, Block $target, $face, $fx, $fy, $fz, Player $player = null){ + if($face === 0 or $face === 1){ + return false; + } + + $faces = [ + 2 => 3, + 3 => 2, + 4 => 1, + 5 => 0 + ]; + + $this->meta = $faces[$face]; + $this->level->setBlock($block, $this, true, true); + + $nbt = new CompoundTag("", [ + new StringTag("id", Tile::ITEM_FRAME), + new IntTag("x", $block->x), + new IntTag("y", $block->y), + new IntTag("z", $block->z), + new FloatTag("ItemDropChance", 1.0), + new ByteTag("ItemRotation", 0) + ]); + + if($item->hasCustomBlockData()){ + foreach($item->getCustomBlockData() as $key => $v){ + $nbt->{$key} = $v; + } + } + + Tile::createTile(Tile::ITEM_FRAME, $this->level->getChunk($this->x >> 4, $this->z >> 4), $nbt); + + return true; + + } + + public function getDrops(Item $item){ + return [ + [Item::ITEM_FRAME, 0, 1] + ]; + } + +} \ No newline at end of file diff --git a/src/pocketmine/item/Item.php b/src/pocketmine/item/Item.php index c2d18d569..fe9fdfed4 100644 --- a/src/pocketmine/item/Item.php +++ b/src/pocketmine/item/Item.php @@ -196,6 +196,7 @@ class Item implements ItemIds, \JsonSerializable{ self::$list[self::GLISTERING_MELON] = GlisteringMelon::class; self::$list[self::SPAWN_EGG] = SpawnEgg::class; self::$list[self::EMERALD] = Emerald::class; + self::$list[self::ITEM_FRAME] = ItemFrame::class; self::$list[self::FLOWER_POT] = FlowerPot::class; self::$list[self::CARROT] = Carrot::class; self::$list[self::POTATO] = Potato::class; diff --git a/src/pocketmine/item/ItemFrame.php b/src/pocketmine/item/ItemFrame.php new file mode 100644 index 000000000..a114b43ef --- /dev/null +++ b/src/pocketmine/item/ItemFrame.php @@ -0,0 +1,31 @@ +block = Block::get(Block::ITEM_FRAME_BLOCK); + parent::__construct(self::ITEM_FRAME, 0, $count, "Item Frame"); + } +} \ No newline at end of file diff --git a/src/pocketmine/tile/ItemFrame.php b/src/pocketmine/tile/ItemFrame.php index a902d83dc..d0b252e35 100644 --- a/src/pocketmine/tile/ItemFrame.php +++ b/src/pocketmine/tile/ItemFrame.php @@ -43,13 +43,6 @@ class ItemFrame extends Spawnable{ parent::__construct($chunk, $nbt); } - public function dropItem(){ - if(lcg_value() < $this->getDropChance() and $this->hasItem()){ - $this->level->dropItem($this, $this->getItem()); - } - $this->setItem(null); - } - public function hasItem() : bool{ return $this->getItem()->getId() !== Item::AIR; } @@ -103,4 +96,5 @@ class ItemFrame extends Spawnable{ } return $tag; } + } \ No newline at end of file