mirror of
https://github.com/pmmp/PocketMine-MP.git
synced 2025-07-06 01:51:51 +00:00
Cleaned up and added API for entity air supply, fixed oxygen being used in creative/spectator
this commit also includes respiration checks because it's cherry-picked from api3/blocks, but respiration won't work until it's registered.
This commit is contained in:
parent
bdfd9c95dd
commit
2601e35990
@ -1713,6 +1713,10 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{
|
|||||||
return 0.0;
|
return 0.0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function canBreathe() : bool{
|
||||||
|
return $this->isCreative() or parent::canBreathe();
|
||||||
|
}
|
||||||
|
|
||||||
public function checkNetwork(){
|
public function checkNetwork(){
|
||||||
if(!$this->isOnline()){
|
if(!$this->isOnline()){
|
||||||
return;
|
return;
|
||||||
|
@ -28,6 +28,9 @@ use pocketmine\event\entity\EntityRegainHealthEvent;
|
|||||||
use pocketmine\event\player\PlayerExhaustEvent;
|
use pocketmine\event\player\PlayerExhaustEvent;
|
||||||
use pocketmine\inventory\InventoryHolder;
|
use pocketmine\inventory\InventoryHolder;
|
||||||
use pocketmine\inventory\PlayerInventory;
|
use pocketmine\inventory\PlayerInventory;
|
||||||
|
use pocketmine\item\Consumable;
|
||||||
|
use pocketmine\item\enchantment\Enchantment;
|
||||||
|
use pocketmine\item\FoodSource;
|
||||||
use pocketmine\item\Item as ItemItem;
|
use pocketmine\item\Item as ItemItem;
|
||||||
use pocketmine\level\Level;
|
use pocketmine\level\Level;
|
||||||
use pocketmine\nbt\NBT;
|
use pocketmine\nbt\NBT;
|
||||||
@ -454,6 +457,14 @@ class Human extends Creature implements ProjectileSource, InventoryHolder{
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected function doAirSupplyTick(int $tickDiff){
|
||||||
|
//TODO: allow this to apply to other mobs
|
||||||
|
if(($ench = $this->inventory->getHelmet()->getEnchantment(Enchantment::RESPIRATION)) === null or
|
||||||
|
lcg_value() <= (1 / ($ench->getLevel() + 1))){
|
||||||
|
parent::doAirSupplyTick($tickDiff);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public function getName() : string{
|
public function getName() : string{
|
||||||
return $this->getNameTag();
|
return $this->getNameTag();
|
||||||
}
|
}
|
||||||
|
@ -422,7 +422,6 @@ abstract class Living extends Entity implements Damageable{
|
|||||||
|
|
||||||
public function entityBaseTick(int $tickDiff = 1) : bool{
|
public function entityBaseTick(int $tickDiff = 1) : bool{
|
||||||
Timings::$timerLivingEntityBaseTick->startTiming();
|
Timings::$timerLivingEntityBaseTick->startTiming();
|
||||||
$this->setGenericFlag(self::DATA_FLAG_BREATHING, !$this->isInsideOfWater());
|
|
||||||
|
|
||||||
$hasUpdate = parent::entityBaseTick($tickDiff);
|
$hasUpdate = parent::entityBaseTick($tickDiff);
|
||||||
|
|
||||||
@ -435,34 +434,14 @@ abstract class Living extends Entity implements Damageable{
|
|||||||
$this->attack($ev);
|
$this->attack($ev);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!$this->hasEffect(Effect::WATER_BREATHING) and $this->isInsideOfWater()){
|
if(!$this->canBreathe()){
|
||||||
if($this instanceof WaterAnimal){
|
if($this->isBreathing()){
|
||||||
$this->setDataProperty(self::DATA_AIR, self::DATA_TYPE_SHORT, 400);
|
$this->setBreathing(false);
|
||||||
}else{
|
|
||||||
$hasUpdate = true;
|
|
||||||
$airTicks = $this->getDataProperty(self::DATA_AIR) - $tickDiff;
|
|
||||||
if($airTicks <= -20){
|
|
||||||
$airTicks = 0;
|
|
||||||
|
|
||||||
$ev = new EntityDamageEvent($this, EntityDamageEvent::CAUSE_DROWNING, 2);
|
|
||||||
$this->attack($ev);
|
|
||||||
}
|
|
||||||
$this->setDataProperty(self::DATA_AIR, self::DATA_TYPE_SHORT, $airTicks);
|
|
||||||
}
|
|
||||||
}else{
|
|
||||||
if($this instanceof WaterAnimal){
|
|
||||||
$hasUpdate = true;
|
|
||||||
$airTicks = $this->getDataProperty(self::DATA_AIR) - $tickDiff;
|
|
||||||
if($airTicks <= -20){
|
|
||||||
$airTicks = 0;
|
|
||||||
|
|
||||||
$ev = new EntityDamageEvent($this, EntityDamageEvent::CAUSE_SUFFOCATION, 2);
|
|
||||||
$this->attack($ev);
|
|
||||||
}
|
|
||||||
$this->setDataProperty(self::DATA_AIR, self::DATA_TYPE_SHORT, $airTicks);
|
|
||||||
}else{
|
|
||||||
$this->setDataProperty(self::DATA_AIR, self::DATA_TYPE_SHORT, 400);
|
|
||||||
}
|
}
|
||||||
|
$this->doAirSupplyTick($tickDiff);
|
||||||
|
}elseif(!$this->isBreathing()){
|
||||||
|
$this->setBreathing(true);
|
||||||
|
$this->setAirSupplyTicks($this->getMaxAirSupplyTicks());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -495,6 +474,90 @@ abstract class Living extends Entity implements Damageable{
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Ticks the entity's air supply when it cannot breathe.
|
||||||
|
* @param int $tickDiff
|
||||||
|
*/
|
||||||
|
protected function doAirSupplyTick(int $tickDiff){
|
||||||
|
$ticks = $this->getAirSupplyTicks() - $tickDiff;
|
||||||
|
|
||||||
|
if($ticks <= -20){
|
||||||
|
$this->setAirSupplyTicks(0);
|
||||||
|
$this->onAirExpired();
|
||||||
|
}else{
|
||||||
|
$this->setAirSupplyTicks($ticks);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns whether the entity can currently breathe.
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
public function canBreathe() : bool{
|
||||||
|
return $this->hasEffect(Effect::WATER_BREATHING) or !$this->isInsideOfWater();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns whether the entity is currently breathing or not. If this is false, the entity's air supply will be used.
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
public function isBreathing() : bool{
|
||||||
|
return $this->getGenericFlag(self::DATA_FLAG_BREATHING);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets whether the entity is currently breathing. If false, it will cause the entity's air supply to be used.
|
||||||
|
* For players, this also shows the oxygen bar.
|
||||||
|
*
|
||||||
|
* @param bool $value
|
||||||
|
*/
|
||||||
|
public function setBreathing(bool $value = true){
|
||||||
|
$this->setGenericFlag(self::DATA_FLAG_BREATHING, $value);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the number of ticks remaining in the entity's air supply. Note that the entity may survive longer than
|
||||||
|
* this amount of time without damage due to enchantments such as Respiration.
|
||||||
|
*
|
||||||
|
* @return int
|
||||||
|
*/
|
||||||
|
public function getAirSupplyTicks() : int{
|
||||||
|
return $this->getDataProperty(self::DATA_AIR);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the number of air ticks left in the entity's air supply.
|
||||||
|
* @param int $ticks
|
||||||
|
*/
|
||||||
|
public function setAirSupplyTicks(int $ticks){
|
||||||
|
$this->setDataProperty(self::DATA_AIR, self::DATA_TYPE_SHORT, $ticks);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the maximum amount of air ticks the entity's air supply can contain.
|
||||||
|
* @return int
|
||||||
|
*/
|
||||||
|
public function getMaxAirSupplyTicks() : int{
|
||||||
|
return $this->getDataProperty(self::DATA_MAX_AIR);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the maximum amount of air ticks the air supply can hold.
|
||||||
|
* @param int $ticks
|
||||||
|
*/
|
||||||
|
public function setMaxAirSupplyTicks(int $ticks){
|
||||||
|
$this->setDataProperty(self::DATA_AIR, self::DATA_TYPE_SHORT, $ticks);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Called when the entity's air supply ticks reaches -20 or lower. The entity will usually take damage at this point
|
||||||
|
* and then the supply is reset to 0, so this method will be called roughly every second.
|
||||||
|
*/
|
||||||
|
public function onAirExpired(){
|
||||||
|
$ev = new EntityDamageEvent($this, EntityDamageEvent::CAUSE_DROWNING, 2);
|
||||||
|
$this->attack($ev);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return ItemItem[]
|
* @return ItemItem[]
|
||||||
*/
|
*/
|
||||||
|
@ -23,9 +23,20 @@ declare(strict_types=1);
|
|||||||
|
|
||||||
namespace pocketmine\entity;
|
namespace pocketmine\entity;
|
||||||
|
|
||||||
|
use pocketmine\event\entity\EntityDamageEvent;
|
||||||
|
|
||||||
abstract class WaterAnimal extends Creature implements Ageable{
|
abstract class WaterAnimal extends Creature implements Ageable{
|
||||||
|
|
||||||
public function isBaby() : bool{
|
public function isBaby() : bool{
|
||||||
return $this->getGenericFlag(self::DATA_FLAG_BABY);
|
return $this->getGenericFlag(self::DATA_FLAG_BABY);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function canBreathe() : bool{
|
||||||
|
return $this->isInsideOfWater();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function onAirExpired(){
|
||||||
|
$ev = new EntityDamageEvent($this, EntityDamageEvent::CAUSE_SUFFOCATION, 2);
|
||||||
|
$this->attack($ev);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user