mirror of
https://github.com/pmmp/PocketMine-MP.git
synced 2025-09-08 10:53:05 +00:00
Consumables refactor (#1796)
* Removed broken EntityEatEvents - these don't fit the pattern since they only apply to Human entities anyway. PlayerItemConsumeEvent and PlayerInteractEvent can be used for cancellation purposes, and plugins can do custom stuff without mess. * Restrict item consuming to Living entities only * Added FoodSource->requiresHunger() * Only items implementing the Consumable interface can now be consumed. * The effects from consuming items are now generic-ized by way of the Living->consume() function. This is overridden in Human to allow applying food and hunger. * Fixed the hardcoded mess for buckets
This commit is contained in:
@ -27,13 +27,14 @@ use pocketmine\block\Air;
|
||||
use pocketmine\block\Block;
|
||||
use pocketmine\block\BlockFactory;
|
||||
use pocketmine\block\Liquid;
|
||||
use pocketmine\entity\Living;
|
||||
use pocketmine\event\player\PlayerBucketEmptyEvent;
|
||||
use pocketmine\event\player\PlayerBucketFillEvent;
|
||||
use pocketmine\level\Level;
|
||||
use pocketmine\math\Vector3;
|
||||
use pocketmine\Player;
|
||||
|
||||
class Bucket extends Item{
|
||||
class Bucket extends Item implements Consumable{
|
||||
public function __construct(int $meta = 0){
|
||||
parent::__construct(self::BUCKET, $meta, "Bucket");
|
||||
}
|
||||
@ -85,4 +86,20 @@ class Bucket extends Item{
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public function getResidue(){
|
||||
return ItemFactory::get(Item::BUCKET, 0, 1);
|
||||
}
|
||||
|
||||
public function getAdditionalEffects() : array{
|
||||
return [];
|
||||
}
|
||||
|
||||
public function canBeConsumed() : bool{
|
||||
return $this->meta === 1; //Milk
|
||||
}
|
||||
|
||||
public function onConsume(Living $consumer){
|
||||
$consumer->removeAllEffects();
|
||||
}
|
||||
}
|
||||
|
@ -23,14 +23,32 @@ declare(strict_types=1);
|
||||
|
||||
namespace pocketmine\item;
|
||||
|
||||
use pocketmine\block\Block;
|
||||
use pocketmine\entity\Effect;
|
||||
use pocketmine\entity\Living;
|
||||
|
||||
/**
|
||||
* Interface implemented by objects that can be consumed by mobs.
|
||||
*/
|
||||
interface Consumable{
|
||||
|
||||
/**
|
||||
* Returns the leftover that this Consumable produces when it is consumed. For Items, this is usually air, but could
|
||||
* be an Item to add to a Player's inventory afterwards (such as a bowl).
|
||||
*
|
||||
* @return Item|Block|mixed
|
||||
*/
|
||||
public function getResidue();
|
||||
|
||||
/**
|
||||
* @return Effect[]
|
||||
*/
|
||||
public function getAdditionalEffects() : array;
|
||||
|
||||
/**
|
||||
* Called when this Consumable is consumed by mob, after standard resulting effects have been applied.
|
||||
*
|
||||
* @param Living $consumer
|
||||
*/
|
||||
public function onConsume(Living $consumer);
|
||||
}
|
||||
|
@ -23,42 +23,25 @@ declare(strict_types=1);
|
||||
|
||||
namespace pocketmine\item;
|
||||
|
||||
use pocketmine\entity\Entity;
|
||||
use pocketmine\entity\Human;
|
||||
use pocketmine\event\entity\EntityEatItemEvent;
|
||||
use pocketmine\entity\Living;
|
||||
|
||||
abstract class Food extends Item implements FoodSource{
|
||||
public function canBeConsumed() : bool{
|
||||
public function requiresHunger() : bool{
|
||||
return true;
|
||||
}
|
||||
|
||||
public function canBeConsumedBy(Entity $entity) : bool{
|
||||
return $entity instanceof Human and $entity->getFood() < $entity->getMaxFood();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Item
|
||||
*/
|
||||
public function getResidue(){
|
||||
if($this->getCount() === 1){
|
||||
return ItemFactory::get(0);
|
||||
}else{
|
||||
$new = clone $this;
|
||||
$new->count--;
|
||||
return $new;
|
||||
}
|
||||
return ItemFactory::get(Item::AIR, 0, 0);
|
||||
}
|
||||
|
||||
public function getAdditionalEffects() : array{
|
||||
return [];
|
||||
}
|
||||
|
||||
public function onConsume(Entity $human){
|
||||
$ev = new EntityEatItemEvent($human, $this);
|
||||
public function onConsume(Living $consumer){
|
||||
|
||||
$human->addSaturation($ev->getSaturationRestore());
|
||||
$human->addFood($ev->getFoodRestore());
|
||||
foreach($ev->getAdditionalEffects() as $effect){
|
||||
$human->addEffect($effect);
|
||||
}
|
||||
|
||||
$human->getInventory()->setItemInHand($ev->getResidue());
|
||||
}
|
||||
}
|
||||
|
@ -23,9 +23,18 @@ declare(strict_types=1);
|
||||
|
||||
namespace pocketmine\item;
|
||||
|
||||
/**
|
||||
* Interface implemented by objects that can be consumed by players, giving them food and saturation.
|
||||
*/
|
||||
interface FoodSource extends Consumable{
|
||||
|
||||
public function getFoodRestore() : int;
|
||||
|
||||
public function getSaturationRestore() : float;
|
||||
|
||||
/**
|
||||
* Returns whether a Human eating this FoodSource must have a non-full hunger bar.
|
||||
* @return bool
|
||||
*/
|
||||
public function requiresHunger() : bool;
|
||||
}
|
||||
|
@ -24,8 +24,6 @@ declare(strict_types=1);
|
||||
namespace pocketmine\item;
|
||||
|
||||
use pocketmine\entity\Effect;
|
||||
use pocketmine\entity\Entity;
|
||||
use pocketmine\entity\Human;
|
||||
|
||||
class GoldenApple extends Food{
|
||||
|
||||
@ -33,8 +31,8 @@ class GoldenApple extends Food{
|
||||
parent::__construct(self::GOLDEN_APPLE, $meta, "Golden Apple");
|
||||
}
|
||||
|
||||
public function canBeConsumedBy(Entity $entity) : bool{
|
||||
return $entity instanceof Human;
|
||||
public function requiresHunger() : bool{
|
||||
return false;
|
||||
}
|
||||
|
||||
public function getFoodRestore() : int{
|
||||
|
@ -621,32 +621,6 @@ class Item implements ItemIds, \JsonSerializable{
|
||||
return $this->block !== null and $this->block->canBePlaced();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether an entity can eat or drink this item.
|
||||
* @return bool
|
||||
*/
|
||||
public function canBeConsumed() : bool{
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether this item can be consumed by the supplied Entity.
|
||||
* @param Entity $entity
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function canBeConsumedBy(Entity $entity) : bool{
|
||||
return $this->canBeConsumed();
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when the item is consumed by an Entity.
|
||||
* @param Entity $entity
|
||||
*/
|
||||
public function onConsume(Entity $entity){
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the block corresponding to this Item.
|
||||
* @return Block
|
||||
|
@ -23,7 +23,7 @@ declare(strict_types=1);
|
||||
|
||||
namespace pocketmine\item;
|
||||
|
||||
use pocketmine\entity\Entity;
|
||||
use pocketmine\entity\Living;
|
||||
|
||||
class Potion extends Item{
|
||||
public function __construct(int $meta = 0){
|
||||
@ -38,7 +38,7 @@ class Potion extends Item{
|
||||
return 1;
|
||||
}
|
||||
|
||||
public function onConsume(Entity $entity){
|
||||
public function onConsume(Living $consumer){
|
||||
// TODO: Implement potions
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user