Enable various types of interaction to return items to the player, without needing to have a bunch of boilerplate creative mode and held item checks

it became glaringly obvious that this was needed because of #4827 and #4868.

this is further needed with the addition of cauldrons.
This commit is contained in:
Dylan K. Taylor
2022-07-16 19:50:33 +01:00
parent 4afd3dcabf
commit d0ff6d2e36
69 changed files with 177 additions and 155 deletions

View File

@@ -1660,9 +1660,10 @@ class World implements ChunkManager{
* Tries to break a block using a item, including Player time checks if available
* It'll try to lower the durability if Item is a tool, and set it to Air if broken.
*
* @param Item $item reference parameter (if null, can break anything)
* @param Item &$item reference parameter (if null, can break anything)
* @param Item[] &$returnedItems Items to be added to the target's inventory (or dropped, if the inventory is full)
*/
public function useBreakOn(Vector3 $vector, Item &$item = null, ?Player $player = null, bool $createParticles = false) : bool{
public function useBreakOn(Vector3 $vector, Item &$item = null, ?Player $player = null, bool $createParticles = false, array &$returnedItems = []) : bool{
$vector = $vector->floor();
$chunkX = $vector->getFloorX() >> Chunk::COORD_BIT_SIZE;
@@ -1724,10 +1725,10 @@ class World implements ChunkManager{
}
foreach($affectedBlocks as $t){
$this->destroyBlockInternal($t, $item, $player, $createParticles);
$this->destroyBlockInternal($t, $item, $player, $createParticles, $returnedItems);
}
$item->onDestroyBlock($target);
$item->onDestroyBlock($target, $returnedItems);
if(count($drops) > 0){
$dropPos = $vector->add(0.5, 0.5, 0.5);
@@ -1745,12 +1746,15 @@ class World implements ChunkManager{
return true;
}
private function destroyBlockInternal(Block $target, Item $item, ?Player $player = null, bool $createParticles = false) : void{
/**
* @param Item[] &$returnedItems
*/
private function destroyBlockInternal(Block $target, Item $item, ?Player $player, bool $createParticles, array &$returnedItems) : void{
if($createParticles){
$this->addParticle($target->getPosition()->add(0.5, 0.5, 0.5), new BlockBreakParticle($target));
}
$target->onBreak($item, $player);
$target->onBreak($item, $player, $returnedItems);
$tile = $this->getTile($target->getPosition());
if($tile !== null){
@@ -1761,10 +1765,11 @@ class World implements ChunkManager{
/**
* Uses a item on a position and face, placing it or activating the block
*
* @param Player|null $player default null
* @param bool $playSound Whether to play a block-place sound if the block was placed successfully.
* @param Player|null $player default null
* @param bool $playSound Whether to play a block-place sound if the block was placed successfully.
* @param Item[] &$returnedItems Items to be added to the target's inventory (or dropped if the inventory is full)
*/
public function useItemOn(Vector3 $vector, Item &$item, int $face, ?Vector3 $clickVector = null, ?Player $player = null, bool $playSound = false) : bool{
public function useItemOn(Vector3 $vector, Item &$item, int $face, ?Vector3 $clickVector = null, ?Player $player = null, bool $playSound = false, array &$returnedItems = []) : bool{
$blockClicked = $this->getBlock($vector);
$blockReplace = $blockClicked->getSide($face);
@@ -1794,18 +1799,18 @@ class World implements ChunkManager{
$ev->call();
if(!$ev->isCancelled()){
if((!$player->isSneaking() || $item->isNull()) && $blockClicked->onInteract($item, $face, $clickVector, $player)){
if((!$player->isSneaking() || $item->isNull()) && $blockClicked->onInteract($item, $face, $clickVector, $player, $returnedItems)){
return true;
}
$result = $item->onInteractBlock($player, $blockReplace, $blockClicked, $face, $clickVector);
$result = $item->onInteractBlock($player, $blockReplace, $blockClicked, $face, $clickVector, $returnedItems);
if(!$result->equals(ItemUseResult::NONE())){
return $result->equals(ItemUseResult::SUCCESS());
}
}else{
return false;
}
}elseif($blockClicked->onInteract($item, $face, $clickVector, $player)){
}elseif($blockClicked->onInteract($item, $face, $clickVector, $player, $returnedItems)){
return true;
}