Altered armour handling, now works for damage other than PvP

This commit is contained in:
Dylan K. Taylor 2017-12-14 12:37:28 +00:00
parent 1822abc862
commit 953f45c50f
3 changed files with 49 additions and 12 deletions

View File

@ -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);

View File

@ -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);
}

View File

@ -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;
}
}