ExperienceOrb: add get/setDespawnDelay

closes #5645

the code for this is borrowed from ItemEntity. I didn't feel like a base class was appropriate, and we can't (yet) declare constants in traits.
This commit is contained in:
Dylan K. Taylor 2023-04-07 22:33:30 +01:00
parent 1683aa681d
commit d6c923b525
No known key found for this signature in database
GPG Key ID: 8927471A91CAFD3D

View File

@ -32,6 +32,7 @@ use pocketmine\network\mcpe\protocol\types\entity\EntityIds;
use pocketmine\network\mcpe\protocol\types\entity\EntityMetadataCollection;
use pocketmine\network\mcpe\protocol\types\entity\EntityMetadataProperties;
use pocketmine\player\Player;
use function max;
use function sqrt;
class ExperienceOrb extends Entity{
@ -48,6 +49,10 @@ class ExperienceOrb extends Entity{
/** Split sizes used for dropping experience orbs. */
public const ORB_SPLIT_SIZES = [2477, 1237, 617, 307, 149, 73, 37, 17, 7, 3, 1]; //This is indexed biggest to smallest so that we can return as soon as we found the biggest value.
public const DEFAULT_DESPAWN_DELAY = 6000;
public const NEVER_DESPAWN = -1;
public const MAX_DESPAWN_DELAY = 32767 + self::DEFAULT_DESPAWN_DELAY; //max value storable by mojang NBT :(
/**
* Returns the largest size of normal XP orb that will be spawned for the specified amount of XP. Used to split XP
* up into multiple orbs when an amount of XP is dropped.
@ -82,7 +87,10 @@ class ExperienceOrb extends Entity{
public $gravity = 0.04;
public $drag = 0.02;
/** @var int */
/**
* @var int
* @deprecated
*/
protected $age = 0;
/**
@ -100,6 +108,8 @@ class ExperienceOrb extends Entity{
/** @var int */
protected $xpValue;
private int $despawnDelay = self::DEFAULT_DESPAWN_DELAY;
public function __construct(Location $location, int $xpValue, ?CompoundTag $nbt = null){
$this->xpValue = $xpValue;
parent::__construct($location, $nbt);
@ -111,12 +121,22 @@ class ExperienceOrb extends Entity{
parent::initEntity($nbt);
$this->age = $nbt->getShort(self::TAG_AGE, 0);
if($this->age === -32768){
$this->despawnDelay = self::NEVER_DESPAWN;
}else{
$this->despawnDelay = max(0, self::DEFAULT_DESPAWN_DELAY - $this->age);
}
}
public function saveNBT() : CompoundTag{
$nbt = parent::saveNBT();
$nbt->setShort(self::TAG_AGE, $this->age);
if($this->despawnDelay === self::NEVER_DESPAWN){
$age = -32768;
}else{
$age = self::DEFAULT_DESPAWN_DELAY - $this->despawnDelay;
}
$nbt->setShort(self::TAG_AGE, $age);
$nbt->setShort(self::TAG_VALUE_PC, $this->getXpValue());
$nbt->setInt(self::TAG_VALUE_PE, $this->getXpValue());
@ -124,6 +144,15 @@ class ExperienceOrb extends Entity{
return $nbt;
}
public function getDespawnDelay() : int{ return $this->despawnDelay; }
public function setDespawnDelay(int $despawnDelay) : void{
if(($despawnDelay < 0 || $despawnDelay > self::MAX_DESPAWN_DELAY) && $despawnDelay !== self::NEVER_DESPAWN){
throw new \InvalidArgumentException("Despawn ticker must be in range 0 ... " . self::MAX_DESPAWN_DELAY . " or " . self::NEVER_DESPAWN . ", got $despawnDelay");
}
$this->despawnDelay = $despawnDelay;
}
public function getXpValue() : int{
return $this->xpValue;
}
@ -161,7 +190,8 @@ class ExperienceOrb extends Entity{
$hasUpdate = parent::entityBaseTick($tickDiff);
$this->age += $tickDiff;
if($this->age > 6000){
$this->despawnDelay -= $tickDiff;
if($this->despawnDelay <= 0){
$this->flagForDespawn();
return true;
}