mirror of
https://github.com/pmmp/PocketMine-MP.git
synced 2025-09-06 17:59:48 +00:00
Added Level->dropExperience() and API for splitting XP into orb sizes
This commit is contained in:
@ -41,6 +41,48 @@ class ExperienceOrb extends Entity{
|
|||||||
*/
|
*/
|
||||||
public const MAX_TARGET_DISTANCE = 8.0;
|
public const MAX_TARGET_DISTANCE = 8.0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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.
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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.
|
||||||
|
*
|
||||||
|
* @param int $amount
|
||||||
|
*
|
||||||
|
* @return int
|
||||||
|
*/
|
||||||
|
public static function getMaxOrbSize(int $amount) : int{
|
||||||
|
foreach(self::ORB_SPLIT_SIZES as $split){
|
||||||
|
if($amount >= $split){
|
||||||
|
return $split;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Splits the specified amount of XP into an array of acceptable XP orb sizes.
|
||||||
|
*
|
||||||
|
* @param int $amount
|
||||||
|
*
|
||||||
|
* @return int[]
|
||||||
|
*/
|
||||||
|
public static function splitIntoOrbSizes(int $amount) : array{
|
||||||
|
$result = [];
|
||||||
|
|
||||||
|
while($amount > 0){
|
||||||
|
$size = self::getMaxOrbSize($amount);
|
||||||
|
$result[] = $size;
|
||||||
|
$amount -= $size;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $result;
|
||||||
|
}
|
||||||
|
|
||||||
public $height = 0.25;
|
public $height = 0.25;
|
||||||
public $width = 0.25;
|
public $width = 0.25;
|
||||||
|
|
||||||
|
@ -31,6 +31,7 @@ use pocketmine\block\BlockFactory;
|
|||||||
use pocketmine\entity\Effect;
|
use pocketmine\entity\Effect;
|
||||||
use pocketmine\entity\Entity;
|
use pocketmine\entity\Entity;
|
||||||
use pocketmine\entity\Item as DroppedItem;
|
use pocketmine\entity\Item as DroppedItem;
|
||||||
|
use pocketmine\entity\object\ExperienceOrb;
|
||||||
use pocketmine\entity\projectile\Arrow;
|
use pocketmine\entity\projectile\Arrow;
|
||||||
use pocketmine\event\block\BlockBreakEvent;
|
use pocketmine\event\block\BlockBreakEvent;
|
||||||
use pocketmine\event\block\BlockPlaceEvent;
|
use pocketmine\event\block\BlockPlaceEvent;
|
||||||
@ -1699,6 +1700,41 @@ class Level implements ChunkManager, Metadatable{
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Drops XP orbs into the world for the specified amount, splitting the amount into several orbs if necessary.
|
||||||
|
*
|
||||||
|
* @param Vector3 $pos
|
||||||
|
* @param int $amount
|
||||||
|
*
|
||||||
|
* @return ExperienceOrb[]
|
||||||
|
*/
|
||||||
|
public function dropExperience(Vector3 $pos, int $amount) : array{
|
||||||
|
/** @var ExperienceOrb[] $orbs */
|
||||||
|
$orbs = [];
|
||||||
|
|
||||||
|
foreach(ExperienceOrb::splitIntoOrbSizes($amount) as $split){
|
||||||
|
$nbt = Entity::createBaseNBT(
|
||||||
|
$pos,
|
||||||
|
$this->temporalVector->setComponents((lcg_value() * 0.2 - 0.1) * 2, lcg_value() * 0.4, (lcg_value() * 0.2 - 0.1) * 2),
|
||||||
|
lcg_value() * 360,
|
||||||
|
0
|
||||||
|
);
|
||||||
|
$nbt->setShort(ExperienceOrb::TAG_VALUE_PC, $split);
|
||||||
|
|
||||||
|
$orb = Entity::createEntity("XPOrb", $this, $nbt);
|
||||||
|
if($orb === null){
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
$orb->spawnToAll();
|
||||||
|
if($orb instanceof ExperienceOrb){
|
||||||
|
$orbs[] = $orb;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $orbs;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Checks if the level spawn protection radius will prevent the player from using items or building at the specified
|
* Checks if the level spawn protection radius will prevent the player from using items or building at the specified
|
||||||
* Vector3 position.
|
* Vector3 position.
|
||||||
|
Reference in New Issue
Block a user