From aa911835045c74a9360125a98e7222da35159b64 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 8 Oct 2017 15:54:31 +0100 Subject: [PATCH] Added Durable class, fixed some tools not breaking correctly, removed some boilerplate code --- src/pocketmine/Player.php | 8 +--- src/pocketmine/item/Bow.php | 7 +-- src/pocketmine/item/Durable.php | 77 ++++++++++++++++++++++++++++++ src/pocketmine/item/FlintSteel.php | 9 +--- src/pocketmine/item/Item.php | 2 + src/pocketmine/item/Tool.php | 17 +++---- src/pocketmine/level/Level.php | 9 +--- 7 files changed, 90 insertions(+), 39 deletions(-) create mode 100644 src/pocketmine/item/Durable.php diff --git a/src/pocketmine/Player.php b/src/pocketmine/Player.php index dc87d7863..2a74cbe36 100644 --- a/src/pocketmine/Player.php +++ b/src/pocketmine/Player.php @@ -2512,12 +2512,8 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{ } if($this->isSurvival()){ - if($heldItem->isTool()){ - if($heldItem->useOn($target) and $heldItem->getDamage() >= $heldItem->getMaxDurability()){ - $this->inventory->setItemInHand(ItemFactory::get(Item::AIR, 0, 0)); - }else{ - $this->inventory->setItemInHand($heldItem); - } + if($heldItem->useOn($target)){ + $this->inventory->setItemInHand($heldItem); } $this->exhaust(0.3, PlayerExhaustEvent::CAUSE_ATTACK); diff --git a/src/pocketmine/item/Bow.php b/src/pocketmine/item/Bow.php index 5ff357c7f..b6c37c93e 100644 --- a/src/pocketmine/item/Bow.php +++ b/src/pocketmine/item/Bow.php @@ -99,12 +99,7 @@ class Bow extends Tool{ $entity->setMotion($entity->getMotion()->multiply($ev->getForce())); if($player->isSurvival()){ $player->getInventory()->removeItem(ItemFactory::get(Item::ARROW, 0, 1)); - $this->setDamage($this->getDamage() + 1); - if($this->getDamage() >= $this->getMaxDurability()){ - $player->getInventory()->setItemInHand(ItemFactory::get(Item::AIR, 0, 0)); - }else{ - $player->getInventory()->setItemInHand($this); - } + $this->applyDamage(1); } if($entity instanceof Projectile){ diff --git a/src/pocketmine/item/Durable.php b/src/pocketmine/item/Durable.php new file mode 100644 index 000000000..d2cab69fc --- /dev/null +++ b/src/pocketmine/item/Durable.php @@ -0,0 +1,77 @@ +getNamedTagEntry("Unbreakable"); + return $tag !== null and $tag->getValue() !== 0; + } + + /** + * Sets whether the item will take damage when used. + * @param bool $value + */ + public function setUnbreakable(bool $value = true){ + $this->setNamedTagEntry(new ByteTag("Unbreakable", $value ? 1 : 0)); + } + + /** + * Applies damage to the item. + * @param int $amount + * + * @return bool if any damage was applied to the item + */ + public function applyDamage(int $amount) : bool{ + if($this->isUnbreakable() or $this->isBroken()){ + return false; + } + + //TODO: Unbreaking enchantment + + $this->meta += $amount; + if($this->isBroken()){ + $this->pop(); + } + + return true; + } + + /** + * Returns whether the item is broken. + * @return bool + */ + public function isBroken() : bool{ + return $this->meta >= $this->getMaxDurability(); + } +} \ No newline at end of file diff --git a/src/pocketmine/item/FlintSteel.php b/src/pocketmine/item/FlintSteel.php index 967fd0e56..573bb4606 100644 --- a/src/pocketmine/item/FlintSteel.php +++ b/src/pocketmine/item/FlintSteel.php @@ -41,14 +41,7 @@ class FlintSteel extends Tool{ $level->setBlock($block, BlockFactory::get(Block::FIRE), true); $level->broadcastLevelSoundEvent($block->add(0.5, 0.5, 0.5), LevelSoundEventPacket::SOUND_IGNITE); - if(($player->gamemode & 0x01) === 0 and $this->useOn($block)){ - if($this->getDamage() >= $this->getMaxDurability()){ - $player->getInventory()->setItemInHand(Item::get(Item::AIR, 0, 0)); - }else{ - $this->meta++; - $player->getInventory()->setItemInHand($this); - } - } + $this->applyDamage(1); return true; } diff --git a/src/pocketmine/item/Item.php b/src/pocketmine/item/Item.php index c0997258e..3dbd9c269 100644 --- a/src/pocketmine/item/Item.php +++ b/src/pocketmine/item/Item.php @@ -763,6 +763,8 @@ class Item implements ItemIds, \JsonSerializable{ } /** + * Returns the maximum amount of damage this item can take before it breaks. + * * @return int|bool */ public function getMaxDurability(){ diff --git a/src/pocketmine/item/Tool.php b/src/pocketmine/item/Tool.php index fe6376f1d..329824b7e 100644 --- a/src/pocketmine/item/Tool.php +++ b/src/pocketmine/item/Tool.php @@ -26,7 +26,7 @@ namespace pocketmine\item; use pocketmine\block\Block; use pocketmine\entity\Entity; -abstract class Tool extends Item{ +abstract class Tool extends Durable{ const TIER_WOODEN = 1; const TIER_GOLD = 2; const TIER_STONE = 3; @@ -64,18 +64,18 @@ abstract class Tool extends Item{ $object->getToolType() === Tool::TYPE_SWORD and $this->isSword() or $object->getToolType() === Tool::TYPE_SHEARS and $this->isShears() ){ - $this->meta++; + $this->applyDamage(1); }elseif(!$this->isShears() and $object->getBreakTime($this) > 0){ - $this->meta += 2; + $this->applyDamage(2); } }elseif($this->isHoe()){ if(($object instanceof Block) and ($object->getId() === self::GRASS or $object->getId() === self::DIRT)){ - $this->meta++; + $this->applyDamage(1); } }elseif(($object instanceof Entity) and !$this->isSword()){ - $this->meta += 2; + $this->applyDamage(2); }else{ - $this->meta++; + $this->applyDamage(1); } return true; @@ -111,11 +111,6 @@ abstract class Tool extends Item{ return $levels[$type]; } - public function isUnbreakable(){ - $tag = $this->getNamedTagEntry("Unbreakable"); - return $tag !== null and $tag->getValue() > 0; - } - public function isTool(){ return true; } diff --git a/src/pocketmine/level/Level.php b/src/pocketmine/level/Level.php index e86fbe289..8b0d436b7 100644 --- a/src/pocketmine/level/Level.php +++ b/src/pocketmine/level/Level.php @@ -1692,9 +1692,6 @@ class Level implements ChunkManager, Metadatable{ if($item !== null){ $item->useOn($target); - if($item->isTool() and $item->getDamage() >= $item->getMaxDurability()){ - $item = ItemFactory::get(Item::AIR, 0, 0); - } } if($player === null or $player->isSurvival()){ @@ -1769,11 +1766,7 @@ class Level implements ChunkManager, Metadatable{ } if(!$player->isSneaking() and $item->onActivate($this, $player, $blockReplace, $blockClicked, $face, $facePos)){ - if($item->getCount() <= 0){ - $item = ItemFactory::get(Item::AIR, 0, 0); - - return true; - } + return true; } }else{ return false;