diff --git a/src/pocketmine/Player.php b/src/pocketmine/Player.php index 5cb528a02..3e07ebaea 100644 --- a/src/pocketmine/Player.php +++ b/src/pocketmine/Player.php @@ -2376,11 +2376,7 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{ $this->level->sendBlocks([$this], [$target, $block], UpdateBlockPacket::FLAG_ALL_PRIORITY); return true; }elseif($packet->face === -1){ - $directionVector = new Vector3( - -sin($this->yaw / 180 * M_PI) * cos($this->pitch / 180 * M_PI), - -sin($this->pitch / 180 * M_PI), - cos($this->yaw / 180 * M_PI) * cos($this->pitch / 180 * M_PI) - ); + $directionVector = $this->getDirectionVector(); if($this->isCreative()){ $item = $this->inventory->getItemInHand(); diff --git a/src/pocketmine/block/Cake.php b/src/pocketmine/block/Cake.php index 65ef59040..0cce711f1 100644 --- a/src/pocketmine/block/Cake.php +++ b/src/pocketmine/block/Cake.php @@ -50,10 +50,10 @@ class Cake extends Transparent implements FoodSource{ protected function recalculateBoundingBox(){ - $f = (1 + $this->getDamage() * 2) / 16; + $f = $this->getDamage() * 0.125; //1 slice width return new AxisAlignedBB( - $this->x + $f, + $this->x + 0.0625 + $f, $this->y, $this->z + 0.0625, $this->x + 1 - 0.0625, @@ -90,10 +90,17 @@ class Cake extends Transparent implements FoodSource{ } public function onActivate(Item $item, Player $player = null) : bool{ - if($player instanceof Player and $player->getHealth() < $player->getMaxHealth()){ - $ev = new EntityEatBlockEvent($player, $this); + //TODO: refactor this into generic food handling + if($player instanceof Player and $player->getFood() < $player->getMaxFood()){ + $player->getServer()->getPluginManager()->callEvent($ev = new EntityEatBlockEvent($player, $this)); if(!$ev->isCancelled()){ + $player->addFood($ev->getFoodRestore()); + $player->addSaturation($ev->getSaturationRestore()); + foreach($ev->getAdditionalEffects() as $effect){ + $player->addEffect($effect); + } + $this->getLevel()->setBlock($this, $ev->getResidue()); return true; } @@ -113,7 +120,7 @@ class Cake extends Transparent implements FoodSource{ public function getResidue(){ $clone = clone $this; $clone->meta++; - if($clone->meta >= 0x06){ + if($clone->meta > 0x06){ $clone = BlockFactory::get(Block::AIR); } return $clone; diff --git a/src/pocketmine/block/Sapling.php b/src/pocketmine/block/Sapling.php index 9597a6d96..e29faebbb 100644 --- a/src/pocketmine/block/Sapling.php +++ b/src/pocketmine/block/Sapling.php @@ -76,9 +76,8 @@ class Sapling extends Flowable{ if($item->getId() === Item::DYE and $item->getDamage() === 0x0F){ //Bonemeal //TODO: change log type Tree::growTree($this->getLevel(), $this->x, $this->y, $this->z, new Random(mt_rand()), $this->meta & 0x07); - if(($player->gamemode & 0x01) === 0){ - $item->count--; - } + + $item->count--; return true; } diff --git a/src/pocketmine/block/Sugarcane.php b/src/pocketmine/block/Sugarcane.php index 6512fbd4a..09280ce3c 100644 --- a/src/pocketmine/block/Sugarcane.php +++ b/src/pocketmine/block/Sugarcane.php @@ -64,9 +64,8 @@ class Sugarcane extends Flowable{ $this->meta = 0; $this->getLevel()->setBlock($this, $this, true); } - if(($player->gamemode & 0x01) === 0){ - $item->count--; - } + + $item->count--; return true; } diff --git a/src/pocketmine/entity/Entity.php b/src/pocketmine/entity/Entity.php index dae3ed5c6..1f71de95f 100644 --- a/src/pocketmine/entity/Entity.php +++ b/src/pocketmine/entity/Entity.php @@ -205,6 +205,7 @@ abstract class Entity extends Location implements Metadatable{ public static $entityCount = 1; /** @var Entity[] */ private static $knownEntities = []; + /** @var string[] */ private static $shortNames = []; public static function init(){ @@ -891,21 +892,7 @@ abstract class Entity extends Location implements Metadatable{ $this->setLastDamageCause($source); - $damage = $source->getFinalDamage(); - - $absorption = $this->getAbsorption(); - if($absorption > 0){ - if($absorption > $damage){ - //Use absorption health before normal health. - $this->setAbsorption($absorption - $damage); - $damage = 0; - }else{ - $this->setAbsorption(0); - $damage -= $absorption; - } - } - - $this->setHealth($this->getHealth() - $damage); + $this->setHealth($this->getHealth() - $source->getFinalDamage()); } /** @@ -952,14 +939,6 @@ abstract class Entity extends Location implements Metadatable{ } } - public function getAbsorption() : float{ - return 0; - } - - public function setAbsorption(float $absorption){ - - } - /** * @param EntityDamageEvent $type */ diff --git a/src/pocketmine/entity/Living.php b/src/pocketmine/entity/Living.php index 8c4d01b19..3cde9874e 100644 --- a/src/pocketmine/entity/Living.php +++ b/src/pocketmine/entity/Living.php @@ -342,8 +342,10 @@ abstract class Living extends Entity implements Damageable{ $source->setCancelled(); } + $source->setDamage(-min($this->getAbsorption(), $source->getFinalDamage()), EntityDamageEvent::MODIFIER_ABSORPTION); + if($this->hasEffect(Effect::DAMAGE_RESISTANCE)){ - $source->setDamage(-($source->getDamage(EntityDamageEvent::MODIFIER_BASE) * 0.20 * $this->getEffect(Effect::DAMAGE_RESISTANCE)->getEffectLevel()), EntityDamageEvent::MODIFIER_RESISTANCE); + $source->setDamage(-($source->getFinalDamage() * 0.20 * $this->getEffect(Effect::DAMAGE_RESISTANCE)->getEffectLevel()), EntityDamageEvent::MODIFIER_RESISTANCE); } parent::attack($source); @@ -369,6 +371,8 @@ abstract class Living extends Entity implements Damageable{ } } + $this->setAbsorption(max(0, $this->getAbsorption() + $source->getDamage(EntityDamageEvent::MODIFIER_ABSORPTION))); + $pk = new EntityEventPacket(); $pk->entityRuntimeId = $this->getId(); $pk->event = $this->getHealth() <= 0 ? EntityEventPacket::DEATH_ANIMATION : EntityEventPacket::HURT_ANIMATION; //Ouch! diff --git a/src/pocketmine/event/entity/EntityDamageEvent.php b/src/pocketmine/event/entity/EntityDamageEvent.php index 836ed2fec..0be966f2c 100644 --- a/src/pocketmine/event/entity/EntityDamageEvent.php +++ b/src/pocketmine/event/entity/EntityDamageEvent.php @@ -37,6 +37,7 @@ class EntityDamageEvent extends EntityEvent implements Cancellable{ const MODIFIER_STRENGTH = 2; const MODIFIER_WEAKNESS = 3; const MODIFIER_RESISTANCE = 4; + const MODIFIER_ABSORPTION = 5; const CAUSE_CONTACT = 0; const CAUSE_ENTITY_ATTACK = 1; @@ -99,11 +100,7 @@ class EntityDamageEvent extends EntityEvent implements Cancellable{ * @return float */ public function getOriginalDamage(int $type = self::MODIFIER_BASE) : float{ - if(isset($this->originals[$type])){ - return $this->originals[$type]; - } - - return 0.0; + return $this->originals[$type] ?? 0.0; } /** @@ -112,11 +109,7 @@ class EntityDamageEvent extends EntityEvent implements Cancellable{ * @return float */ public function getDamage(int $type = self::MODIFIER_BASE) : float{ - if(isset($this->modifiers[$type])){ - return $this->modifiers[$type]; - } - - return 0.0; + return $this->modifiers[$type] ?? 0.0; } /** diff --git a/src/pocketmine/inventory/DoubleChestInventory.php b/src/pocketmine/inventory/DoubleChestInventory.php index 3b68ef889..e588de9dc 100644 --- a/src/pocketmine/inventory/DoubleChestInventory.php +++ b/src/pocketmine/inventory/DoubleChestInventory.php @@ -139,4 +139,9 @@ class DoubleChestInventory extends ChestInventory implements InventoryHolder{ public function getRightSide() : ChestInventory{ return $this->right; } + + public function invalidate(){ + $this->left = null; + $this->right = null; + } } diff --git a/src/pocketmine/item/BlazeRod.php b/src/pocketmine/item/BlazeRod.php new file mode 100644 index 000000000..d4fa6e0ba --- /dev/null +++ b/src/pocketmine/item/BlazeRod.php @@ -0,0 +1,36 @@ +getDirectionVector(); + $nbt = new CompoundTag("", [ new ListTag("Pos", [ new DoubleTag("", $player->x), @@ -61,9 +63,9 @@ class Bow extends Tool{ new DoubleTag("", $player->z) ]), new ListTag("Motion", [ - new DoubleTag("", -sin($player->yaw / 180 * M_PI) * cos($player->pitch / 180 * M_PI)), - new DoubleTag("", -sin($player->pitch / 180 * M_PI)), - new DoubleTag("", cos($player->yaw / 180 * M_PI) * cos($player->pitch / 180 * M_PI)) + new DoubleTag("", $directionVector->x), + new DoubleTag("", $directionVector->y), + new DoubleTag("", $directionVector->z) ]), new ListTag("Rotation", [ //yaw/pitch for arrows taken crosswise, not along the arrow shaft. diff --git a/src/pocketmine/item/Bucket.php b/src/pocketmine/item/Bucket.php index 489c6d1c2..9b4414442 100644 --- a/src/pocketmine/item/Bucket.php +++ b/src/pocketmine/item/Bucket.php @@ -51,13 +51,13 @@ class Bucket extends Item{ } public function onActivate(Level $level, Player $player, Block $block, Block $target, int $face, Vector3 $facePos) : bool{ - $targetBlock = BlockFactory::get($this->meta); + $resultBlock = BlockFactory::get($this->meta); - if($targetBlock instanceof Air){ + if($resultBlock instanceof Air){ if($target instanceof Liquid and $target->getDamage() === 0){ - $result = clone $this; - $result->setDamage($target->getId()); - $player->getServer()->getPluginManager()->callEvent($ev = new PlayerBucketFillEvent($player, $block, $face, $this, $result)); + $resultItem = clone $this; + $resultItem->setDamage($target->getId()); + $player->getServer()->getPluginManager()->callEvent($ev = new PlayerBucketFillEvent($player, $block, $face, $this, $resultItem)); if(!$ev->isCancelled()){ $player->getLevel()->setBlock($target, BlockFactory::get(Block::AIR), true, true); if($player->isSurvival()){ @@ -68,12 +68,12 @@ class Bucket extends Item{ $player->getInventory()->sendContents($player); } } - }elseif($targetBlock instanceof Liquid){ - $result = clone $this; - $result->setDamage(0); - $player->getServer()->getPluginManager()->callEvent($ev = new PlayerBucketEmptyEvent($player, $block, $face, $this, $result)); + }elseif($resultBlock instanceof Liquid){ + $resultItem = clone $this; + $resultItem->setDamage(0); + $player->getServer()->getPluginManager()->callEvent($ev = new PlayerBucketEmptyEvent($player, $block, $face, $this, $resultItem)); if(!$ev->isCancelled()){ - $player->getLevel()->setBlock($block, $targetBlock, true, true); + $player->getLevel()->setBlock($block, $resultBlock, true, true); if($player->isSurvival()){ $player->getInventory()->setItemInHand($ev->getItem()); } diff --git a/src/pocketmine/item/ItemFactory.php b/src/pocketmine/item/ItemFactory.php index aacbb3c41..cecd30e11 100644 --- a/src/pocketmine/item/ItemFactory.php +++ b/src/pocketmine/item/ItemFactory.php @@ -150,8 +150,8 @@ class ItemFactory{ self::registerItem(new CookedChicken()); //TODO: ROTTEN_FLESH //TODO: ENDER_PEARL - //TODO: BLAZE_ROD - //TODO: GHAST_TEAR + self::registerItem(new BlazeRod()); + self::registerItem(new Item(Item::GHAST_TEAR, 0, "Ghast Tear")); self::registerItem(new Item(Item::GOLD_NUGGET, 0, "Gold Nugget")); self::registerItem(new NetherWart()); self::registerItem(new Potion()); @@ -193,7 +193,7 @@ class ItemFactory{ //TODO: RABBIT self::registerItem(new CookedRabbit()); //TODO: RABBIT_STEW - //TODO: RABBIT_FOOT + self::registerItem(new Item(Item::RABBIT_FOOT, 0, "Rabbit's Foot")); //TODO: RABBIT_HIDE //TODO: HORSEARMORLEATHER //TODO: HORSEARMORIRON @@ -212,7 +212,7 @@ class ItemFactory{ //TODO: ACACIA_DOOR //TODO: DARK_OAK_DOOR //TODO: CHORUS_FRUIT - //TODO: CHORUS_FRUIT_POPPED + self::registerItem(new Item(Item::CHORUS_FRUIT_POPPED, 0, "Popped Chorus Fruit")); //TODO: DRAGON_BREATH //TODO: SPLASH_POTION @@ -221,11 +221,11 @@ class ItemFactory{ //TODO: COMMAND_BLOCK_MINECART //TODO: ELYTRA - //TODO: SHULKER_SHELL + self::registerItem(new Item(Item::SHULKER_SHELL, 0, "Shulker Shell")); //TODO: TOTEM - //TODO: IRON_NUGGET + self::registerItem(new Item(Item::IRON_NUGGET, 0, "Iron Nugget")); self::registerItem(new Beetroot()); self::registerItem(new BeetrootSeeds()); diff --git a/src/pocketmine/item/Stick.php b/src/pocketmine/item/Stick.php index a3ff64e95..f5a216326 100644 --- a/src/pocketmine/item/Stick.php +++ b/src/pocketmine/item/Stick.php @@ -30,7 +30,7 @@ class Stick extends Item{ } public function getFuelTime() : int{ - return 5; + return 100; } } \ No newline at end of file diff --git a/src/pocketmine/level/Level.php b/src/pocketmine/level/Level.php index f8607c6cc..781c568e9 100644 --- a/src/pocketmine/level/Level.php +++ b/src/pocketmine/level/Level.php @@ -1743,26 +1743,22 @@ class Level implements ChunkManager, Metadatable{ if($hand->isSolid() === true and $hand->getBoundingBox() !== null){ $entities = $this->getCollidingEntities($hand->getBoundingBox()); - $realCount = 0; foreach($entities as $e){ - if($e instanceof Arrow or $e instanceof DroppedItem){ + if($e instanceof Arrow or $e instanceof DroppedItem or ($e instanceof Player and $e->isSpectator())){ continue; } - ++$realCount; + + return false; //Entity in block } if($player !== null){ if(($diff = $player->getNextPosition()->subtract($player->getPosition())) and $diff->lengthSquared() > 0.00001){ $bb = $player->getBoundingBox()->getOffsetBoundingBox($diff->x, $diff->y, $diff->z); if($hand->getBoundingBox()->intersectsWith($bb)){ - ++$realCount; + return false; //Inside player BB } } } - - if($realCount > 0){ - return false; //Entity in block - } } diff --git a/src/pocketmine/scheduler/TaskHandler.php b/src/pocketmine/scheduler/TaskHandler.php index 8e04778b7..bb1f5212d 100644 --- a/src/pocketmine/scheduler/TaskHandler.php +++ b/src/pocketmine/scheduler/TaskHandler.php @@ -25,6 +25,7 @@ namespace pocketmine\scheduler; use pocketmine\event\Timings; use pocketmine\event\TimingsHandler; +use pocketmine\utils\MainLogger; class TaskHandler{ @@ -136,10 +137,15 @@ class TaskHandler{ * Changes to this function won't be recorded on the version. */ public function cancel(){ - if(!$this->isCancelled()){ - $this->task->onCancel(); + try{ + if(!$this->isCancelled()){ + $this->task->onCancel(); + } + }catch(\Throwable $e){ + MainLogger::getLogger()->logException($e); + }finally{ + $this->remove(); } - $this->remove(); } public function remove(){ diff --git a/src/pocketmine/tile/Chest.php b/src/pocketmine/tile/Chest.php index fc3e472f3..edce48f0a 100644 --- a/src/pocketmine/tile/Chest.php +++ b/src/pocketmine/tile/Chest.php @@ -67,8 +67,12 @@ class Chest extends Spawnable implements InventoryHolder, Container, Nameable{ $player->removeWindow($this->getRealInventory()); } + if($this->doubleInventory !== null){ + $this->doubleInventory->invalidate(); + $this->doubleInventory = null; + } + $this->inventory = null; - $this->doubleInventory = null; parent::close(); }