Merge branch 'php/7.0' into mcpe-1.2

This commit is contained in:
Dylan K. Taylor 2017-09-03 15:02:41 +01:00
commit 78d49f8e66
16 changed files with 108 additions and 82 deletions

View File

@ -2290,11 +2290,7 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{
return true; return true;
case InventoryTransactionPacket::USE_ITEM_ACTION_CLICK_AIR: case InventoryTransactionPacket::USE_ITEM_ACTION_CLICK_AIR:
$directionVector = new Vector3( $directionVector = $this->getDirectionVector();
-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)
);
if($this->isCreative()){ if($this->isCreative()){
$item = $this->inventory->getItemInHand(); $item = $this->inventory->getItemInHand();

View File

@ -50,10 +50,10 @@ class Cake extends Transparent implements FoodSource{
protected function recalculateBoundingBox(){ protected function recalculateBoundingBox(){
$f = (1 + $this->getDamage() * 2) / 16; $f = $this->getDamage() * 0.125; //1 slice width
return new AxisAlignedBB( return new AxisAlignedBB(
$this->x + $f, $this->x + 0.0625 + $f,
$this->y, $this->y,
$this->z + 0.0625, $this->z + 0.0625,
$this->x + 1 - 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{ public function onActivate(Item $item, Player $player = null) : bool{
if($player instanceof Player and $player->getHealth() < $player->getMaxHealth()){ //TODO: refactor this into generic food handling
$ev = new EntityEatBlockEvent($player, $this); if($player instanceof Player and $player->getFood() < $player->getMaxFood()){
$player->getServer()->getPluginManager()->callEvent($ev = new EntityEatBlockEvent($player, $this));
if(!$ev->isCancelled()){ 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()); $this->getLevel()->setBlock($this, $ev->getResidue());
return true; return true;
} }
@ -113,7 +120,7 @@ class Cake extends Transparent implements FoodSource{
public function getResidue(){ public function getResidue(){
$clone = clone $this; $clone = clone $this;
$clone->meta++; $clone->meta++;
if($clone->meta >= 0x06){ if($clone->meta > 0x06){
$clone = BlockFactory::get(Block::AIR); $clone = BlockFactory::get(Block::AIR);
} }
return $clone; return $clone;

View File

@ -76,9 +76,8 @@ class Sapling extends Flowable{
if($item->getId() === Item::DYE and $item->getDamage() === 0x0F){ //Bonemeal if($item->getId() === Item::DYE and $item->getDamage() === 0x0F){ //Bonemeal
//TODO: change log type //TODO: change log type
Tree::growTree($this->getLevel(), $this->x, $this->y, $this->z, new Random(mt_rand()), $this->meta & 0x07); 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; return true;
} }

View File

@ -64,9 +64,8 @@ class Sugarcane extends Flowable{
$this->meta = 0; $this->meta = 0;
$this->getLevel()->setBlock($this, $this, true); $this->getLevel()->setBlock($this, $this, true);
} }
if(($player->gamemode & 0x01) === 0){
$item->count--; $item->count--;
}
return true; return true;
} }

View File

@ -212,6 +212,7 @@ abstract class Entity extends Location implements Metadatable{
public static $entityCount = 1; public static $entityCount = 1;
/** @var Entity[] */ /** @var Entity[] */
private static $knownEntities = []; private static $knownEntities = [];
/** @var string[] */
private static $shortNames = []; private static $shortNames = [];
public static function init(){ public static function init(){
@ -901,21 +902,7 @@ abstract class Entity extends Location implements Metadatable{
$this->setLastDamageCause($source); $this->setLastDamageCause($source);
$damage = $source->getFinalDamage(); $this->setHealth($this->getHealth() - $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);
} }
/** /**
@ -962,14 +949,6 @@ abstract class Entity extends Location implements Metadatable{
} }
} }
public function getAbsorption() : float{
return 0;
}
public function setAbsorption(float $absorption){
}
/** /**
* @param EntityDamageEvent $type * @param EntityDamageEvent $type
*/ */

View File

@ -342,8 +342,10 @@ abstract class Living extends Entity implements Damageable{
$source->setCancelled(); $source->setCancelled();
} }
$source->setDamage(-min($this->getAbsorption(), $source->getFinalDamage()), EntityDamageEvent::MODIFIER_ABSORPTION);
if($this->hasEffect(Effect::DAMAGE_RESISTANCE)){ 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); 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 = new EntityEventPacket();
$pk->entityRuntimeId = $this->getId(); $pk->entityRuntimeId = $this->getId();
$pk->event = $this->getHealth() <= 0 ? EntityEventPacket::DEATH_ANIMATION : EntityEventPacket::HURT_ANIMATION; //Ouch! $pk->event = $this->getHealth() <= 0 ? EntityEventPacket::DEATH_ANIMATION : EntityEventPacket::HURT_ANIMATION; //Ouch!

View File

@ -37,6 +37,7 @@ class EntityDamageEvent extends EntityEvent implements Cancellable{
const MODIFIER_STRENGTH = 2; const MODIFIER_STRENGTH = 2;
const MODIFIER_WEAKNESS = 3; const MODIFIER_WEAKNESS = 3;
const MODIFIER_RESISTANCE = 4; const MODIFIER_RESISTANCE = 4;
const MODIFIER_ABSORPTION = 5;
const CAUSE_CONTACT = 0; const CAUSE_CONTACT = 0;
const CAUSE_ENTITY_ATTACK = 1; const CAUSE_ENTITY_ATTACK = 1;
@ -99,11 +100,7 @@ class EntityDamageEvent extends EntityEvent implements Cancellable{
* @return float * @return float
*/ */
public function getOriginalDamage(int $type = self::MODIFIER_BASE) : float{ public function getOriginalDamage(int $type = self::MODIFIER_BASE) : float{
if(isset($this->originals[$type])){ return $this->originals[$type] ?? 0.0;
return $this->originals[$type];
}
return 0.0;
} }
/** /**
@ -112,11 +109,7 @@ class EntityDamageEvent extends EntityEvent implements Cancellable{
* @return float * @return float
*/ */
public function getDamage(int $type = self::MODIFIER_BASE) : float{ public function getDamage(int $type = self::MODIFIER_BASE) : float{
if(isset($this->modifiers[$type])){ return $this->modifiers[$type] ?? 0.0;
return $this->modifiers[$type];
}
return 0.0;
} }
/** /**

View File

@ -150,4 +150,9 @@ class DoubleChestInventory extends ChestInventory implements InventoryHolder{
public function getRightSide() : ChestInventory{ public function getRightSide() : ChestInventory{
return $this->right; return $this->right;
} }
public function invalidate(){
$this->left = null;
$this->right = null;
}
} }

View File

@ -0,0 +1,36 @@
<?php
/*
*
* ____ _ _ __ __ _ __ __ ____
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* @author PocketMine Team
* @link http://www.pocketmine.net/
*
*
*/
declare(strict_types=1);
namespace pocketmine\item;
class BlazeRod extends Item{
public function __construct(int $meta = 0){
parent::__construct(self::BLAZE_ROD, $meta, "Blaze Rod");
}
public function getFuelTime() : int{
return 2400;
}
}

View File

@ -54,6 +54,8 @@ class Bow extends Tool{
return false; return false;
} }
$directionVector = $player->getDirectionVector();
$nbt = new CompoundTag("", [ $nbt = new CompoundTag("", [
new ListTag("Pos", [ new ListTag("Pos", [
new DoubleTag("", $player->x), new DoubleTag("", $player->x),
@ -61,9 +63,9 @@ class Bow extends Tool{
new DoubleTag("", $player->z) new DoubleTag("", $player->z)
]), ]),
new ListTag("Motion", [ new ListTag("Motion", [
new DoubleTag("", -sin($player->yaw / 180 * M_PI) * cos($player->pitch / 180 * M_PI)), new DoubleTag("", $directionVector->x),
new DoubleTag("", -sin($player->pitch / 180 * M_PI)), new DoubleTag("", $directionVector->y),
new DoubleTag("", cos($player->yaw / 180 * M_PI) * cos($player->pitch / 180 * M_PI)) new DoubleTag("", $directionVector->z)
]), ]),
new ListTag("Rotation", [ new ListTag("Rotation", [
//yaw/pitch for arrows taken crosswise, not along the arrow shaft. //yaw/pitch for arrows taken crosswise, not along the arrow shaft.

View File

@ -51,13 +51,13 @@ class Bucket extends Item{
} }
public function onActivate(Level $level, Player $player, Block $block, Block $target, int $face, Vector3 $facePos) : bool{ 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){ if($target instanceof Liquid and $target->getDamage() === 0){
$result = clone $this; $resultItem = clone $this;
$result->setDamage($target->getId()); $resultItem->setDamage($target->getId());
$player->getServer()->getPluginManager()->callEvent($ev = new PlayerBucketFillEvent($player, $block, $face, $this, $result)); $player->getServer()->getPluginManager()->callEvent($ev = new PlayerBucketFillEvent($player, $block, $face, $this, $resultItem));
if(!$ev->isCancelled()){ if(!$ev->isCancelled()){
$player->getLevel()->setBlock($target, BlockFactory::get(Block::AIR), true, true); $player->getLevel()->setBlock($target, BlockFactory::get(Block::AIR), true, true);
if($player->isSurvival()){ if($player->isSurvival()){
@ -68,12 +68,12 @@ class Bucket extends Item{
$player->getInventory()->sendContents($player); $player->getInventory()->sendContents($player);
} }
} }
}elseif($targetBlock instanceof Liquid){ }elseif($resultBlock instanceof Liquid){
$result = clone $this; $resultItem = clone $this;
$result->setDamage(0); $resultItem->setDamage(0);
$player->getServer()->getPluginManager()->callEvent($ev = new PlayerBucketEmptyEvent($player, $block, $face, $this, $result)); $player->getServer()->getPluginManager()->callEvent($ev = new PlayerBucketEmptyEvent($player, $block, $face, $this, $resultItem));
if(!$ev->isCancelled()){ if(!$ev->isCancelled()){
$player->getLevel()->setBlock($block, $targetBlock, true, true); $player->getLevel()->setBlock($block, $resultBlock, true, true);
if($player->isSurvival()){ if($player->isSurvival()){
$player->getInventory()->setItemInHand($ev->getItem()); $player->getInventory()->setItemInHand($ev->getItem());
} }

View File

@ -150,8 +150,8 @@ class ItemFactory{
self::registerItem(new CookedChicken()); self::registerItem(new CookedChicken());
//TODO: ROTTEN_FLESH //TODO: ROTTEN_FLESH
//TODO: ENDER_PEARL //TODO: ENDER_PEARL
//TODO: BLAZE_ROD self::registerItem(new BlazeRod());
//TODO: GHAST_TEAR self::registerItem(new Item(Item::GHAST_TEAR, 0, "Ghast Tear"));
self::registerItem(new Item(Item::GOLD_NUGGET, 0, "Gold Nugget")); self::registerItem(new Item(Item::GOLD_NUGGET, 0, "Gold Nugget"));
self::registerItem(new NetherWart()); self::registerItem(new NetherWart());
self::registerItem(new Potion()); self::registerItem(new Potion());
@ -193,7 +193,7 @@ class ItemFactory{
//TODO: RABBIT //TODO: RABBIT
self::registerItem(new CookedRabbit()); self::registerItem(new CookedRabbit());
//TODO: RABBIT_STEW //TODO: RABBIT_STEW
//TODO: RABBIT_FOOT self::registerItem(new Item(Item::RABBIT_FOOT, 0, "Rabbit's Foot"));
//TODO: RABBIT_HIDE //TODO: RABBIT_HIDE
//TODO: HORSEARMORLEATHER //TODO: HORSEARMORLEATHER
//TODO: HORSEARMORIRON //TODO: HORSEARMORIRON
@ -212,7 +212,7 @@ class ItemFactory{
//TODO: ACACIA_DOOR //TODO: ACACIA_DOOR
//TODO: DARK_OAK_DOOR //TODO: DARK_OAK_DOOR
//TODO: CHORUS_FRUIT //TODO: CHORUS_FRUIT
//TODO: CHORUS_FRUIT_POPPED self::registerItem(new Item(Item::CHORUS_FRUIT_POPPED, 0, "Popped Chorus Fruit"));
//TODO: DRAGON_BREATH //TODO: DRAGON_BREATH
//TODO: SPLASH_POTION //TODO: SPLASH_POTION
@ -221,11 +221,11 @@ class ItemFactory{
//TODO: COMMAND_BLOCK_MINECART //TODO: COMMAND_BLOCK_MINECART
//TODO: ELYTRA //TODO: ELYTRA
//TODO: SHULKER_SHELL self::registerItem(new Item(Item::SHULKER_SHELL, 0, "Shulker Shell"));
//TODO: TOTEM //TODO: TOTEM
//TODO: IRON_NUGGET self::registerItem(new Item(Item::IRON_NUGGET, 0, "Iron Nugget"));
self::registerItem(new Beetroot()); self::registerItem(new Beetroot());
self::registerItem(new BeetrootSeeds()); self::registerItem(new BeetrootSeeds());

View File

@ -30,7 +30,7 @@ class Stick extends Item{
} }
public function getFuelTime() : int{ public function getFuelTime() : int{
return 5; return 100;
} }
} }

View File

@ -1739,26 +1739,22 @@ class Level implements ChunkManager, Metadatable{
if($hand->isSolid() === true and $hand->getBoundingBox() !== null){ if($hand->isSolid() === true and $hand->getBoundingBox() !== null){
$entities = $this->getCollidingEntities($hand->getBoundingBox()); $entities = $this->getCollidingEntities($hand->getBoundingBox());
$realCount = 0;
foreach($entities as $e){ 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; continue;
} }
++$realCount;
return false; //Entity in block
} }
if($player !== null){ if($player !== null){
if(($diff = $player->getNextPosition()->subtract($player->getPosition())) and $diff->lengthSquared() > 0.00001){ if(($diff = $player->getNextPosition()->subtract($player->getPosition())) and $diff->lengthSquared() > 0.00001){
$bb = $player->getBoundingBox()->getOffsetBoundingBox($diff->x, $diff->y, $diff->z); $bb = $player->getBoundingBox()->getOffsetBoundingBox($diff->x, $diff->y, $diff->z);
if($hand->getBoundingBox()->intersectsWith($bb)){ if($hand->getBoundingBox()->intersectsWith($bb)){
++$realCount; return false; //Inside player BB
} }
} }
} }
if($realCount > 0){
return false; //Entity in block
}
} }

View File

@ -25,6 +25,7 @@ namespace pocketmine\scheduler;
use pocketmine\event\Timings; use pocketmine\event\Timings;
use pocketmine\event\TimingsHandler; use pocketmine\event\TimingsHandler;
use pocketmine\utils\MainLogger;
class TaskHandler{ class TaskHandler{
@ -136,10 +137,15 @@ class TaskHandler{
* Changes to this function won't be recorded on the version. * Changes to this function won't be recorded on the version.
*/ */
public function cancel(){ public function cancel(){
if(!$this->isCancelled()){ try{
$this->task->onCancel(); if(!$this->isCancelled()){
$this->task->onCancel();
}
}catch(\Throwable $e){
MainLogger::getLogger()->logException($e);
}finally{
$this->remove();
} }
$this->remove();
} }
public function remove(){ public function remove(){

View File

@ -67,8 +67,12 @@ class Chest extends Spawnable implements InventoryHolder, Container, Nameable{
$player->removeWindow($this->getRealInventory()); $player->removeWindow($this->getRealInventory());
} }
if($this->doubleInventory !== null){
$this->doubleInventory->invalidate();
$this->doubleInventory = null;
}
$this->inventory = null; $this->inventory = null;
$this->doubleInventory = null;
parent::close(); parent::close();
} }