diff --git a/src/pocketmine/Server.php b/src/pocketmine/Server.php index 172eca85b..2646a0a2e 100644 --- a/src/pocketmine/Server.php +++ b/src/pocketmine/Server.php @@ -2352,37 +2352,29 @@ class Server{ if($level->getTickRate() > $this->baseTickRate and --$level->tickRateCounter > 0){ continue; } - try{ - $levelTime = microtime(true); - $level->doTick($currentTick); - $tickMs = (microtime(true) - $levelTime) * 1000; - $level->tickRateTime = $tickMs; - if($this->autoTickRate){ - if($tickMs < 50 and $level->getTickRate() > $this->baseTickRate){ - $level->setTickRate($r = $level->getTickRate() - 1); - if($r > $this->baseTickRate){ - $level->tickRateCounter = $level->getTickRate(); - } - $this->getLogger()->debug("Raising level \"{$level->getName()}\" tick rate to {$level->getTickRate()} ticks"); - }elseif($tickMs >= 50){ - if($level->getTickRate() === $this->baseTickRate){ - $level->setTickRate(max($this->baseTickRate + 1, min($this->autoTickRateLimit, (int) floor($tickMs / 50)))); - $this->getLogger()->debug(sprintf("Level \"%s\" took %gms, setting tick rate to %d ticks", $level->getName(), (int) round($tickMs, 2), $level->getTickRate())); - }elseif(($tickMs / $level->getTickRate()) >= 50 and $level->getTickRate() < $this->autoTickRateLimit){ - $level->setTickRate($level->getTickRate() + 1); - $this->getLogger()->debug(sprintf("Level \"%s\" took %gms, setting tick rate to %d ticks", $level->getName(), (int) round($tickMs, 2), $level->getTickRate())); - } + $levelTime = microtime(true); + $level->doTick($currentTick); + $tickMs = (microtime(true) - $levelTime) * 1000; + $level->tickRateTime = $tickMs; + + if($this->autoTickRate){ + if($tickMs < 50 and $level->getTickRate() > $this->baseTickRate){ + $level->setTickRate($r = $level->getTickRate() - 1); + if($r > $this->baseTickRate){ $level->tickRateCounter = $level->getTickRate(); } + $this->getLogger()->debug("Raising level \"{$level->getName()}\" tick rate to {$level->getTickRate()} ticks"); + }elseif($tickMs >= 50){ + if($level->getTickRate() === $this->baseTickRate){ + $level->setTickRate(max($this->baseTickRate + 1, min($this->autoTickRateLimit, (int) floor($tickMs / 50)))); + $this->getLogger()->debug(sprintf("Level \"%s\" took %gms, setting tick rate to %d ticks", $level->getName(), (int) round($tickMs, 2), $level->getTickRate())); + }elseif(($tickMs / $level->getTickRate()) >= 50 and $level->getTickRate() < $this->autoTickRateLimit){ + $level->setTickRate($level->getTickRate() + 1); + $this->getLogger()->debug(sprintf("Level \"%s\" took %gms, setting tick rate to %d ticks", $level->getName(), (int) round($tickMs, 2), $level->getTickRate())); + } + $level->tickRateCounter = $level->getTickRate(); } - }catch(\Throwable $e){ - if(!$level->isClosed()){ - $this->logger->critical($this->getLanguage()->translateString("pocketmine.level.tickError", [$level->getName(), $e->getMessage()])); - }else{ - $this->logger->critical($this->getLanguage()->translateString("pocketmine.level.tickUnloadError", [$level->getName()])); - } - $this->logger->logException($e); } } } diff --git a/src/pocketmine/entity/Entity.php b/src/pocketmine/entity/Entity.php index dcf6dbf34..d363d43ac 100644 --- a/src/pocketmine/entity/Entity.php +++ b/src/pocketmine/entity/Entity.php @@ -408,8 +408,6 @@ abstract class Entity extends Location implements Metadatable, EntityIds{ public $boundingBox; /** @var bool */ public $onGround; - /** @var int */ - protected $age = 0; /** @var float */ public $eyeHeight = null; @@ -1041,7 +1039,6 @@ abstract class Entity extends Location implements Metadatable, EntityIds{ } } - $this->age += $tickDiff; $this->ticksLived += $tickDiff; return $hasUpdate; diff --git a/src/pocketmine/entity/object/ExperienceOrb.php b/src/pocketmine/entity/object/ExperienceOrb.php index aa7cd5759..f830bfba0 100644 --- a/src/pocketmine/entity/object/ExperienceOrb.php +++ b/src/pocketmine/entity/object/ExperienceOrb.php @@ -88,6 +88,9 @@ class ExperienceOrb extends Entity{ public $gravity = 0.04; public $drag = 0.02; + /** @var int */ + protected $age = 0; + /** * @var int * Ticker used for determining interval in which to look for new target players. @@ -159,6 +162,7 @@ class ExperienceOrb extends Entity{ public function entityBaseTick(int $tickDiff = 1) : bool{ $hasUpdate = parent::entityBaseTick($tickDiff); + $this->age += $tickDiff; if($this->age > 6000){ $this->flagForDespawn(); return true; diff --git a/src/pocketmine/entity/object/ItemEntity.php b/src/pocketmine/entity/object/ItemEntity.php index d8b136563..f41b73813 100644 --- a/src/pocketmine/entity/object/ItemEntity.php +++ b/src/pocketmine/entity/object/ItemEntity.php @@ -53,6 +53,9 @@ class ItemEntity extends Entity{ public $canCollide = false; + /** @var int */ + protected $age = 0; + protected function initEntity() : void{ parent::initEntity(); @@ -82,14 +85,13 @@ class ItemEntity extends Entity{ $hasUpdate = parent::entityBaseTick($tickDiff); - if(!$this->isFlaggedForDespawn()){ - if($this->pickupDelay > 0 and $this->pickupDelay < 32767){ //Infinite delay - $this->pickupDelay -= $tickDiff; - if($this->pickupDelay < 0){ - $this->pickupDelay = 0; - } + if(!$this->isFlaggedForDespawn() and $this->pickupDelay > -1 and $this->pickupDelay < 32767){ //Infinite delay + $this->pickupDelay -= $tickDiff; + if($this->pickupDelay < 0){ + $this->pickupDelay = 0; } + $this->age += $tickDiff; if($this->age > 6000){ $this->server->getPluginManager()->callEvent($ev = new ItemDespawnEvent($this)); if($ev->isCancelled()){ @@ -99,7 +101,6 @@ class ItemEntity extends Entity{ $hasUpdate = true; } } - } return $hasUpdate; diff --git a/src/pocketmine/entity/projectile/Arrow.php b/src/pocketmine/entity/projectile/Arrow.php index ee2716e5a..3c6f4a346 100644 --- a/src/pocketmine/entity/projectile/Arrow.php +++ b/src/pocketmine/entity/projectile/Arrow.php @@ -61,6 +61,9 @@ class Arrow extends Projectile{ /** @var float */ protected $punchKnockback = 0.0; + /** @var int */ + protected $collideTicks = 0; + public function __construct(Level $level, CompoundTag $nbt, ?Entity $shootingEntity = null, bool $critical = false){ parent::__construct($level, $nbt, $shootingEntity); $this->setCritical($critical); @@ -70,12 +73,14 @@ class Arrow extends Projectile{ parent::initEntity(); $this->pickupMode = $this->namedtag->getByte(self::TAG_PICKUP, self::PICKUP_ANY, true); + $this->collideTicks = $this->namedtag->getShort("life", $this->collideTicks); } public function saveNBT() : void{ parent::saveNBT(); $this->namedtag->setByte(self::TAG_PICKUP, $this->pickupMode, true); + $this->namedtag->setShort("life", $this->collideTicks); } public function isCritical() : bool{ @@ -116,9 +121,14 @@ class Arrow extends Projectile{ $hasUpdate = parent::entityBaseTick($tickDiff); - if($this->age > 1200){ - $this->flagForDespawn(); - $hasUpdate = true; + if($this->isCollided){ + $this->collideTicks += $tickDiff; + if($this->collideTicks > 1200){ + $this->flagForDespawn(); + $hasUpdate = true; + } + }else{ + $this->collideTicks = 0; } return $hasUpdate; diff --git a/src/pocketmine/entity/projectile/EnderPearl.php b/src/pocketmine/entity/projectile/EnderPearl.php index d2df081e1..2bbdfab5e 100644 --- a/src/pocketmine/entity/projectile/EnderPearl.php +++ b/src/pocketmine/entity/projectile/EnderPearl.php @@ -66,7 +66,5 @@ class EnderPearl extends Throwable{ $owner->attack(new EntityDamageEvent($owner, EntityDamageEvent::CAUSE_FALL, 5)); } - - $this->flagForDespawn(); } } diff --git a/src/pocketmine/entity/projectile/ExperienceBottle.php b/src/pocketmine/entity/projectile/ExperienceBottle.php index 8e9b5f3cc..604932066 100644 --- a/src/pocketmine/entity/projectile/ExperienceBottle.php +++ b/src/pocketmine/entity/projectile/ExperienceBottle.php @@ -42,7 +42,5 @@ class ExperienceBottle extends Throwable{ $this->level->broadcastLevelSoundEvent($this, LevelSoundEventPacket::SOUND_GLASS); $this->level->dropExperience($this, mt_rand(3, 11)); - - $this->flagForDespawn(); } } diff --git a/src/pocketmine/entity/projectile/Projectile.php b/src/pocketmine/entity/projectile/Projectile.php index 66c0a1433..e7fb2c3f1 100644 --- a/src/pocketmine/entity/projectile/Projectile.php +++ b/src/pocketmine/entity/projectile/Projectile.php @@ -74,7 +74,6 @@ abstract class Projectile extends Entity{ $this->setMaxHealth(1); $this->setHealth(1); - $this->age = $this->namedtag->getShort("Age", $this->age); $this->damage = $this->namedtag->getDouble("damage", $this->damage); do{ @@ -144,7 +143,6 @@ abstract class Projectile extends Entity{ public function saveNBT() : void{ parent::saveNBT(); - $this->namedtag->setShort("Age", $this->age); $this->namedtag->setDouble("damage", $this->damage); if($this->blockHit !== null){ diff --git a/src/pocketmine/entity/projectile/SplashPotion.php b/src/pocketmine/entity/projectile/SplashPotion.php index 01b28cd62..a0cf330d1 100644 --- a/src/pocketmine/entity/projectile/SplashPotion.php +++ b/src/pocketmine/entity/projectile/SplashPotion.php @@ -124,8 +124,6 @@ class SplashPotion extends Throwable{ } } } - - $this->flagForDespawn(); } /** diff --git a/src/pocketmine/entity/projectile/Throwable.php b/src/pocketmine/entity/projectile/Throwable.php index 9eef34780..42086aae4 100644 --- a/src/pocketmine/entity/projectile/Throwable.php +++ b/src/pocketmine/entity/projectile/Throwable.php @@ -23,6 +23,9 @@ declare(strict_types=1); namespace pocketmine\entity\projectile; +use pocketmine\block\Block; +use pocketmine\math\RayTraceResult; + abstract class Throwable extends Projectile{ public $width = 0.25; @@ -31,18 +34,8 @@ abstract class Throwable extends Projectile{ protected $gravity = 0.03; protected $drag = 0.01; - public function entityBaseTick(int $tickDiff = 1) : bool{ - if($this->closed){ - return false; - } - - $hasUpdate = parent::entityBaseTick($tickDiff); - - if($this->age > 1200 or $this->isCollided){ - $this->flagForDespawn(); - $hasUpdate = true; - } - - return $hasUpdate; + protected function onHitBlock(Block $blockHit, RayTraceResult $hitResult) : void{ + parent::onHitBlock($blockHit, $hitResult); + $this->flagForDespawn(); } }