From e79976bdac4b47ab3358ff9c2dc7a1cc8515f3e7 Mon Sep 17 00:00:00 2001 From: PEMapModder Date: Thu, 11 Feb 2016 22:07:04 +0800 Subject: [PATCH] Added events --- src/pocketmine/Player.php | 14 +-- src/pocketmine/block/Cake.php | 42 +++++--- src/pocketmine/entity/Effect.php | 19 ++-- src/pocketmine/entity/Human.php | 17 +++- .../event/entity/EntityEatBlockEvent.php | 49 +++++++++ .../event/entity/EntityEatEvent.php | 99 +++++++++++++++++++ .../event/entity/EntityEatItemEvent.php | 47 +++++++++ .../event/player/PlayerExhaustEvent.php | 66 +++++++++++++ src/pocketmine/item/BeetrootSoup.php | 2 +- src/pocketmine/item/Fish.php | 2 +- src/pocketmine/item/Food.php | 35 ++++--- src/pocketmine/item/FoodSource.php | 37 +++++++ src/pocketmine/item/GoldenApple.php | 2 +- src/pocketmine/item/Item.php | 11 +++ src/pocketmine/item/MushroomStew.php | 2 +- src/pocketmine/item/Potion.php | 10 ++ src/pocketmine/item/RawChicken.php | 2 +- src/pocketmine/item/SpiderEye.php | 2 +- 18 files changed, 405 insertions(+), 53 deletions(-) create mode 100644 src/pocketmine/event/entity/EntityEatBlockEvent.php create mode 100644 src/pocketmine/event/entity/EntityEatEvent.php create mode 100644 src/pocketmine/event/entity/EntityEatItemEvent.php create mode 100644 src/pocketmine/event/player/PlayerExhaustEvent.php create mode 100644 src/pocketmine/item/FoodSource.php diff --git a/src/pocketmine/Player.php b/src/pocketmine/Player.php index a1c2f810f..19dd1696b 100644 --- a/src/pocketmine/Player.php +++ b/src/pocketmine/Player.php @@ -48,6 +48,7 @@ use pocketmine\event\player\PlayerChatEvent; use pocketmine\event\player\PlayerCommandPreprocessEvent; use pocketmine\event\player\PlayerDeathEvent; use pocketmine\event\player\PlayerDropItemEvent; +use pocketmine\event\player\PlayerExhaustEvent; use pocketmine\event\player\PlayerGameModeChangeEvent; use pocketmine\event\player\PlayerInteractEvent; use pocketmine\event\player\PlayerItemConsumeEvent; @@ -75,7 +76,6 @@ use pocketmine\inventory\PlayerInventory; use pocketmine\inventory\ShapedRecipe; use pocketmine\inventory\ShapelessRecipe; use pocketmine\inventory\SimpleTransactionGroup; -use pocketmine\item\Food; use pocketmine\item\Item; use pocketmine\level\ChunkLoader; use pocketmine\level\format\FullChunk; @@ -2267,7 +2267,7 @@ class Player extends Human implements CommandSender, InventoryHolder, ChunkLoade $this->inventory->sendHeldItem($this->hasSpawned); } - $this->exhaust(0.025); + $this->exhaust(0.025, PlayerExhaustEvent::CAUSE_MINING); } break; } @@ -2408,7 +2408,7 @@ class Player extends Human implements CommandSender, InventoryHolder, ChunkLoade } } - $this->exhaust(0.3); + $this->exhaust(0.3, PlayerExhaustEvent::CAUSE_ATTACK); } } @@ -2442,14 +2442,14 @@ class Player extends Human implements CommandSender, InventoryHolder, ChunkLoade case EntityEventPacket::USE_ITEM: //Eating $slot = $this->inventory->getItemInHand(); - if($slot instanceof Food){ + if($slot->canBeConsumed()){ $ev = new PlayerItemConsumeEvent($this, $slot); - if($this->getFood() >= $this->getMaxFood()){ + if(!$slot->canBeConsumedBy($this)){ $ev->setCancelled(); } $this->server->getPluginManager()->callEvent($ev); if(!$ev->isCancelled()){ - $slot->onEat($this); + $slot->onConsume($this); }else{ $this->inventory->sendContents($this); } @@ -3226,7 +3226,7 @@ class Player extends Human implements CommandSender, InventoryHolder, ChunkLoade $this->dataPacket($pk); if($this->isSurvival()){ - $this->exhaust(0.3); + $this->exhaust(0.3, PlayerExhaustEvent::CAUSE_DAMAGE); } } } diff --git a/src/pocketmine/block/Cake.php b/src/pocketmine/block/Cake.php index 90f8efca6..e9c9a3880 100644 --- a/src/pocketmine/block/Cake.php +++ b/src/pocketmine/block/Cake.php @@ -21,14 +21,15 @@ namespace pocketmine\block; -use pocketmine\event\entity\EntityRegainHealthEvent; +use pocketmine\entity\Effect; +use pocketmine\event\entity\EntityEatBlockEvent; +use pocketmine\item\FoodSource; use pocketmine\item\Item; use pocketmine\level\Level; use pocketmine\math\AxisAlignedBB; use pocketmine\Player; - -class Cake extends Transparent{ +class Cake extends Transparent implements FoodSource{ protected $id = self::CAKE_BLOCK; @@ -91,18 +92,10 @@ class Cake extends Transparent{ public function onActivate(Item $item, Player $player = null){ if($player instanceof Player and $player->getHealth() < $player->getMaxHealth()){ - ++$this->meta; - - $ev = new EntityRegainHealthEvent($player, 3, EntityRegainHealthEvent::CAUSE_EATING); - $player->heal($ev->getAmount(), $ev); // TODO hunger + $ev = new EntityEatBlockEvent($player, $this); if(!$ev->isCancelled()){ - if($this->meta >= 0x06){ - $this->getLevel()->setBlock($this, new Air(), true); - }else{ - $this->getLevel()->setBlock($this, $this, true); - } - + $this->getLevel()->setBlock($this, $ev->getResidue()); return true; } } @@ -110,4 +103,27 @@ class Cake extends Transparent{ return false; } + public function getFoodRestore() : int{ + return 2; + } + + public function getSaturationRestore() : float{ + return 0.4; + } + + public function getResidue(){ + $clone = clone $this; + $clone->meta++; + if($clone->meta >= 0x06){ + $clone = new Air(); + } + return $clone; + } + + /** + * @return Effect[] + */ + public function getAdditionalEffects() : array{ + return []; + } } diff --git a/src/pocketmine/entity/Effect.php b/src/pocketmine/entity/Effect.php index 8ed114a98..56f4ff660 100644 --- a/src/pocketmine/entity/Effect.php +++ b/src/pocketmine/entity/Effect.php @@ -23,6 +23,7 @@ namespace pocketmine\entity; use pocketmine\event\entity\EntityDamageEvent; use pocketmine\event\entity\EntityRegainHealthEvent; +use pocketmine\event\player\PlayerExhaustEvent; use pocketmine\network\protocol\MobEffectPacket; use pocketmine\Player; @@ -34,8 +35,8 @@ class Effect{ const FATIGUE = 4; const MINING_FATIGUE = 4; const STRENGTH = 5; - //TODO: const HEALING = 6; - //TODO: const HARMING = 7; +// TODO: const HEALING = 6; +// TODO: const HARMING = 7; const JUMP = 8; const NAUSEA = 9; const CONFUSION = 9; @@ -46,7 +47,7 @@ class Effect{ const INVISIBILITY = 14; const BLINDNESS = 15; const NIGHT_VISION = 16; - const HUNGER = 17; // TODO implement + const HUNGER = 17; const WEAKNESS = 18; const POISON = 19; const WITHER = 20; @@ -74,15 +75,15 @@ class Effect{ self::$effects[Effect::FIRE_RESISTANCE] = new Effect(Effect::FIRE_RESISTANCE, "%potion.fireResistance", 228, 154, 58); self::$effects[Effect::WATER_BREATHING] = new Effect(Effect::WATER_BREATHING, "%potion.waterBreathing", 46, 82, 153); self::$effects[Effect::INVISIBILITY] = new Effect(Effect::INVISIBILITY, "%potion.invisibility", 127, 131, 146); - // TODO Blindness %potion.blindness - // TODO Night Vision %potion.nightVision - // TODO Hunger %potion.hunger + self::$effects[Effect::BLINDNESS] = new Effect(Effect::BLINDNESS, "%potion.blindness", 191, 192, 192); + self::$effects[Effect::NIGHT_VISION] = new Effect(Effect::NIGHT_VISION, "%potion.nightVision", 0, 0, 139); + self::$effects[Effect::HUNGER] = new Effect(Effect::HUNGER, "%potion.hunger", 46, 139, 87); self::$effects[Effect::WEAKNESS] = new Effect(Effect::WEAKNESS, "%potion.weakness", 72, 77, 72, true); self::$effects[Effect::POISON] = new Effect(Effect::POISON, "%potion.poison", 78, 147, 49, true); self::$effects[Effect::WITHER] = new Effect(Effect::WITHER, "%potion.wither", 53, 42, 39, true); self::$effects[Effect::HEALTH_BOOST] = new Effect(Effect::HEALTH_BOOST, "%potion.healthBoost", 248, 125, 35); - // TODO Absorption %potion.absorption - // TODO Saturation %potion.saturation + self::$effects[Effect::ABSORPTION] = new Effect(Effect::ABSORPTION, "%potion.absorption", 36, 107, 251); + self::$effects[Effect::SATURATION] = new Effect(Effect::SATURATION, "%potion.saturation", 255, 0, 255); } /** @@ -236,7 +237,7 @@ class Effect{ case Effect::HUNGER: if($entity instanceof Human){ - $entity->exhaust(0.5 * $this->amplifier); + $entity->exhaust(0.5 * $this->amplifier, PlayerExhaustEvent::CAUSE_POTION); } } } diff --git a/src/pocketmine/entity/Human.php b/src/pocketmine/entity/Human.php index 4f0471570..9cba80291 100644 --- a/src/pocketmine/entity/Human.php +++ b/src/pocketmine/entity/Human.php @@ -23,6 +23,7 @@ namespace pocketmine\entity; use pocketmine\event\entity\EntityDamageEvent; use pocketmine\event\entity\EntityRegainHealthEvent; +use pocketmine\event\player\PlayerExhaustEvent; use pocketmine\inventory\InventoryHolder; use pocketmine\inventory\PlayerInventory; use pocketmine\item\Item as ItemItem; @@ -170,10 +171,18 @@ class Human extends Creature implements ProjectileSource, InventoryHolder{ * Increases a human's exhaustion level. * * @param float $amount + * @param int $cause + * + * @return float the amount of exhaustion level increased */ - public function exhaust(float $amount){ + public function exhaust(float $amount, int $cause = PlayerExhaustEvent::CAUSE_CUSTOM) : float{ + $this->server->getPluginManager()->callEvent($ev = new PlayerExhaustEvent($this, $amount, $cause)); + if($ev->isCancelled()){ + return 0.0; + } + $exhaustion = $this->getExhaustion(); - $exhaustion += $amount; + $exhaustion += $ev->getAmount(); while($exhaustion >= 4.0){ $exhaustion -= 4.0; @@ -191,6 +200,8 @@ class Human extends Creature implements ProjectileSource, InventoryHolder{ } } $this->setExhaustion($exhaustion); + + return $ev->getAmount(); } public function getInventory(){ @@ -254,7 +265,7 @@ class Human extends Creature implements ProjectileSource, InventoryHolder{ $this->foodTickTimer++; if($this->foodTickTimer >= 80){ $this->heal(1, new EntityRegainHealthEvent($this, 1, EntityRegainHealthEvent::CAUSE_SATURATION)); - $this->exhaust(3.0); + $this->exhaust(3.0, PlayerExhaustEvent::CAUSE_HEALTH_REGEN); $this->foodTickTimer = 0; } }elseif($food === 0){ diff --git a/src/pocketmine/event/entity/EntityEatBlockEvent.php b/src/pocketmine/event/entity/EntityEatBlockEvent.php new file mode 100644 index 000000000..969dc9a1b --- /dev/null +++ b/src/pocketmine/event/entity/EntityEatBlockEvent.php @@ -0,0 +1,49 @@ +entity = $entity; + $this->foodSource = $foodSource; + $this->foodRestore = $foodSource->getFoodRestore(); + $this->saturationRestore = $foodSource->getSaturationRestore(); + $this->residue = $foodSource->getResidue(); + $this->additionalEffects = $foodSource->getAdditionalEffects(); + } + + public function getFoodSource(){ + return $this->foodSource; + } + + public function getFoodRestore() : int{ + return $this->foodRestore; + } + + public function setFoodRestore(int $foodRestore){ + $this->foodRestore = $foodRestore; + } + + public function getSaturationRestore() : float{ + return $this->saturationRestore; + } + + public function setSaturationRestore(float $saturationRestore){ + $this->saturationRestore = $saturationRestore; + } + + public function getResidue(){ + return $this->residue; + } + + public function setResidue($residue){ + $this->residue = $residue; + } + + /** + * @return Effect[] + */ + public function getAdditionalEffects(){ + return $this->additionalEffects; + } + + /** + * @param Effect[] $additionalEffects + * + * @throws \TypeError + */ + public function setAdditionalEffects(array $additionalEffects){ + foreach($additionalEffects as $effect){ + if(!($effect instanceof Effect)){ + throw new \TypeError("Argument 1 passed to EntityEatEvent::setAdditionalEffects() must be an Effect array"); + } + } + $this->additionalEffects = $additionalEffects; + } +} diff --git a/src/pocketmine/event/entity/EntityEatItemEvent.php b/src/pocketmine/event/entity/EntityEatItemEvent.php new file mode 100644 index 000000000..9293f8351 --- /dev/null +++ b/src/pocketmine/event/entity/EntityEatItemEvent.php @@ -0,0 +1,47 @@ +player = $human; + $this->amount = $amount; + } + + /** + * @return Human|Player + */ + public function getPlayer(){ + return $this->player; + } + + public function getAmount() : float{ + return $this->amount; + } + + public function setAmount(float $amount){ + $this->amount = $amount; + } +} diff --git a/src/pocketmine/item/BeetrootSoup.php b/src/pocketmine/item/BeetrootSoup.php index 626167e30..9f221f1ae 100644 --- a/src/pocketmine/item/BeetrootSoup.php +++ b/src/pocketmine/item/BeetrootSoup.php @@ -39,7 +39,7 @@ class BeetrootSoup extends Food{ return 7.2; } - public function getResidue() : Item{ + public function getResidue(){ return Item::get(Item::BOWL); } } \ No newline at end of file diff --git a/src/pocketmine/item/Fish.php b/src/pocketmine/item/Fish.php index aa6c9e5fc..58e5da42f 100644 --- a/src/pocketmine/item/Fish.php +++ b/src/pocketmine/item/Fish.php @@ -67,7 +67,7 @@ class Fish extends Food{ return 0; } - public function getAdditionEffects() : array{ + public function getAdditionalEffects() : array{ return $this->meta === self::FISH_PUFFERFISH ? [ Effect::getEffect(Effect::HUNGER)->setDuration(300)->setAmplifier(2), Effect::getEffect(Effect::NAUSEA)->setDuration(300)->setAmplifier(1), diff --git a/src/pocketmine/item/Food.php b/src/pocketmine/item/Food.php index 52ba6bbb1..6fd6bfacf 100644 --- a/src/pocketmine/item/Food.php +++ b/src/pocketmine/item/Food.php @@ -21,18 +21,23 @@ namespace pocketmine\item; -use pocketmine\entity\Effect; +use pocketmine\entity\Entity; use pocketmine\entity\Human; +use pocketmine\event\entity\EntityEatItemEvent; use pocketmine\network\protocol\EntityEventPacket; use pocketmine\Player; use pocketmine\Server; -abstract class Food extends Item{ - public abstract function getFoodRestore() : int; +abstract class Food extends Item implements FoodSource{ + public function canBeConsumed() : bool{ + return true; + } - public abstract function getSaturationRestore() : float; + public function canBeConsumedBy(Entity $entity){ + return $entity instanceof Human and $entity->getFood() < $entity->getMaxFood(); + } - public function getResidue() : Item{ + public function getResidue(){ if($this->getCount() === 1){ return Item::get(0); }else{ @@ -42,14 +47,11 @@ abstract class Food extends Item{ } } - /** - * @return Effect[] - */ - public function getAdditionEffects() : array{ + public function getAdditionalEffects() : array{ return []; } - public function onEat(Human $human){ + public function onConsume(Entity $human){ $pk = new EntityEventPacket(); $pk->eid = $human->getId(); $pk->event = EntityEventPacket::USE_ITEM; @@ -57,12 +59,15 @@ abstract class Food extends Item{ $human->dataPacket($pk); } Server::broadcastPacket($human->getViewers(), $pk); - - $human->addSaturation($this->getSaturationRestore()); - $human->addFood($this->getFoodRestore()); - foreach($this->getAdditionEffects() as $effect){ + + $ev = new EntityEatItemEvent($human, $this); + + $human->addSaturation($ev->getSaturationRestore()); + $human->addFood($ev->getFoodRestore()); + foreach($ev->getAdditionalEffects() as $effect){ $human->addEffect($effect); } - $human->getInventory()->setItemInHand($this->getResidue()); + + $human->getInventory()->setItemInHand($ev->getResidue()); } } diff --git a/src/pocketmine/item/FoodSource.php b/src/pocketmine/item/FoodSource.php new file mode 100644 index 000000000..ed3834361 --- /dev/null +++ b/src/pocketmine/item/FoodSource.php @@ -0,0 +1,37 @@ +meta === 1 ? [ Effect::getEffect(Effect::REGENERATION)->setDuration(600)->setAmplifier(4), Effect::getEffect(Effect::ABSORPTION)->setDuration(2400), diff --git a/src/pocketmine/item/Item.php b/src/pocketmine/item/Item.php index c631f706b..8bcb4887b 100644 --- a/src/pocketmine/item/Item.php +++ b/src/pocketmine/item/Item.php @@ -1042,6 +1042,17 @@ class Item{ return $this->block !== null and $this->block->canBePlaced(); } + public function canBeConsumed() : bool{ + return false; + } + + public function canBeConsumedBy(Entity $entity) : bool{ + return $this->canBeConsumed(); + } + + public function onConsume(Entity $entity){ + } + public function getBlock() : Block{ if($this->block instanceof Block){ return clone $this->block; diff --git a/src/pocketmine/item/MushroomStew.php b/src/pocketmine/item/MushroomStew.php index b729bbdc5..4c315ab9a 100644 --- a/src/pocketmine/item/MushroomStew.php +++ b/src/pocketmine/item/MushroomStew.php @@ -38,7 +38,7 @@ class MushroomStew extends Food{ return 7.2; } - public function getResidue() : Item{ + public function getResidue(){ return Item::get(Item::BOWL); } } diff --git a/src/pocketmine/item/Potion.php b/src/pocketmine/item/Potion.php index 8a6bac037..af879be24 100644 --- a/src/pocketmine/item/Potion.php +++ b/src/pocketmine/item/Potion.php @@ -21,8 +21,18 @@ namespace pocketmine\item; +use pocketmine\entity\Entity; + class Potion extends Item{ public function __construct($meta = 0, $count = 1){ parent::__construct(self::POTION, $meta, $count, "Potion"); } + + public function canBeConsumed() : bool{ + return true; + } + + public function onConsume(Entity $entity){ + // TODO: Implement potions + } } diff --git a/src/pocketmine/item/RawChicken.php b/src/pocketmine/item/RawChicken.php index a7a07a06a..244191287 100644 --- a/src/pocketmine/item/RawChicken.php +++ b/src/pocketmine/item/RawChicken.php @@ -36,7 +36,7 @@ class RawChicken extends Food{ return 1.2; } - public function getAdditionEffects() : array{ + public function getAdditionalEffects() : array{ if(mt_rand(0, 9) < 3){ return Effect::getEffect(Effect::HUNGER)->setDuration(600); } diff --git a/src/pocketmine/item/SpiderEye.php b/src/pocketmine/item/SpiderEye.php index 3d8d67296..049e4c6f9 100644 --- a/src/pocketmine/item/SpiderEye.php +++ b/src/pocketmine/item/SpiderEye.php @@ -36,7 +36,7 @@ class SpiderEye extends Food{ return 3.2; } - public function getAdditionEffects() : array{ + public function getAdditionalEffects() : array{ return [Effect::getEffect(Effect::POISON)->setDuration(80)]; } }