diff --git a/src/pocketmine/Player.php b/src/pocketmine/Player.php index c67a7cb91..bbb3f1156 100644 --- a/src/pocketmine/Player.php +++ b/src/pocketmine/Player.php @@ -2402,26 +2402,15 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{ $heldItem = $this->inventory->getItemInHand(); - $damage = [ - EntityDamageEvent::MODIFIER_BASE => $heldItem->getAttackPoints() - ]; - if(!$this->canInteract($target, 8)){ $cancelled = true; }elseif($target instanceof Player){ if($this->server->getConfigBool("pvp") !== true){ $cancelled = true; } - - $points = 0; - foreach($target->getInventory()->getArmorContents() as $armorItem){ - $points += $armorItem->getDefensePoints(); - } - - $damage[EntityDamageEvent::MODIFIER_ARMOR] = -($damage[EntityDamageEvent::MODIFIER_BASE] * $points * 0.04); } - $ev = new EntityDamageByEntityEvent($this, $target, EntityDamageEvent::CAUSE_ENTITY_ATTACK, $damage); + $ev = new EntityDamageByEntityEvent($this, $target, EntityDamageEvent::CAUSE_ENTITY_ATTACK, $heldItem->getAttackPoints()); if($cancelled){ $ev->setCancelled(); } @@ -3589,6 +3578,15 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{ return false; //never flag players for despawn } + public function getArmorPoints() : int{ + $total = 0; + foreach($this->inventory->getArmorContents() as $item){ + $total += $item->getDefensePoints(); + } + + return $total; + } + protected function applyPostDamageEffects(EntityDamageEvent $source) : void{ parent::applyPostDamageEffects($source); diff --git a/src/pocketmine/entity/Living.php b/src/pocketmine/entity/Living.php index 06dba9446..0c68308bd 100644 --- a/src/pocketmine/entity/Living.php +++ b/src/pocketmine/entity/Living.php @@ -348,6 +348,17 @@ abstract class Living extends Entity implements Damageable{ } } + /** + * Returns how many armour points this mob has. Armour points provide a percentage reduction to damage. + * For mobs which can wear armour, this should return the sum total of the armour points provided by their + * equipment. + * + * @return int + */ + public function getArmorPoints() : int{ + return 0; + } + /** * Called prior to EntityDamageEvent execution to apply modifications to the event's damage, such as reduction due * to effects or armour. @@ -355,11 +366,18 @@ abstract class Living extends Entity implements Damageable{ * @param EntityDamageEvent $source */ public function applyDamageModifiers(EntityDamageEvent $source) : void{ + if($source->canBeReducedByArmor()){ + //MCPE uses the same system as PC did pre-1.9 + $source->setDamage(-$source->getFinalDamage() * $this->getArmorPoints() * 0.04, EntityDamageEvent::MODIFIER_ARMOR); + } + $cause = $source->getCause(); if($this->hasEffect(Effect::DAMAGE_RESISTANCE) and $cause !== EntityDamageEvent::CAUSE_VOID and $cause !== EntityDamageEvent::CAUSE_SUICIDE){ $source->setDamage(-($source->getFinalDamage() * 0.20 * $this->getEffect(Effect::DAMAGE_RESISTANCE)->getEffectLevel()), EntityDamageEvent::MODIFIER_RESISTANCE); } + //TODO: armour protection enchantments should be checked here (after effect damage reduction) + $source->setDamage(-min($this->getAbsorption(), $source->getFinalDamage()), EntityDamageEvent::MODIFIER_ABSORPTION); } diff --git a/src/pocketmine/event/entity/EntityDamageEvent.php b/src/pocketmine/event/entity/EntityDamageEvent.php index e9a36c13f..a7d41081e 100644 --- a/src/pocketmine/event/entity/EntityDamageEvent.php +++ b/src/pocketmine/event/entity/EntityDamageEvent.php @@ -136,4 +136,25 @@ class EntityDamageEvent extends EntityEvent implements Cancellable{ return array_sum($this->modifiers); } + /** + * Returns whether an entity can use armour points to reduce this type of damage. + * @return bool + */ + public function canBeReducedByArmor() : bool{ + switch($this->cause){ + case self::CAUSE_FIRE_TICK: + case self::CAUSE_SUFFOCATION: + case self::CAUSE_DROWNING: + case self::CAUSE_STARVATION: + case self::CAUSE_FALL: + case self::CAUSE_VOID: + case self::CAUSE_MAGIC: + case self::CAUSE_SUICIDE: + //TODO: lightning + return false; + + } + + return true; + } } \ No newline at end of file