From 2f70a1eefb801341cbc374bf4981f8050f99df4d Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 23 Jun 2018 13:36:58 +0100 Subject: [PATCH] Implemented Thorns enchantment (#2258) This implementation is rough and can probably be improved to make it extendable, but this works for now and can be improved later. --- src/pocketmine/entity/Living.php | 33 ++++++++++++++++--- .../item/enchantment/Enchantment.php | 2 +- 2 files changed, 30 insertions(+), 5 deletions(-) diff --git a/src/pocketmine/entity/Living.php b/src/pocketmine/entity/Living.php index 6202e9ee4..c4a354b13 100644 --- a/src/pocketmine/entity/Living.php +++ b/src/pocketmine/entity/Living.php @@ -34,6 +34,7 @@ use pocketmine\inventory\ArmorInventory; use pocketmine\inventory\ArmorInventoryEventProcessor; use pocketmine\item\Armor; use pocketmine\item\Consumable; +use pocketmine\item\Durable; use pocketmine\item\enchantment\Enchantment; use pocketmine\item\Item; use pocketmine\math\Vector3; @@ -476,6 +477,26 @@ abstract class Living extends Entity implements Damageable{ protected function applyPostDamageEffects(EntityDamageEvent $source) : void{ $this->setAbsorption(max(0, $this->getAbsorption() + $source->getModifier(EntityDamageEvent::MODIFIER_ABSORPTION))); $this->damageArmor($source->getBaseDamage()); + + if($source instanceof EntityDamageByEntityEvent){ + $damage = 0; + foreach($this->armorInventory->getContents() as $k => $item){ + if($item instanceof Armor and ($thornsLevel = $item->getEnchantmentLevel(Enchantment::THORNS)) > 0){ + if(mt_rand(0, 99) < $thornsLevel * 15){ + $this->damageItem($item, 3); + $damage += ($thornsLevel > 10 ? $thornsLevel - 10 : 1 + mt_rand(0, 3)); + }else{ + $this->damageItem($item, 1); //thorns causes an extra +1 durability loss even if it didn't activate + } + + $this->armorInventory->setItem($k, $item); + } + } + + if($damage > 0){ + $source->getDamager()->attack(new EntityDamageByEntityEvent($this, $source->getDamager(), EntityDamageEvent::CAUSE_MAGIC, $damage)); + } + } } /** @@ -490,16 +511,20 @@ abstract class Living extends Entity implements Damageable{ $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->damageItem($item, $durabilityRemoved); } } $this->armorInventory->setContents($armor); } + private function damageItem(Durable $item, int $durabilityRemoved) : void{ + $item->applyDamage($durabilityRemoved); + if($item->isBroken()){ + $this->level->broadcastLevelSoundEvent($this, LevelSoundEventPacket::SOUND_BREAK); + } + } + public function attack(EntityDamageEvent $source) : void{ if($this->attackTime > 0 or $this->noDamageTicks > 0){ $lastCause = $this->getLastDamageCause(); diff --git a/src/pocketmine/item/enchantment/Enchantment.php b/src/pocketmine/item/enchantment/Enchantment.php index 9d40e7758..e410a0d16 100644 --- a/src/pocketmine/item/enchantment/Enchantment.php +++ b/src/pocketmine/item/enchantment/Enchantment.php @@ -114,7 +114,7 @@ class Enchantment{ self::registerEnchantment(new ProtectionEnchantment(self::PROJECTILE_PROTECTION, "%enchantment.protect.projectile", self::RARITY_UNCOMMON, self::SLOT_ARMOR, self::SLOT_NONE, 4, 1.5, [ EntityDamageEvent::CAUSE_PROJECTILE ])); - + self::registerEnchantment(new Enchantment(self::THORNS, "%enchantment.thorns", self::RARITY_MYTHIC, self::SLOT_TORSO, self::SLOT_HEAD | self::SLOT_LEGS | self::SLOT_FEET, 3)); self::registerEnchantment(new Enchantment(self::RESPIRATION, "%enchantment.oxygen", self::RARITY_RARE, self::SLOT_HEAD, self::SLOT_NONE, 3)); self::registerEnchantment(new Enchantment(self::EFFICIENCY, "%enchantment.digging", self::RARITY_COMMON, self::SLOT_DIG, self::SLOT_SHEARS, 5));