diff --git a/src/pocketmine/entity/Living.php b/src/pocketmine/entity/Living.php index 83aa249a1..fdb5546c7 100644 --- a/src/pocketmine/entity/Living.php +++ b/src/pocketmine/entity/Living.php @@ -44,6 +44,7 @@ use pocketmine\nbt\tag\FloatTag; use pocketmine\nbt\tag\IntTag; use pocketmine\nbt\tag\ListTag; use pocketmine\network\mcpe\protocol\EntityEventPacket; +use pocketmine\network\mcpe\protocol\LevelSoundEventPacket; use pocketmine\network\mcpe\protocol\MobEffectPacket; use pocketmine\Player; use pocketmine\utils\Binary; @@ -466,6 +467,29 @@ abstract class Living extends Entity implements Damageable{ */ protected function applyPostDamageEffects(EntityDamageEvent $source) : void{ $this->setAbsorption(max(0, $this->getAbsorption() + $source->getDamage(EntityDamageEvent::MODIFIER_ABSORPTION))); + $this->damageArmor($source->getDamage(EntityDamageEvent::MODIFIER_BASE)); + } + + /** + * Damages the worn armour according to the amount of damage given. Each 4 points (rounded down) deals 1 damage + * point to each armour piece, but never less than 1 total. + * + * @param float $damage + */ + public function damageArmor(float $damage) : void{ + $durabilityRemoved = (int) max(floor($damage / 4), 1); + + $armor = $this->armorInventory->getContents(true); + foreach($armor as $item){ + if($item instanceof Armor){ + $item->applyDamage($durabilityRemoved); + if($item->isBroken()){ + $this->level->broadcastLevelSoundEvent($this, LevelSoundEventPacket::SOUND_BREAK); + } + } + } + + $this->armorInventory->setContents($armor); } public function attack(EntityDamageEvent $source){ diff --git a/src/pocketmine/item/Armor.php b/src/pocketmine/item/Armor.php index 7ca373820..85c3db956 100644 --- a/src/pocketmine/item/Armor.php +++ b/src/pocketmine/item/Armor.php @@ -25,12 +25,13 @@ declare(strict_types=1); namespace pocketmine\item; use pocketmine\event\entity\EntityDamageEvent; +use pocketmine\item\enchantment\Enchantment; use pocketmine\item\enchantment\ProtectionEnchantment; use pocketmine\nbt\tag\IntTag; use pocketmine\utils\Binary; use pocketmine\utils\Color; -abstract class Armor extends Item{ +abstract class Armor extends Durable{ public const TAG_CUSTOM_COLOR = "customColor"; //TAG_Int @@ -78,4 +79,21 @@ abstract class Armor extends Item{ return $epf; } + + protected function getUnbreakingDamageReduction(int $amount) : int{ + if(($unbreakingLevel = $this->getEnchantmentLevel(Enchantment::UNBREAKING)) > 0){ + $negated = 0; + + $chance = 1 / ($unbreakingLevel + 1); + for($i = 0; $i < $amount; ++$i){ + if(mt_rand(1, 100) > 60 and lcg_value() > $chance){ //unbreaking only applies to armor 40% of the time at best + $negated++; + } + } + + return $negated; + } + + return 0; + } } diff --git a/src/pocketmine/item/ChainBoots.php b/src/pocketmine/item/ChainBoots.php index 25dfadfa1..141aefc8c 100644 --- a/src/pocketmine/item/ChainBoots.php +++ b/src/pocketmine/item/ChainBoots.php @@ -32,4 +32,8 @@ class ChainBoots extends Armor{ public function getDefensePoints() : int{ return 1; } + + public function getMaxDurability() : int{ + return 196; + } } diff --git a/src/pocketmine/item/ChainChestplate.php b/src/pocketmine/item/ChainChestplate.php index 30dbb6ee7..2f1453fc9 100644 --- a/src/pocketmine/item/ChainChestplate.php +++ b/src/pocketmine/item/ChainChestplate.php @@ -32,4 +32,8 @@ class ChainChestplate extends Armor{ public function getDefensePoints() : int{ return 5; } + + public function getMaxDurability() : int{ + return 241; + } } diff --git a/src/pocketmine/item/ChainHelmet.php b/src/pocketmine/item/ChainHelmet.php index ab55b6262..b949a72ff 100644 --- a/src/pocketmine/item/ChainHelmet.php +++ b/src/pocketmine/item/ChainHelmet.php @@ -32,4 +32,8 @@ class ChainHelmet extends Armor{ public function getDefensePoints() : int{ return 2; } + + public function getMaxDurability() : int{ + return 166; + } } diff --git a/src/pocketmine/item/ChainLeggings.php b/src/pocketmine/item/ChainLeggings.php index 01718ace1..e4882f06b 100644 --- a/src/pocketmine/item/ChainLeggings.php +++ b/src/pocketmine/item/ChainLeggings.php @@ -32,4 +32,8 @@ class ChainLeggings extends Armor{ public function getDefensePoints() : int{ return 4; } + + public function getMaxDurability() : int{ + return 226; + } } diff --git a/src/pocketmine/item/DiamondBoots.php b/src/pocketmine/item/DiamondBoots.php index 1dab525f1..25b79761d 100644 --- a/src/pocketmine/item/DiamondBoots.php +++ b/src/pocketmine/item/DiamondBoots.php @@ -32,4 +32,8 @@ class DiamondBoots extends Armor{ public function getDefensePoints() : int{ return 3; } + + public function getMaxDurability() : int{ + return 430; + } } diff --git a/src/pocketmine/item/DiamondChestplate.php b/src/pocketmine/item/DiamondChestplate.php index 91ce11a9c..778aa6ba9 100644 --- a/src/pocketmine/item/DiamondChestplate.php +++ b/src/pocketmine/item/DiamondChestplate.php @@ -32,4 +32,8 @@ class DiamondChestplate extends Armor{ public function getDefensePoints() : int{ return 8; } + + public function getMaxDurability() : int{ + return 529; + } } diff --git a/src/pocketmine/item/DiamondHelmet.php b/src/pocketmine/item/DiamondHelmet.php index 64215d743..c5f652cc6 100644 --- a/src/pocketmine/item/DiamondHelmet.php +++ b/src/pocketmine/item/DiamondHelmet.php @@ -32,4 +32,8 @@ class DiamondHelmet extends Armor{ public function getDefensePoints() : int{ return 3; } + + public function getMaxDurability() : int{ + return 364; + } } diff --git a/src/pocketmine/item/DiamondLeggings.php b/src/pocketmine/item/DiamondLeggings.php index 2d0b42bc2..6f7613c6f 100644 --- a/src/pocketmine/item/DiamondLeggings.php +++ b/src/pocketmine/item/DiamondLeggings.php @@ -32,4 +32,8 @@ class DiamondLeggings extends Armor{ public function getDefensePoints() : int{ return 6; } + + public function getMaxDurability() : int{ + return 496; + } } diff --git a/src/pocketmine/item/GoldBoots.php b/src/pocketmine/item/GoldBoots.php index da179e5d6..cb039b52d 100644 --- a/src/pocketmine/item/GoldBoots.php +++ b/src/pocketmine/item/GoldBoots.php @@ -32,4 +32,8 @@ class GoldBoots extends Armor{ public function getDefensePoints() : int{ return 1; } + + public function getMaxDurability() : int{ + return 92; + } } diff --git a/src/pocketmine/item/GoldChestplate.php b/src/pocketmine/item/GoldChestplate.php index c04f4f15b..74bed00ac 100644 --- a/src/pocketmine/item/GoldChestplate.php +++ b/src/pocketmine/item/GoldChestplate.php @@ -32,4 +32,8 @@ class GoldChestplate extends Armor{ public function getDefensePoints() : int{ return 5; } + + public function getMaxDurability() : int{ + return 113; + } } diff --git a/src/pocketmine/item/GoldHelmet.php b/src/pocketmine/item/GoldHelmet.php index 00a456177..043c363a2 100644 --- a/src/pocketmine/item/GoldHelmet.php +++ b/src/pocketmine/item/GoldHelmet.php @@ -32,4 +32,8 @@ class GoldHelmet extends Armor{ public function getDefensePoints() : int{ return 2; } + + public function getMaxDurability() : int{ + return 78; + } } diff --git a/src/pocketmine/item/GoldLeggings.php b/src/pocketmine/item/GoldLeggings.php index 8b740f3eb..47b675259 100644 --- a/src/pocketmine/item/GoldLeggings.php +++ b/src/pocketmine/item/GoldLeggings.php @@ -32,4 +32,8 @@ class GoldLeggings extends Armor{ public function getDefensePoints() : int{ return 3; } + + public function getMaxDurability() : int{ + return 106; + } } diff --git a/src/pocketmine/item/IronBoots.php b/src/pocketmine/item/IronBoots.php index fbb3f725b..a11639468 100644 --- a/src/pocketmine/item/IronBoots.php +++ b/src/pocketmine/item/IronBoots.php @@ -32,4 +32,8 @@ class IronBoots extends Armor{ public function getDefensePoints() : int{ return 2; } + + public function getMaxDurability() : int{ + return 196; + } } diff --git a/src/pocketmine/item/IronChestplate.php b/src/pocketmine/item/IronChestplate.php index 886c7e435..2cb881478 100644 --- a/src/pocketmine/item/IronChestplate.php +++ b/src/pocketmine/item/IronChestplate.php @@ -32,4 +32,8 @@ class IronChestplate extends Armor{ public function getDefensePoints() : int{ return 6; } + + public function getMaxDurability() : int{ + return 241; + } } diff --git a/src/pocketmine/item/IronHelmet.php b/src/pocketmine/item/IronHelmet.php index 936370d14..74875d29e 100644 --- a/src/pocketmine/item/IronHelmet.php +++ b/src/pocketmine/item/IronHelmet.php @@ -32,4 +32,8 @@ class IronHelmet extends Armor{ public function getDefensePoints() : int{ return 2; } + + public function getMaxDurability() : int{ + return 166; + } } diff --git a/src/pocketmine/item/IronLeggings.php b/src/pocketmine/item/IronLeggings.php index 0494db868..655248f99 100644 --- a/src/pocketmine/item/IronLeggings.php +++ b/src/pocketmine/item/IronLeggings.php @@ -32,4 +32,8 @@ class IronLeggings extends Armor{ public function getDefensePoints() : int{ return 5; } + + public function getMaxDurability() : int{ + return 226; + } } diff --git a/src/pocketmine/item/LeatherBoots.php b/src/pocketmine/item/LeatherBoots.php index 397b55b0c..4c93de806 100644 --- a/src/pocketmine/item/LeatherBoots.php +++ b/src/pocketmine/item/LeatherBoots.php @@ -32,4 +32,8 @@ class LeatherBoots extends Armor{ public function getDefensePoints() : int{ return 1; } + + public function getMaxDurability() : int{ + return 66; + } } diff --git a/src/pocketmine/item/LeatherCap.php b/src/pocketmine/item/LeatherCap.php index 9877d979b..3b2c0653d 100644 --- a/src/pocketmine/item/LeatherCap.php +++ b/src/pocketmine/item/LeatherCap.php @@ -32,4 +32,8 @@ class LeatherCap extends Armor{ public function getDefensePoints() : int{ return 1; } + + public function getMaxDurability() : int{ + return 56; + } } diff --git a/src/pocketmine/item/LeatherPants.php b/src/pocketmine/item/LeatherPants.php index 4f7301012..05ee76ca7 100644 --- a/src/pocketmine/item/LeatherPants.php +++ b/src/pocketmine/item/LeatherPants.php @@ -32,4 +32,8 @@ class LeatherPants extends Armor{ public function getDefensePoints() : int{ return 2; } + + public function getMaxDurability() : int{ + return 76; + } } diff --git a/src/pocketmine/item/LeatherTunic.php b/src/pocketmine/item/LeatherTunic.php index ce83c351d..d587f2eaa 100644 --- a/src/pocketmine/item/LeatherTunic.php +++ b/src/pocketmine/item/LeatherTunic.php @@ -32,4 +32,8 @@ class LeatherTunic extends Armor{ public function getDefensePoints() : int{ return 3; } + + public function getMaxDurability() : int{ + return 81; + } }