diff --git a/src/pocketmine/Player.php b/src/pocketmine/Player.php index 85b668ddc..f4151a8af 100644 --- a/src/pocketmine/Player.php +++ b/src/pocketmine/Player.php @@ -1246,7 +1246,7 @@ class Player extends Human implements CommandSender, InventoryHolder, IPlayer{ $this->lastUpdate = $currentTick; - if($this->spawned){ + if($this->spawned){ $this->processMovement($currentTick); $this->entityBaseTick(1); @@ -1749,7 +1749,7 @@ class Player extends Human implements CommandSender, InventoryHolder, IPlayer{ } $target = $this->level->getBlock($blockVector); - $ev = new PlayerInteractEvent($this, $item, $target, $packet->face); + $ev = new PlayerInteractEvent($this, $item, $target, $packet->face, PlayerInteractEvent::RIGHT_CLICK_AIR); $this->server->getPluginManager()->callEvent($ev); @@ -1807,6 +1807,11 @@ class Player extends Human implements CommandSender, InventoryHolder, IPlayer{ $packet->eid = $this->id; switch($packet->action){ + case 0: //Start break + $target = $this->level->getBlock(new Vector3($packet->x, $packet->y, $packet->z)); + $ev = new PlayerInteractEvent($this, $this->inventory->getItemInHand(), $target, $packet->face, $target->getId() === 0 ? PlayerInteractEvent::LEFT_CLICK_AIR : PlayerInteractEvent::LEFT_CLICK_BLOCK); + $this->lastBreak = microtime(true); + break; case 5: //Shot arrow if($this->inventory->getItemInHand()->getId() === Item::BOW){ $bow = $this->inventory->getItemInHand(); diff --git a/src/pocketmine/event/player/PlayerInteractEvent.php b/src/pocketmine/event/player/PlayerInteractEvent.php index 20a7c2f6a..c35b843bb 100644 --- a/src/pocketmine/event/player/PlayerInteractEvent.php +++ b/src/pocketmine/event/player/PlayerInteractEvent.php @@ -32,6 +32,12 @@ use pocketmine\Player; class PlayerInteractEvent extends PlayerEvent implements Cancellable{ public static $handlerList = null; + const LEFT_CLICK_BLOCK = 0; + const RIGHT_CLICK_BLOCK = 1; + const LEFT_CLICK_AIR = 2; + const RIGHT_CLICK_AIR = 3; + const PHYSICAL = 4; + /** * @var \pocketmine\block\Block; */ @@ -42,12 +48,19 @@ class PlayerInteractEvent extends PlayerEvent implements Cancellable{ /** @var \pocketmine\item\Item */ protected $item; + + protected $action; - public function __construct(Player $player, Item $item, Block $block, $face){ + public function __construct(Player $player, Item $item, Block $block, $face, $action = PlayerInteractEvent::RIGHT_CLICK){ $this->blockTouched = $block; $this->player = $player; $this->item = $item; $this->blockFace = (int) $face; + $this->action = (int) $action; + } + + public function getAction(){ + return $this->action; } public function getItem(){ @@ -61,4 +74,4 @@ class PlayerInteractEvent extends PlayerEvent implements Cancellable{ public function getFace(){ return $this->blockFace; } -} \ No newline at end of file +} diff --git a/src/pocketmine/inventory/PlayerInventory.php b/src/pocketmine/inventory/PlayerInventory.php index 83cc156ec..913ff2fd6 100644 --- a/src/pocketmine/inventory/PlayerInventory.php +++ b/src/pocketmine/inventory/PlayerInventory.php @@ -146,9 +146,7 @@ class PlayerInventory extends BaseInventory{ foreach($target as $player){ if($player === $this->getHolder()){ - //TODO: Check if Mojang enabled sending a single slot this - //$this->sendSlot($this->getHeldItemSlot()); - $this->sendContents($player); + $this->sendSlot($this->getHeldItemSlot()); }else{ $player->dataPacket($pk); } @@ -393,9 +391,6 @@ class PlayerInventory extends BaseInventory{ foreach($target as $player){ if($player === $this->getHolder()){ /** @var Player $player */ - //$pk2 = clone $pk; - //$pk2->eid = 0; - $pk2 = new ContainerSetSlotPacket(); $pk2->windowid = 0x78; //Armor window id constant $pk2->slot = $index; @@ -454,7 +449,8 @@ class PlayerInventory extends BaseInventory{ foreach($target as $player){ if($player === $this->getHolder()){ /** @var Player $player */ - $this->sendContents($player); //#blamemojang + $pk->windowid = 0; + $player->dataPacket(clone $pk); }else{ if(($id = $player->getWindowId($this)) === -1){ $this->close($player); @@ -473,4 +469,4 @@ class PlayerInventory extends BaseInventory{ return parent::getHolder(); } -} \ No newline at end of file +} diff --git a/src/pocketmine/level/Level.php b/src/pocketmine/level/Level.php index e19538be8..c0e9ea29a 100644 --- a/src/pocketmine/level/Level.php +++ b/src/pocketmine/level/Level.php @@ -95,6 +95,8 @@ use pocketmine\utils\LevelException; use pocketmine\utils\MainLogger; use pocketmine\utils\ReversePriorityQueue; use pocketmine\utils\TextFormat; +use pocketmine\level\particle\Particle; +use pocketmine\level\particle\DestroyBlockParticle; #include @@ -355,6 +357,13 @@ class Level implements ChunkManager, Metadatable{ $this->blockCache = []; $this->temporalPosition = null; } + + public function addParticle(Particle $particle){ + $pk = $particle->encode(); + if($pk !== null){ + Server::broadcastPacket($this->getUsingChunk($particle->x >> 4, $particle->z >> 4), $pk); + } + } /** * @return bool @@ -1243,7 +1252,7 @@ class Level implements ChunkManager, Metadatable{ return false; } - $player->lastBreak = microtime(true); + $player->lastBreak = PHP_INT_MAX; }elseif($item instanceof Item and !$target->isBreakable($item)){ return false; } @@ -1259,7 +1268,11 @@ class Level implements ChunkManager, Metadatable{ } } $drops = $target->getDrops($item); //Fixes tile entities being deleted before getting drops + + $this->addParticle(new DestroyBlockParticle($target, $target)); + $target->onBreak($item); + $tile = $this->getTile($target); if($tile instanceof Tile){ if($tile instanceof InventoryHolder){ @@ -1319,7 +1332,7 @@ class Level implements ChunkManager, Metadatable{ } if($player instanceof Player){ - $ev = new PlayerInteractEvent($player, $item, $target, $face); + $ev = new PlayerInteractEvent($player, $item, $target, $face, $target->getId() === 0 ? PlayerInteractEvent::RIGHT_CLICK_AIR : PlayerInteractEvent::RIGHT_CLICK_BLOCK); if(!$player->isOp() and ($distance = $this->server->getSpawnRadius()) > -1){ $t = new Vector2($target->x, $target->z); $s = new Vector2($this->getSpawnLocation()->x, $this->getSpawnLocation()->z); diff --git a/src/pocketmine/level/format/mcregion/RegionLoader.php b/src/pocketmine/level/format/mcregion/RegionLoader.php index 6a1142d28..7d5955290 100644 --- a/src/pocketmine/level/format/mcregion/RegionLoader.php +++ b/src/pocketmine/level/format/mcregion/RegionLoader.php @@ -189,8 +189,8 @@ class RegionLoader{ $sectors = (int) ceil(($length + 4) / 4096); $index = self::getChunkOffset($x, $z); if($this->locationTable[$index][1] < $sectors){ + $this->locationTable[$index][0] = $this->lastSector + 1; $this->lastSector += $sectors; //The GC will clean this shift "later" - $this->locationTable[$index][0] = $this->lastSector; } $this->locationTable[$index][1] = $sectors; $this->locationTable[$index][2] = time(); @@ -247,7 +247,8 @@ class RegionLoader{ $chunk = Binary::writeInt(strlen($chunk)) . $chunk; $sectors = (int) ceil(strlen($chunk) / 4096); if($sectors > $this->locationTable[$i][1]){ - $this->locationTable[$i][0] = $this->lastSector += $sectors; + $this->locationTable[$i][0] = $this->lastSector + 1; + $this->lastSector += $sectors; } fseek($this->filePointer, $this->locationTable[$i][0] << 12); fwrite($this->filePointer, str_pad($chunk, $sectors << 12, "\x00", STR_PAD_RIGHT)); @@ -358,4 +359,4 @@ class RegionLoader{ return $this->z; } -} \ No newline at end of file +} diff --git a/src/pocketmine/level/particle/DestroyBlockParticle.php b/src/pocketmine/level/particle/DestroyBlockParticle.php new file mode 100644 index 000000000..eae28f775 --- /dev/null +++ b/src/pocketmine/level/particle/DestroyBlockParticle.php @@ -0,0 +1,47 @@ +x, $pos->y, $pos->z); + $this->data = $b->getId() + ($b->getDamage() << 12); + } + + public function encode(){ + $pk = new LevelEventPacket; + $pk->evid = 2001; + $pk->x = $this->x; + $pk->y = $this->y; + $pk->z = $this->z; + $pk->data = $this->data; + + return $pk; + } +} diff --git a/src/pocketmine/level/particle/ExplodeParticle.php b/src/pocketmine/level/particle/ExplodeParticle.php new file mode 100644 index 000000000..7317c5e95 --- /dev/null +++ b/src/pocketmine/level/particle/ExplodeParticle.php @@ -0,0 +1,42 @@ +x, $pos->y, $pos->z); + } + + public function encode(){ + $pk = new ExplodePacket; + $pk->x = $this->x; + $pk->y = $this->y; + $pk->z = $this->z; + $pk->radius = 0; + + return $pk; + } +} diff --git a/src/pocketmine/level/particle/MobSpawnParticle.php b/src/pocketmine/level/particle/MobSpawnParticle.php new file mode 100644 index 000000000..379b8b854 --- /dev/null +++ b/src/pocketmine/level/particle/MobSpawnParticle.php @@ -0,0 +1,48 @@ +x, $pos->y, $pos->z); + $this->width = $width; + $this->height = $height; + } + + public function encode(){ + $pk = new LevelEventPacket; + $pk->evid = 2004; + $pk->x = $this->x; + $pk->y = $this->y; + $pk->z = $this->z; + $pk->data = ($this->width & 0xff) + (($this->height & 0xff) << 8); + + return $pk; + } +} diff --git a/src/pocketmine/level/particle/Particle.php b/src/pocketmine/level/particle/Particle.php new file mode 100644 index 000000000..66ce268ee --- /dev/null +++ b/src/pocketmine/level/particle/Particle.php @@ -0,0 +1,34 @@ +reset(); $this->putShort($this->evid); $this->putInt($this->x); - $this->putShort($this->y); + $this->putByte($this->y); $this->putInt($this->z); $this->putInt($this->data); } -} \ No newline at end of file +}