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

@@ -129,16 +129,15 @@ class Armor extends Durable{
return 0;
}
public function onClickAir(Player $player, Vector3 $directionVector) : ItemUseResult{
public function onClickAir(Player $player, Vector3 $directionVector, array &$returnedItems) : ItemUseResult{
$existing = $player->getArmorInventory()->getItem($this->getArmorSlot());
$thisCopy = clone $this;
$new = $thisCopy->pop();
$player->getArmorInventory()->setItem($this->getArmorSlot(), $new);
if($thisCopy->getCount() === 0){
$player->getInventory()->setItemInHand($existing);
}else{ //if the stack size was bigger than 1 (usually won't happen, but might be caused by plugins
$player->getInventory()->setItemInHand($thisCopy);
$player->getInventory()->addItem($existing);
$player->getInventory()->setItemInHand($existing);
if(!$thisCopy->isNull()){
//if the stack size was bigger than 1 (usually won't happen, but might be caused by plugins)
$returnedItems[] = $thisCopy;
}
return ItemUseResult::SUCCESS();
}

View File

@@ -41,14 +41,14 @@ class Axe extends TieredTool{
return $this->tier->getBaseAttackPoints() - 1;
}
public function onDestroyBlock(Block $block) : bool{
public function onDestroyBlock(Block $block, array &$returnedItems) : bool{
if(!$block->getBreakInfo()->breaksInstantly()){
return $this->applyDamage(1);
}
return false;
}
public function onAttackEntity(Entity $victim) : bool{
public function onAttackEntity(Entity $victim, array &$returnedItems) : bool{
return $this->applyDamage(2);
}
}

View File

@@ -44,7 +44,7 @@ class Bow extends Tool implements Releasable{
return 385;
}
public function onReleaseUsing(Player $player) : ItemUseResult{
public function onReleaseUsing(Player $player, array &$returnedItems) : ItemUseResult{
$arrow = VanillaItems::ARROW();
$inventory = match(true){
$player->getOffHandInventory()->contains($arrow) => $player->getOffHandInventory(),

View File

@@ -37,7 +37,7 @@ class Bucket extends Item{
return 16;
}
public function onInteractBlock(Player $player, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector) : ItemUseResult{
public function onInteractBlock(Player $player, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, array &$returnedItems) : ItemUseResult{
//TODO: move this to generic placement logic
if($blockClicked instanceof Liquid && $blockClicked->isSource()){
$stack = clone $this;
@@ -57,16 +57,9 @@ class Bucket extends Item{
if(!$ev->isCancelled()){
$player->getWorld()->setBlock($blockClicked->getPosition(), VanillaBlocks::AIR());
$player->getWorld()->addSound($blockClicked->getPosition()->add(0.5, 0.5, 0.5), $blockClicked->getBucketFillSound());
if($player->hasFiniteResources()){
if($stack->getCount() === 0){
$player->getInventory()->setItemInHand($ev->getItem());
}else{
$player->getInventory()->setItemInHand($stack);
$player->getInventory()->addItem($ev->getItem());
}
}else{
$player->getInventory()->addItem($ev->getItem());
}
$this->pop();
$returnedItems[] = $ev->getItem();
return ItemUseResult::SUCCESS();
}

View File

@@ -32,7 +32,7 @@ use pocketmine\world\sound\FlintSteelSound;
class FlintSteel extends Tool{
public function onInteractBlock(Player $player, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector) : ItemUseResult{
public function onInteractBlock(Player $player, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, array &$returnedItems) : ItemUseResult{
if($blockReplace->getTypeId() === BlockTypeIds::AIR){
$world = $player->getWorld();
$world->setBlock($blockReplace->getPosition(), VanillaBlocks::FIRE());

View File

@@ -33,11 +33,11 @@ class Hoe extends TieredTool{
return BlockToolType::HOE;
}
public function onAttackEntity(Entity $victim) : bool{
public function onAttackEntity(Entity $victim, array &$returnedItems) : bool{
return $this->applyDamage(1);
}
public function onDestroyBlock(Block $block) : bool{
public function onDestroyBlock(Block $block, array &$returnedItems) : bool{
if(!$block->getBreakInfo()->breaksInstantly()){
return $this->applyDamage(1);
}

View File

@@ -513,38 +513,48 @@ class Item implements \JsonSerializable{
/**
* Called when a player uses this item on a block.
*
* @param Item[] &$returnedItems Items to be added to the target's inventory (or dropped, if the inventory is full)
*/
public function onInteractBlock(Player $player, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector) : ItemUseResult{
public function onInteractBlock(Player $player, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, array &$returnedItems) : ItemUseResult{
return ItemUseResult::NONE();
}
/**
* Called when a player uses the item on air, for example throwing a projectile.
* Returns whether the item was changed, for example count decrease or durability change.
*
* @param Item[] &$returnedItems Items to be added to the target's inventory (or dropped, if the inventory is full)
*/
public function onClickAir(Player $player, Vector3 $directionVector) : ItemUseResult{
public function onClickAir(Player $player, Vector3 $directionVector, array &$returnedItems) : ItemUseResult{
return ItemUseResult::NONE();
}
/**
* Called when a player is using this item and releases it. Used to handle bow shoot actions.
* Returns whether the item was changed, for example count decrease or durability change.
*
* @param Item[] &$returnedItems Items to be added to the target's inventory (or dropped, if the inventory is full)
*/
public function onReleaseUsing(Player $player) : ItemUseResult{
public function onReleaseUsing(Player $player, array &$returnedItems) : ItemUseResult{
return ItemUseResult::NONE();
}
/**
* Called when this item is used to destroy a block. Usually used to update durability.
*
* @param Item[] &$returnedItems Items to be added to the target's inventory (or dropped, if the inventory is full)
*/
public function onDestroyBlock(Block $block) : bool{
public function onDestroyBlock(Block $block, array &$returnedItems) : bool{
return false;
}
/**
* Called when this item is used to attack an entity. Usually used to update durability.
*
* @param Item[] &$returnedItems Items to be added to the target's inventory (or dropped, if the inventory is full)
*/
public function onAttackEntity(Entity $victim) : bool{
public function onAttackEntity(Entity $victim, array &$returnedItems) : bool{
return false;
}

View File

@@ -54,7 +54,7 @@ class LiquidBucket extends Item{
return VanillaItems::BUCKET();
}
public function onInteractBlock(Player $player, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector) : ItemUseResult{
public function onInteractBlock(Player $player, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, array &$returnedItems) : ItemUseResult{
if(!$blockReplace->canBeReplaced()){
return ItemUseResult::NONE();
}
@@ -68,9 +68,8 @@ class LiquidBucket extends Item{
$player->getWorld()->setBlock($blockReplace->getPosition(), $resultBlock->getFlowingForm());
$player->getWorld()->addSound($blockReplace->getPosition()->add(0.5, 0.5, 0.5), $resultBlock->getBucketEmptySound());
if($player->hasFiniteResources()){
$player->getInventory()->setItemInHand($ev->getItem());
}
$this->pop();
$returnedItems[] = $ev->getItem();
return ItemUseResult::SUCCESS();
}

View File

@@ -37,7 +37,7 @@ use function count;
class PaintingItem extends Item{
public function onInteractBlock(Player $player, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector) : ItemUseResult{
public function onInteractBlock(Player $player, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, array &$returnedItems) : ItemUseResult{
if(Facing::axis($face) === Axis::Y){
return ItemUseResult::NONE();
}

View File

@@ -41,14 +41,14 @@ class Pickaxe extends TieredTool{
return $this->tier->getBaseAttackPoints() - 2;
}
public function onDestroyBlock(Block $block) : bool{
public function onDestroyBlock(Block $block, array &$returnedItems) : bool{
if(!$block->getBreakInfo()->breaksInstantly()){
return $this->applyDamage(1);
}
return false;
}
public function onAttackEntity(Entity $victim) : bool{
public function onAttackEntity(Entity $victim, array &$returnedItems) : bool{
return $this->applyDamage(2);
}
}

View File

@@ -36,7 +36,7 @@ abstract class ProjectileItem extends Item{
abstract protected function createEntity(Location $location, Player $thrower) : Throwable;
public function onClickAir(Player $player, Vector3 $directionVector) : ItemUseResult{
public function onClickAir(Player $player, Vector3 $directionVector, array &$returnedItems) : ItemUseResult{
$location = $player->getLocation();
$projectile = $this->createEntity(Location::fromObject($player->getEyePos(), $player->getWorld(), $location->yaw, $location->pitch), $player);

View File

@@ -44,7 +44,7 @@ class Shears extends Tool{
return 15;
}
public function onDestroyBlock(Block $block) : bool{
public function onDestroyBlock(Block $block, array &$returnedItems) : bool{
return $this->applyDamage(1);
}
}

View File

@@ -41,14 +41,14 @@ class Shovel extends TieredTool{
return $this->tier->getBaseAttackPoints() - 3;
}
public function onDestroyBlock(Block $block) : bool{
public function onDestroyBlock(Block $block, array &$returnedItems) : bool{
if(!$block->getBreakInfo()->breaksInstantly()){
return $this->applyDamage(1);
}
return false;
}
public function onAttackEntity(Entity $victim) : bool{
public function onAttackEntity(Entity $victim, array &$returnedItems) : bool{
return $this->applyDamage(2);
}
}

View File

@@ -34,7 +34,7 @@ abstract class SpawnEgg extends Item{
abstract protected function createEntity(World $world, Vector3 $pos, float $yaw, float $pitch) : Entity;
public function onInteractBlock(Player $player, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector) : ItemUseResult{
public function onInteractBlock(Player $player, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, array &$returnedItems) : ItemUseResult{
$entity = $this->createEntity($player->getWorld(), $blockReplace->getPosition()->add(0.5, 0, 0.5), lcg_value() * 360, 0);
if($this->hasCustomName()){

View File

@@ -49,14 +49,14 @@ class Sword extends TieredTool{
return 10;
}
public function onDestroyBlock(Block $block) : bool{
public function onDestroyBlock(Block $block, array &$returnedItems) : bool{
if(!$block->getBreakInfo()->breaksInstantly()){
return $this->applyDamage(2);
}
return false;
}
public function onAttackEntity(Entity $victim) : bool{
public function onAttackEntity(Entity $victim, array &$returnedItems) : bool{
return $this->applyDamage(1);
}
}