diff --git a/src/pocketmine/Server.php b/src/pocketmine/Server.php index a2f8d92c6..561446996 100644 --- a/src/pocketmine/Server.php +++ b/src/pocketmine/Server.php @@ -2398,37 +2398,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 25f68b0c9..bc4e5fc36 100644 --- a/src/pocketmine/entity/Entity.php +++ b/src/pocketmine/entity/Entity.php @@ -395,8 +395,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; @@ -1023,7 +1021,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 01c0eaf6b..96578acd0 100644 --- a/src/pocketmine/entity/object/ExperienceOrb.php +++ b/src/pocketmine/entity/object/ExperienceOrb.php @@ -89,6 +89,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. @@ -162,6 +165,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 faaba466f..198650c19 100644 --- a/src/pocketmine/entity/object/ItemEntity.php +++ b/src/pocketmine/entity/object/ItemEntity.php @@ -54,6 +54,9 @@ class ItemEntity extends Entity{ public $canCollide = false; + /** @var int */ + protected $age = 0; + protected function initEntity(CompoundTag $nbt) : void{ parent::initEntity($nbt); @@ -83,14 +86,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()){ @@ -100,7 +102,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 92409071e..fce599e8f 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,11 +73,13 @@ class Arrow extends Projectile{ parent::initEntity($nbt); $this->pickupMode = $nbt->getByte(self::TAG_PICKUP, self::PICKUP_ANY, true); + $this->collideTicks = $nbt->getShort("life", $this->collideTicks); } public function saveNBT() : CompoundTag{ $nbt = parent::saveNBT(); $nbt->setByte(self::TAG_PICKUP, $this->pickupMode); + $nbt->setShort("life", $this->collideTicks); return $nbt; } @@ -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 d6553cacd..bafe1d673 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 = $nbt->getShort("Age", $this->age); $this->damage = $nbt->getDouble("damage", $this->damage); do{ @@ -144,7 +143,6 @@ abstract class Projectile extends Entity{ public function saveNBT() : CompoundTag{ $nbt = parent::saveNBT(); - $nbt->setShort("Age", $this->age); $nbt->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 bc31dda7c..4d0010e59 100644 --- a/src/pocketmine/entity/projectile/SplashPotion.php +++ b/src/pocketmine/entity/projectile/SplashPotion.php @@ -127,8 +127,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(); } }