mirror of
https://github.com/pmmp/PocketMine-MP.git
synced 2025-04-20 16:00:20 +00:00
Implemented block break XP drops
This commit is contained in:
parent
1e2122d854
commit
532269a484
@ -471,6 +471,30 @@ class Block extends Position implements BlockIds, Metadatable{
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns how much XP will be dropped by breaking this block with the given item.
|
||||
*
|
||||
* @param Item $item
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function getXpDropForTool(Item $item) : int{
|
||||
if($item->hasEnchantment(Enchantment::SILK_TOUCH) or !$this->isCompatibleWithTool($item)){
|
||||
return 0;
|
||||
}
|
||||
|
||||
return $this->getXpDropAmount();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns how much XP this block will drop when broken with an appropriate tool.
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
protected function getXpDropAmount() : int{
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether Silk Touch enchanted tools will cause this block to drop as itself. Since most blocks drop
|
||||
* themselves anyway, this is implicitly true.
|
||||
|
@ -57,4 +57,7 @@ class CoalOre extends Solid{
|
||||
];
|
||||
}
|
||||
|
||||
public function getXpDropForTool(Item $item) : int{
|
||||
return mt_rand(0, 2);
|
||||
}
|
||||
}
|
||||
|
@ -56,4 +56,8 @@ class DiamondOre extends Solid{
|
||||
ItemFactory::get(Item::DIAMOND)
|
||||
];
|
||||
}
|
||||
|
||||
protected function getXpDropAmount() : int{
|
||||
return mt_rand(3, 7);
|
||||
}
|
||||
}
|
||||
|
@ -57,4 +57,7 @@ class LapisOre extends Solid{
|
||||
];
|
||||
}
|
||||
|
||||
protected function getXpDropAmount() : int{
|
||||
return mt_rand(2, 5);
|
||||
}
|
||||
}
|
||||
|
@ -57,4 +57,8 @@ class MonsterSpawner extends Transparent{
|
||||
public function isAffectedBySilkTouch() : bool{
|
||||
return false;
|
||||
}
|
||||
|
||||
protected function getXpDropAmount() : int{
|
||||
return mt_rand(15, 43);
|
||||
}
|
||||
}
|
||||
|
@ -57,4 +57,7 @@ class NetherQuartzOre extends Solid{
|
||||
];
|
||||
}
|
||||
|
||||
protected function getXpDropAmount() : int{
|
||||
return mt_rand(2, 5);
|
||||
}
|
||||
}
|
||||
|
@ -70,4 +70,8 @@ class RedstoneOre extends Solid{
|
||||
ItemFactory::get(Item::REDSTONE_DUST, 0, mt_rand(4, 5))
|
||||
];
|
||||
}
|
||||
|
||||
protected function getXpDropAmount() : int{
|
||||
return mt_rand(1, 5);
|
||||
}
|
||||
}
|
||||
|
@ -42,6 +42,8 @@ class BlockBreakEvent extends BlockEvent implements Cancellable{
|
||||
protected $instaBreak = false;
|
||||
/** @var Item[] */
|
||||
protected $blockDrops = [];
|
||||
/** @var int */
|
||||
protected $xpDrops;
|
||||
|
||||
/**
|
||||
* @param Player $player
|
||||
@ -49,14 +51,16 @@ class BlockBreakEvent extends BlockEvent implements Cancellable{
|
||||
* @param Item $item
|
||||
* @param bool $instaBreak
|
||||
* @param Item[] $drops
|
||||
* @param int $xpDrops
|
||||
*/
|
||||
public function __construct(Player $player, Block $block, Item $item, bool $instaBreak = false, array $drops){
|
||||
public function __construct(Player $player, Block $block, Item $item, bool $instaBreak = false, array $drops, int $xpDrops = 0){
|
||||
parent::__construct($block);
|
||||
$this->item = $item;
|
||||
$this->player = $player;
|
||||
|
||||
$this->instaBreak = $instaBreak;
|
||||
$this->setDrops($drops);
|
||||
$this->xpDrops = $xpDrops;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -115,4 +119,25 @@ class BlockBreakEvent extends BlockEvent implements Cancellable{
|
||||
public function setDropsVariadic(Item ...$drops){
|
||||
$this->blockDrops = $drops;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns how much XP will be dropped by breaking this block.
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function getXpDropAmount() : int{
|
||||
return $this->xpDrops;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets how much XP will be dropped by breaking this block.
|
||||
*
|
||||
* @param int $amount
|
||||
*/
|
||||
public function setXpDrops(int $amount) : void{
|
||||
if($amount < 0){
|
||||
throw new \InvalidArgumentException("Amount must be at least zero");
|
||||
}
|
||||
$this->xpDrops = $amount;
|
||||
}
|
||||
}
|
||||
|
@ -1676,10 +1676,16 @@ class Level implements ChunkManager, Metadatable{
|
||||
$item = ItemFactory::get(Item::AIR, 0, 0);
|
||||
}
|
||||
|
||||
$drops = ($player !== null and $player->isCreative()) ? [] : array_merge(...array_map(function(Block $block) use ($item) : array{ return $block->getDrops($item); }, $affectedBlocks));
|
||||
$drops = [];
|
||||
$xpDrop = 0;
|
||||
|
||||
if($player !== null and !$player->isCreative()){
|
||||
$drops = array_merge(...array_map(function(Block $block) use ($item) : array{ return $block->getDrops($item); }, $affectedBlocks));
|
||||
$xpDrop = array_sum(array_map(function(Block $block) use ($item) : int{ return $block->getXpDropForTool($item); }, $affectedBlocks));
|
||||
}
|
||||
|
||||
if($player !== null){
|
||||
$ev = new BlockBreakEvent($player, $target, $item, $player->isCreative(), $drops);
|
||||
$ev = new BlockBreakEvent($player, $target, $item, $player->isCreative(), $drops, $xpDrop);
|
||||
|
||||
if(($player->isSurvival() and !$target->isBreakable($item)) or $player->isSpectator()){
|
||||
$ev->setCancelled();
|
||||
@ -1711,6 +1717,7 @@ class Level implements ChunkManager, Metadatable{
|
||||
}
|
||||
|
||||
$drops = $ev->getDrops();
|
||||
$xpDrop = $ev->getXpDropAmount();
|
||||
|
||||
}elseif(!$target->isBreakable($item)){
|
||||
return false;
|
||||
@ -1731,6 +1738,10 @@ class Level implements ChunkManager, Metadatable{
|
||||
}
|
||||
}
|
||||
|
||||
if($xpDrop > 0){
|
||||
$this->dropExperience($target->add(0.5, 0.5, 0.5), $xpDrop);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user