mirror of
https://github.com/pmmp/PocketMine-MP.git
synced 2025-07-03 00:29:54 +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
|
* Returns whether Silk Touch enchanted tools will cause this block to drop as itself. Since most blocks drop
|
||||||
* themselves anyway, this is implicitly true.
|
* 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)
|
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{
|
public function isAffectedBySilkTouch() : bool{
|
||||||
return false;
|
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))
|
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;
|
protected $instaBreak = false;
|
||||||
/** @var Item[] */
|
/** @var Item[] */
|
||||||
protected $blockDrops = [];
|
protected $blockDrops = [];
|
||||||
|
/** @var int */
|
||||||
|
protected $xpDrops;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param Player $player
|
* @param Player $player
|
||||||
@ -49,14 +51,16 @@ class BlockBreakEvent extends BlockEvent implements Cancellable{
|
|||||||
* @param Item $item
|
* @param Item $item
|
||||||
* @param bool $instaBreak
|
* @param bool $instaBreak
|
||||||
* @param Item[] $drops
|
* @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);
|
parent::__construct($block);
|
||||||
$this->item = $item;
|
$this->item = $item;
|
||||||
$this->player = $player;
|
$this->player = $player;
|
||||||
|
|
||||||
$this->instaBreak = $instaBreak;
|
$this->instaBreak = $instaBreak;
|
||||||
$this->setDrops($drops);
|
$this->setDrops($drops);
|
||||||
|
$this->xpDrops = $xpDrops;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -115,4 +119,25 @@ class BlockBreakEvent extends BlockEvent implements Cancellable{
|
|||||||
public function setDropsVariadic(Item ...$drops){
|
public function setDropsVariadic(Item ...$drops){
|
||||||
$this->blockDrops = $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);
|
$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){
|
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()){
|
if(($player->isSurvival() and !$target->isBreakable($item)) or $player->isSpectator()){
|
||||||
$ev->setCancelled();
|
$ev->setCancelled();
|
||||||
@ -1711,6 +1717,7 @@ class Level implements ChunkManager, Metadatable{
|
|||||||
}
|
}
|
||||||
|
|
||||||
$drops = $ev->getDrops();
|
$drops = $ev->getDrops();
|
||||||
|
$xpDrop = $ev->getXpDropAmount();
|
||||||
|
|
||||||
}elseif(!$target->isBreakable($item)){
|
}elseif(!$target->isBreakable($item)){
|
||||||
return false;
|
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;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user