diff --git a/src/pocketmine/entity/projectile/Arrow.php b/src/pocketmine/entity/projectile/Arrow.php index 9bfab053b..bfe45c412 100644 --- a/src/pocketmine/entity/projectile/Arrow.php +++ b/src/pocketmine/entity/projectile/Arrow.php @@ -40,6 +40,12 @@ use pocketmine\Player; class Arrow extends Projectile{ public const NETWORK_ID = self::ARROW; + public const PICKUP_NONE = 0; + public const PICKUP_ANY = 1; + public const PICKUP_CREATIVE = 2; + + private const TAG_PICKUP = "pickup"; //TAG_Byte + public $width = 0.25; public $height = 0.25; @@ -48,11 +54,26 @@ class Arrow extends Projectile{ protected $damage = 2; + /** @var int */ + protected $pickupMode = self::PICKUP_ANY; + public function __construct(Level $level, CompoundTag $nbt, ?Entity $shootingEntity = null, bool $critical = false){ parent::__construct($level, $nbt, $shootingEntity); $this->setCritical($critical); } + protected function initEntity() : void{ + parent::initEntity(); + + $this->pickupMode = $this->namedtag->getByte(self::TAG_PICKUP, self::PICKUP_ANY, true); + } + + public function saveNBT() : void{ + parent::saveNBT(); + + $this->namedtag->setByte(self::TAG_PICKUP, $this->pickupMode, true); + } + public function isCritical() : bool{ return $this->getGenericFlag(self::DATA_FLAG_CRITICAL); } @@ -95,6 +116,20 @@ class Arrow extends Projectile{ $this->broadcastEntityEvent(EntityEventPacket::ARROW_SHAKE, 7); //7 ticks } + /** + * @return int + */ + public function getPickupMode() : int{ + return $this->pickupMode; + } + + /** + * @param int $pickupMode + */ + public function setPickupMode(int $pickupMode) : void{ + $this->pickupMode = $pickupMode; + } + public function onCollideWithPlayer(Player $player) : void{ if($this->blockHit === null){ return; @@ -107,7 +142,12 @@ class Arrow extends Projectile{ return; } - $this->server->getPluginManager()->callEvent($ev = new InventoryPickupArrowEvent($playerInventory, $this)); + $ev = new InventoryPickupArrowEvent($playerInventory, $this); + if($this->pickupMode === self::PICKUP_NONE or ($this->pickupMode === self::PICKUP_CREATIVE and !$player->isCreative())){ + $ev->setCancelled(); + } + + $this->server->getPluginManager()->callEvent($ev); if($ev->isCancelled()){ return; }