From b071ce9c5a6d8b47561fd65d907b843d180dd3ae Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 2 Sep 2017 11:57:26 +0100 Subject: [PATCH] Refactored projectile handling, added Item->onClickAir() --- src/pocketmine/Player.php | 48 ++-------------- src/pocketmine/item/Item.php | 14 +++++ src/pocketmine/item/ProjectileItem.php | 80 ++++++++++++++++++++++++++ src/pocketmine/item/Snowball.php | 10 +++- 4 files changed, 106 insertions(+), 46 deletions(-) create mode 100644 src/pocketmine/item/ProjectileItem.php diff --git a/src/pocketmine/Player.php b/src/pocketmine/Player.php index d30cb4074..5cb528a02 100644 --- a/src/pocketmine/Player.php +++ b/src/pocketmine/Player.php @@ -34,11 +34,9 @@ use pocketmine\entity\Entity; use pocketmine\entity\Human; use pocketmine\entity\Item as DroppedItem; use pocketmine\entity\Living; -use pocketmine\entity\Projectile; use pocketmine\event\entity\EntityDamageByBlockEvent; use pocketmine\event\entity\EntityDamageByEntityEvent; use pocketmine\event\entity\EntityDamageEvent; -use pocketmine\event\entity\ProjectileLaunchEvent; use pocketmine\event\inventory\CraftItemEvent; use pocketmine\event\inventory\InventoryCloseEvent; use pocketmine\event\inventory\InventoryPickupArrowEvent; @@ -88,7 +86,6 @@ use pocketmine\level\format\Chunk; use pocketmine\level\Level; use pocketmine\level\Location; use pocketmine\level\Position; -use pocketmine\level\sound\LaunchSound; use pocketmine\level\WeakPosition; use pocketmine\math\AxisAlignedBB; use pocketmine\math\Vector2; @@ -97,10 +94,7 @@ use pocketmine\metadata\MetadataValue; use pocketmine\nbt\NBT; use pocketmine\nbt\tag\ByteTag; use pocketmine\nbt\tag\CompoundTag; -use pocketmine\nbt\tag\DoubleTag; -use pocketmine\nbt\tag\FloatTag; use pocketmine\nbt\tag\IntTag; -use pocketmine\nbt\tag\ListTag; use pocketmine\nbt\tag\LongTag; use pocketmine\nbt\tag\StringTag; use pocketmine\network\mcpe\PlayerNetworkSessionAdapter; @@ -2382,7 +2376,7 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{ $this->level->sendBlocks([$this], [$target, $block], UpdateBlockPacket::FLAG_ALL_PRIORITY); return true; }elseif($packet->face === -1){ - $aimPos = new Vector3( + $directionVector = new Vector3( -sin($this->yaw / 180 * M_PI) * cos($this->pitch / 180 * M_PI), -sin($this->pitch / 180 * M_PI), cos($this->yaw / 180 * M_PI) * cos($this->pitch / 180 * M_PI) @@ -2397,7 +2391,7 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{ $item = $this->inventory->getItemInHand(); } - $ev = new PlayerInteractEvent($this, $item, $aimPos, $packet->face, PlayerInteractEvent::RIGHT_CLICK_AIR); + $ev = new PlayerInteractEvent($this, $item, $directionVector, $packet->face, PlayerInteractEvent::RIGHT_CLICK_AIR); $this->server->getPluginManager()->callEvent($ev); @@ -2406,42 +2400,8 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{ return true; } - if($item->getId() === Item::SNOWBALL){ - $nbt = new CompoundTag("", [ - new ListTag("Pos", [ - new DoubleTag("", $this->x), - new DoubleTag("", $this->y + $this->getEyeHeight()), - new DoubleTag("", $this->z) - ]), - new ListTag("Motion", [ - new DoubleTag("", $aimPos->x), - new DoubleTag("", $aimPos->y), - new DoubleTag("", $aimPos->z) - ]), - new ListTag("Rotation", [ - new FloatTag("", $this->yaw), - new FloatTag("", $this->pitch) - ]), - ]); - - $f = 1.5; - $snowball = Entity::createEntity("Snowball", $this->getLevel(), $nbt, $this); - $snowball->setMotion($snowball->getMotion()->multiply($f)); - if($this->isSurvival()){ - $item->setCount($item->getCount() - 1); - $this->inventory->setItemInHand($item->getCount() > 0 ? $item : ItemFactory::get(Item::AIR)); - } - if($snowball instanceof Projectile){ - $this->server->getPluginManager()->callEvent($projectileEv = new ProjectileLaunchEvent($snowball)); - if($projectileEv->isCancelled()){ - $snowball->kill(); - }else{ - $snowball->spawnToAll(); - $this->level->addSound(new LaunchSound($this), $this->getViewers()); - } - }else{ - $snowball->spawnToAll(); - } + if($item->onClickAir($this, $directionVector) and $this->isSurvival()){ + $this->inventory->setItemInHand($item); } $this->setGenericFlag(self::DATA_FLAG_ACTION, true); diff --git a/src/pocketmine/item/Item.php b/src/pocketmine/item/Item.php index 0d90a6790..8c3504193 100644 --- a/src/pocketmine/item/Item.php +++ b/src/pocketmine/item/Item.php @@ -829,8 +829,22 @@ class Item implements ItemIds, \JsonSerializable{ return false; } + /** + * Called when a player uses the item on air, for example throwing a projectile. + * Returns whether the item was changed, for example count decrease or durability change. + * + * @param Player $player + * @param Vector3 $directionVector + * + * @return bool + */ + public function onClickAir(Player $player, Vector3 $directionVector) : bool{ + return false; + } + /** * Called when a player is using this item and releases it. Used to handle bow shoot actions. + * Returns whether the item was changed, for example count decrease or durability change. * * @param Player $player * @return bool diff --git a/src/pocketmine/item/ProjectileItem.php b/src/pocketmine/item/ProjectileItem.php new file mode 100644 index 000000000..319be3864 --- /dev/null +++ b/src/pocketmine/item/ProjectileItem.php @@ -0,0 +1,80 @@ +x), + new DoubleTag("", $player->y + $player->getEyeHeight()), + new DoubleTag("", $player->z) + ]), + new ListTag("Motion", [ + new DoubleTag("", $directionVector->x), + new DoubleTag("", $directionVector->y), + new DoubleTag("", $directionVector->z) + ]), + new ListTag("Rotation", [ + new FloatTag("", $player->yaw), + new FloatTag("", $player->pitch) + ]), + ]); + + $snowball = Entity::createEntity($this->getProjectileEntityType(), $player->getLevel(), $nbt, $player); + $snowball->setMotion($snowball->getMotion()->multiply($this->getThrowForce())); + + $this->count--; + + if($snowball instanceof Projectile){ + $player->getServer()->getPluginManager()->callEvent($projectileEv = new ProjectileLaunchEvent($snowball)); + if($projectileEv->isCancelled()){ + $snowball->kill(); + }else{ + $snowball->spawnToAll(); + $player->getLevel()->addSound(new LaunchSound($player), $player->getViewers()); + } + }else{ + $snowball->spawnToAll(); + } + + return true; + } +} \ No newline at end of file diff --git a/src/pocketmine/item/Snowball.php b/src/pocketmine/item/Snowball.php index cd5abcbe4..ba58c8fbf 100644 --- a/src/pocketmine/item/Snowball.php +++ b/src/pocketmine/item/Snowball.php @@ -23,8 +23,7 @@ declare(strict_types=1); namespace pocketmine\item; - -class Snowball extends Item{ +class Snowball extends ProjectileItem{ public function __construct(int $meta = 0){ parent::__construct(self::SNOWBALL, $meta, "Snowball"); } @@ -33,4 +32,11 @@ class Snowball extends Item{ return 16; } + public function getProjectileEntityType() : string{ + return "Snowball"; + } + + public function getThrowForce() : float{ + return 1.5; + } } \ No newline at end of file