diff --git a/src/pocketmine/entity/Living.php b/src/pocketmine/entity/Living.php index 1f10662d9..0d5561fbe 100644 --- a/src/pocketmine/entity/Living.php +++ b/src/pocketmine/entity/Living.php @@ -665,13 +665,8 @@ abstract class Living extends Entity implements Damageable{ $this->attack($ev); } - if(!$this->canBreathe()){ - $this->setBreathing(false); - $this->doAirSupplyTick($tickDiff); + if($this->doAirSupplyTick($tickDiff)){ $hasUpdate = true; - }elseif(!$this->isBreathing()){ - $this->setBreathing(true); - $this->setAirSupplyTicks($this->getMaxAirSupplyTicks()); } } @@ -700,22 +695,42 @@ abstract class Living extends Entity implements Damageable{ } /** - * Ticks the entity's air supply when it cannot breathe. + * Ticks the entity's air supply, consuming it when underwater and regenerating it when out of water. + * * @param int $tickDiff + * + * @return bool */ - protected function doAirSupplyTick(int $tickDiff) : void{ - if(($respirationLevel = $this->armorInventory->getHelmet()->getEnchantmentLevel(Enchantment::RESPIRATION)) <= 0 or - lcg_value() <= (1 / ($respirationLevel + 1)) - ){ - $ticks = $this->getAirSupplyTicks() - $tickDiff; + protected function doAirSupplyTick(int $tickDiff) : bool{ + $ticks = $this->getAirSupplyTicks(); + $oldTicks = $ticks; + if(!$this->canBreathe()){ + $this->setBreathing(false); - if($ticks <= -20){ - $this->setAirSupplyTicks(0); - $this->onAirExpired(); - }else{ - $this->setAirSupplyTicks($ticks); + if(($respirationLevel = $this->armorInventory->getHelmet()->getEnchantmentLevel(Enchantment::RESPIRATION)) <= 0 or + lcg_value() <= (1 / ($respirationLevel + 1)) + ){ + $ticks -= $tickDiff; + if($ticks <= -20){ + $ticks = 0; + $this->onAirExpired(); + } + } + }elseif(!$this->isBreathing()){ + if($ticks < ($max = $this->getMaxAirSupplyTicks())){ + $ticks += $tickDiff * 5; + } + if($ticks >= $max){ + $ticks = $max; + $this->setBreathing(true); } } + + if($ticks !== $oldTicks){ + $this->setAirSupplyTicks($ticks); + } + + return $ticks !== $oldTicks; } /**