From 056d24c67dc2c2d330100b55f23566c3efa7d1c3 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Fri, 22 Jun 2018 19:39:18 +0100 Subject: [PATCH 01/10] Add MUTTON as an ID constant fixes crashdump #518862 - Unable to resolve "minecraft:mutton" to a valid item PC refers to these as just mutton, but PE calls them muttonraw --- src/pocketmine/item/ItemIds.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pocketmine/item/ItemIds.php b/src/pocketmine/item/ItemIds.php index 2fe989bb2..79cfb00e5 100644 --- a/src/pocketmine/item/ItemIds.php +++ b/src/pocketmine/item/ItemIds.php @@ -193,7 +193,7 @@ interface ItemIds extends BlockIds{ public const LEAD = 420; public const NAMETAG = 421, NAME_TAG = 421; public const PRISMARINE_CRYSTALS = 422; - public const MUTTONRAW = 423, MUTTON_RAW = 423, RAW_MUTTON = 423; + public const MUTTON = 423, MUTTONRAW = 423, MUTTON_RAW = 423, RAW_MUTTON = 423; public const COOKED_MUTTON = 424, MUTTONCOOKED = 424, MUTTON_COOKED = 424; public const ARMOR_STAND = 425; public const END_CRYSTAL = 426; From 87852f2fe175ad22a85e1225150f1bf342f2f7ae Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Fri, 22 Jun 2018 21:31:22 +0100 Subject: [PATCH 02/10] EmeraldOre: remove excess indentation --- src/pocketmine/block/EmeraldOre.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pocketmine/block/EmeraldOre.php b/src/pocketmine/block/EmeraldOre.php index 7e790702a..e6d6cfbe6 100644 --- a/src/pocketmine/block/EmeraldOre.php +++ b/src/pocketmine/block/EmeraldOre.php @@ -53,7 +53,7 @@ class EmeraldOre extends Solid{ public function getDropsForCompatibleTool(Item $item) : array{ return [ - ItemFactory::get(Item::EMERALD) + ItemFactory::get(Item::EMERALD) ]; } } From dd6b5902a6537f37eda563c3de7496f550d9c836 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Fri, 22 Jun 2018 21:35:58 +0100 Subject: [PATCH 03/10] EmeraldOre: fixed not dropping XP on break --- src/pocketmine/block/EmeraldOre.php | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/pocketmine/block/EmeraldOre.php b/src/pocketmine/block/EmeraldOre.php index e6d6cfbe6..7dcbcde65 100644 --- a/src/pocketmine/block/EmeraldOre.php +++ b/src/pocketmine/block/EmeraldOre.php @@ -56,4 +56,8 @@ class EmeraldOre extends Solid{ ItemFactory::get(Item::EMERALD) ]; } + + protected function getXpDropAmount() : int{ + return mt_rand(3, 7); + } } From f1970492c10591dcecc72a0cada6f7cf1cbfa8d5 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 23 Jun 2018 10:38:58 +0100 Subject: [PATCH 04/10] Projectile: added API to modify projectile base damage multiplier This adds two new methods: - Projectile->getBaseDamage() - Projectile->setBaseDamage() --- src/pocketmine/entity/projectile/Arrow.php | 3 ++- .../entity/projectile/Projectile.php | 22 ++++++++++++++++++- 2 files changed, 23 insertions(+), 2 deletions(-) diff --git a/src/pocketmine/entity/projectile/Arrow.php b/src/pocketmine/entity/projectile/Arrow.php index bfe45c412..5842149a9 100644 --- a/src/pocketmine/entity/projectile/Arrow.php +++ b/src/pocketmine/entity/projectile/Arrow.php @@ -52,7 +52,8 @@ class Arrow extends Projectile{ protected $gravity = 0.05; protected $drag = 0.01; - protected $damage = 2; + /** @var float */ + protected $damage = 2.0; /** @var int */ protected $pickupMode = self::PICKUP_ANY; diff --git a/src/pocketmine/entity/projectile/Projectile.php b/src/pocketmine/entity/projectile/Projectile.php index 7cd579690..0daf7039d 100644 --- a/src/pocketmine/entity/projectile/Projectile.php +++ b/src/pocketmine/entity/projectile/Projectile.php @@ -46,7 +46,8 @@ abstract class Projectile extends Entity{ public const DATA_SHOOTER_ID = 17; - protected $damage = 0; + /** @var float */ + protected $damage = 0.0; /** @var Vector3|null */ protected $blockHit; @@ -112,6 +113,25 @@ abstract class Projectile extends Entity{ return false; } + /** + * Returns the base damage applied on collision. This is multiplied by the projectile's speed to give a result + * damage. + * + * @return float + */ + public function getBaseDamage() : float{ + return $this->damage; + } + + /** + * Sets the base amount of damage applied by the projectile. + * + * @param float $damage + */ + public function setBaseDamage(float $damage) : void{ + $this->damage = $damage; + } + /** * Returns the amount of damage this projectile will deal to the entity it hits. * @return int From b393f5f17e116c745ceecc9f184104e4abb0fe32 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 23 Jun 2018 10:41:04 +0100 Subject: [PATCH 05/10] Projectile: ensure that damage multiplier gets saved and restored --- src/pocketmine/entity/projectile/Projectile.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/pocketmine/entity/projectile/Projectile.php b/src/pocketmine/entity/projectile/Projectile.php index 0daf7039d..768334c05 100644 --- a/src/pocketmine/entity/projectile/Projectile.php +++ b/src/pocketmine/entity/projectile/Projectile.php @@ -75,6 +75,7 @@ abstract class Projectile extends Entity{ $this->setMaxHealth(1); $this->setHealth(1); $this->age = $this->namedtag->getShort("Age", $this->age); + $this->damage = $this->namedtag->getDouble("damage", $this->damage); do{ $blockHit = null; @@ -144,6 +145,7 @@ abstract class Projectile extends Entity{ parent::saveNBT(); $this->namedtag->setShort("Age", $this->age); + $this->namedtag->setDouble("damage", $this->damage); if($this->blockHit !== null){ $this->namedtag->setInt("tileX", $this->blockHit->x); From 814a94958018dd7b78d5a0f00307bbe37eb2d9b0 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 23 Jun 2018 11:39:39 +0100 Subject: [PATCH 06/10] Implemented Power enchantment --- src/pocketmine/item/Bow.php | 4 ++++ src/pocketmine/item/enchantment/Enchantment.php | 2 ++ 2 files changed, 6 insertions(+) diff --git a/src/pocketmine/item/Bow.php b/src/pocketmine/item/Bow.php index 5807401ad..75ea0334d 100644 --- a/src/pocketmine/item/Bow.php +++ b/src/pocketmine/item/Bow.php @@ -27,6 +27,7 @@ use pocketmine\entity\Entity; use pocketmine\entity\projectile\Projectile; use pocketmine\event\entity\EntityShootBowEvent; use pocketmine\event\entity\ProjectileLaunchEvent; +use pocketmine\item\enchantment\Enchantment; use pocketmine\network\mcpe\protocol\LevelSoundEventPacket; use pocketmine\Player; @@ -64,6 +65,9 @@ class Bow extends Tool{ $entity = Entity::createEntity("Arrow", $player->getLevel(), $nbt, $player, $force == 2); if($entity instanceof Projectile){ + if(($powerLevel = $this->getEnchantmentLevel(Enchantment::POWER)) > 0){ + $entity->setBaseDamage($entity->getBaseDamage() + (($powerLevel + 1) / 2)); + } $ev = new EntityShootBowEvent($player, $this, $entity, $force); if($force < 0.1 or $diff < 5){ diff --git a/src/pocketmine/item/enchantment/Enchantment.php b/src/pocketmine/item/enchantment/Enchantment.php index 8b4fca982..35fa10c2c 100644 --- a/src/pocketmine/item/enchantment/Enchantment.php +++ b/src/pocketmine/item/enchantment/Enchantment.php @@ -121,6 +121,8 @@ class Enchantment{ self::registerEnchantment(new Enchantment(self::SILK_TOUCH, "%enchantment.untouching", self::RARITY_MYTHIC, self::SLOT_DIG, self::SLOT_SHEARS, 1)); self::registerEnchantment(new Enchantment(self::UNBREAKING, "%enchantment.durability", self::RARITY_UNCOMMON, self::SLOT_DIG | self::SLOT_ARMOR | self::SLOT_FISHING_ROD | self::SLOT_BOW, self::SLOT_TOOL | self::SLOT_CARROT_STICK | self::SLOT_ELYTRA, 3)); + self::registerEnchantment(new Enchantment(self::POWER, "%enchantment.arrowDamage", self::RARITY_COMMON, self::SLOT_BOW, self::SLOT_NONE, 5)); + self::registerEnchantment(new Enchantment(self::VANISHING, "%enchantment.curse.vanishing", self::RARITY_MYTHIC, self::SLOT_NONE, self::SLOT_ALL, 1)); } From 1c0b49343c82c833dff08fe40256b495be8ce3e6 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 23 Jun 2018 11:44:35 +0100 Subject: [PATCH 07/10] Implemented Infinity enchantment (#2259) --- src/pocketmine/item/Bow.php | 9 ++++++++- src/pocketmine/item/enchantment/Enchantment.php | 2 ++ 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/src/pocketmine/item/Bow.php b/src/pocketmine/item/Bow.php index 75ea0334d..39e11a4c1 100644 --- a/src/pocketmine/item/Bow.php +++ b/src/pocketmine/item/Bow.php @@ -24,6 +24,7 @@ declare(strict_types=1); namespace pocketmine\item; use pocketmine\entity\Entity; +use pocketmine\entity\projectile\Arrow as ArrowEntity; use pocketmine\entity\projectile\Projectile; use pocketmine\event\entity\EntityShootBowEvent; use pocketmine\event\entity\ProjectileLaunchEvent; @@ -65,6 +66,10 @@ class Bow extends Tool{ $entity = Entity::createEntity("Arrow", $player->getLevel(), $nbt, $player, $force == 2); if($entity instanceof Projectile){ + $infinity = $this->hasEnchantment(Enchantment::INFINITY); + if($infinity and $entity instanceof ArrowEntity){ + $entity->setPickupMode(ArrowEntity::PICKUP_CREATIVE); + } if(($powerLevel = $this->getEnchantmentLevel(Enchantment::POWER)) > 0){ $entity->setBaseDamage($entity->getBaseDamage() + (($powerLevel + 1) / 2)); } @@ -84,7 +89,9 @@ class Bow extends Tool{ }else{ $entity->setMotion($entity->getMotion()->multiply($ev->getForce())); if($player->isSurvival()){ - $player->getInventory()->removeItem(ItemFactory::get(Item::ARROW, 0, 1)); + if(!$infinity){ //TODO: tipped arrows are still consumed when Infinity is applied + $player->getInventory()->removeItem(ItemFactory::get(Item::ARROW, 0, 1)); + } $this->applyDamage(1); } diff --git a/src/pocketmine/item/enchantment/Enchantment.php b/src/pocketmine/item/enchantment/Enchantment.php index 35fa10c2c..9d40e7758 100644 --- a/src/pocketmine/item/enchantment/Enchantment.php +++ b/src/pocketmine/item/enchantment/Enchantment.php @@ -123,6 +123,8 @@ class Enchantment{ self::registerEnchantment(new Enchantment(self::POWER, "%enchantment.arrowDamage", self::RARITY_COMMON, self::SLOT_BOW, self::SLOT_NONE, 5)); + self::registerEnchantment(new Enchantment(self::INFINITY, "%enchantment.arrowInfinite", self::RARITY_MYTHIC, self::SLOT_BOW, self::SLOT_NONE, 1)); + self::registerEnchantment(new Enchantment(self::VANISHING, "%enchantment.curse.vanishing", self::RARITY_MYTHIC, self::SLOT_NONE, self::SLOT_ALL, 1)); } From 860c20109bab3eedd8a6fc03952370fa2ea5c886 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 23 Jun 2018 12:54:21 +0100 Subject: [PATCH 08/10] TNT can now be ignited by burning arrows --- src/pocketmine/block/TNT.php | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/src/pocketmine/block/TNT.php b/src/pocketmine/block/TNT.php index 7666fd91f..5ebae29cd 100644 --- a/src/pocketmine/block/TNT.php +++ b/src/pocketmine/block/TNT.php @@ -24,6 +24,7 @@ declare(strict_types=1); namespace pocketmine\block; use pocketmine\entity\Entity; +use pocketmine\entity\projectile\Arrow; use pocketmine\item\FlintSteel; use pocketmine\item\Item; use pocketmine\math\Vector3; @@ -56,6 +57,16 @@ class TNT extends Solid{ return false; } + public function hasEntityCollision() : bool{ + return true; + } + + public function onEntityCollide(Entity $entity) : void{ + if($entity instanceof Arrow and $entity->isOnFire()){ + $this->ignite(); + } + } + public function ignite(int $fuse = 80){ $this->getLevel()->setBlock($this, BlockFactory::get(Block::AIR), true); From 47c862bc38b08543be51b502aa15d5234a594b1a Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 23 Jun 2018 12:57:13 +0100 Subject: [PATCH 09/10] Projectile: check for blockhit change on nearby blockupdate --- src/pocketmine/entity/projectile/Projectile.php | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/src/pocketmine/entity/projectile/Projectile.php b/src/pocketmine/entity/projectile/Projectile.php index 768334c05..66c0a1433 100644 --- a/src/pocketmine/entity/projectile/Projectile.php +++ b/src/pocketmine/entity/projectile/Projectile.php @@ -162,17 +162,19 @@ abstract class Projectile extends Entity{ return true; } - public function hasMovementUpdate() : bool{ - $parent = parent::hasMovementUpdate(); - if($parent and $this->blockHit !== null){ + public function onNearbyBlockChange() : void{ + if($this->blockHit !== null){ $blockIn = $this->level->getBlockAt($this->blockHit->x, $this->blockHit->y, $this->blockHit->z); - - if($blockIn->getId() === $this->blockHitId and $blockIn->getDamage() === $this->blockHitData){ - return false; + if($blockIn->getId() !== $this->blockHitId or $blockIn->getDamage() !== $this->blockHitData){ + $this->blockHit = $this->blockHitId = $this->blockHitData = null; } } - return $parent; + parent::onNearbyBlockChange(); + } + + public function hasMovementUpdate() : bool{ + return $this->blockHit === null and parent::hasMovementUpdate(); } public function move(float $dx, float $dy, float $dz) : void{ From 76174f192036cad1436e9f8f085d92bf3f472db0 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 23 Jun 2018 13:02:19 +0100 Subject: [PATCH 10/10] Explosion: avoid leaving arrows stuck in nonexistent blocks --- src/pocketmine/level/Explosion.php | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/pocketmine/level/Explosion.php b/src/pocketmine/level/Explosion.php index 49300a66f..cc45e2082 100644 --- a/src/pocketmine/level/Explosion.php +++ b/src/pocketmine/level/Explosion.php @@ -236,6 +236,9 @@ class Explosion{ if(!isset($this->affectedBlocks[$index = Level::blockHash($sideBlock->x, $sideBlock->y, $sideBlock->z)]) and !isset($updateBlocks[$index])){ $this->level->getServer()->getPluginManager()->callEvent($ev = new BlockUpdateEvent($this->level->getBlockAt($sideBlock->x, $sideBlock->y, $sideBlock->z))); if(!$ev->isCancelled()){ + foreach($this->level->getNearbyEntities(new AxisAlignedBB($sideBlock->x - 1, $sideBlock->y - 1, $sideBlock->z - 1, $sideBlock->x + 2, $sideBlock->y + 2, $sideBlock->z + 2)) as $entity){ + $entity->onNearbyBlockChange(); + } $ev->getBlock()->onNearbyBlockChange(); } $updateBlocks[$index] = true;