Merge branch 'master' into 0.10

This commit is contained in:
Shoghi Cervantes 2014-10-30 23:20:59 +01:00
commit 4fba6d7c86
253 changed files with 2410 additions and 1218 deletions

View File

@ -24,9 +24,9 @@ namespace pocketmine;
use pocketmine\block\Block; use pocketmine\block\Block;
use pocketmine\command\CommandSender; use pocketmine\command\CommandSender;
use pocketmine\entity\Arrow; use pocketmine\entity\Arrow;
use pocketmine\entity\DroppedItem;
use pocketmine\entity\Entity; use pocketmine\entity\Entity;
use pocketmine\entity\Human; use pocketmine\entity\Human;
use pocketmine\entity\Item as DroppedItem;
use pocketmine\entity\Living; use pocketmine\entity\Living;
use pocketmine\entity\Projectile; use pocketmine\entity\Projectile;
use pocketmine\event\block\SignChangeEvent; use pocketmine\event\block\SignChangeEvent;
@ -36,6 +36,7 @@ use pocketmine\event\entity\EntityRegainHealthEvent;
use pocketmine\event\entity\EntityShootBowEvent; use pocketmine\event\entity\EntityShootBowEvent;
use pocketmine\event\entity\ProjectileLaunchEvent; use pocketmine\event\entity\ProjectileLaunchEvent;
use pocketmine\event\inventory\InventoryCloseEvent; use pocketmine\event\inventory\InventoryCloseEvent;
use pocketmine\event\inventory\InventoryPickupArrowEvent;
use pocketmine\event\inventory\InventoryPickupItemEvent; use pocketmine\event\inventory\InventoryPickupItemEvent;
use pocketmine\event\player\PlayerAchievementAwardedEvent; use pocketmine\event\player\PlayerAchievementAwardedEvent;
use pocketmine\event\player\PlayerAnimationEvent; use pocketmine\event\player\PlayerAnimationEvent;
@ -72,6 +73,7 @@ use pocketmine\level\format\LevelProvider;
use pocketmine\level\Level; use pocketmine\level\Level;
use pocketmine\level\Location; use pocketmine\level\Location;
use pocketmine\level\Position; use pocketmine\level\Position;
use pocketmine\math\AxisAlignedBB;
use pocketmine\math\Vector3; use pocketmine\math\Vector3;
use pocketmine\metadata\MetadataValue; use pocketmine\metadata\MetadataValue;
use pocketmine\nbt\NBT; use pocketmine\nbt\NBT;
@ -425,6 +427,7 @@ class Player extends Human implements CommandSender, InventoryHolder, IPlayer{
$this->setLevel($this->server->getDefaultLevel(), true); $this->setLevel($this->server->getDefaultLevel(), true);
$this->viewDistance = $this->server->getViewDistance(); $this->viewDistance = $this->server->getViewDistance();
$this->newPosition = new Vector3(0, 0, 0); $this->newPosition = new Vector3(0, 0, 0);
$this->boundingBox = new AxisAlignedBB(0, 0, 0, 0, 0, 0);
} }
/** /**
@ -581,7 +584,7 @@ class Player extends Human implements CommandSender, InventoryHolder, IPlayer{
return; return;
} }
$pk = new FullChunkDataPacket; $pk = FullChunkDataPacket::getFromPool();
$pk->chunkX = $x; $pk->chunkX = $x;
$pk->chunkZ = $z; $pk->chunkZ = $z;
$pk->data = $payload; $pk->data = $payload;
@ -645,15 +648,14 @@ class Player extends Human implements CommandSender, InventoryHolder, IPlayer{
$this->blocked = false; $this->blocked = false;
$pk = new SetTimePacket; $pk = SetTimePacket::getFromPool();
$pk->time = $this->level->getTime(); $pk->time = $this->level->getTime();
$pk->started = $this->level->stopTime == false; $pk->started = $this->level->stopTime == false;
$this->dataPacket($pk); $this->dataPacket($pk);
$pos = new Position($this->x, $this->y, $this->z, $this->level); $pos = $this->level->getSafeSpawn($this);
$pos = $this->level->getSafeSpawn($pos);
$this->server->getPluginManager()->callEvent($ev = new PlayerRespawnEvent($this, $pos)); $this->server->getPluginManager()->callEvent($ev = PlayerRespawnEvent::createEvent($this, $pos));
$this->teleport($ev->getRespawnPosition()); $this->teleport($ev->getRespawnPosition());
@ -661,7 +663,7 @@ class Player extends Human implements CommandSender, InventoryHolder, IPlayer{
$this->inventory->sendContents($this); $this->inventory->sendContents($this);
$this->inventory->sendArmorContents($this); $this->inventory->sendArmorContents($this);
$this->server->getPluginManager()->callEvent($ev = new PlayerJoinEvent($this, TextFormat::YELLOW . $this->getName() . " joined the game")); $this->server->getPluginManager()->callEvent($ev = PlayerJoinEvent::createEvent($this, TextFormat::YELLOW . $this->getName() . " joined the game"));
if(strlen(trim($ev->getJoinMessage())) > 0){ if(strlen(trim($ev->getJoinMessage())) > 0){
$this->server->broadcastMessage($ev->getJoinMessage()); $this->server->broadcastMessage($ev->getJoinMessage());
} }
@ -746,7 +748,7 @@ class Player extends Human implements CommandSender, InventoryHolder, IPlayer{
if($this->connected === false){ if($this->connected === false){
return false; return false;
} }
$this->server->getPluginManager()->callEvent($ev = new DataPacketSendEvent($this, $packet)); $this->server->getPluginManager()->callEvent($ev = $packet->getSendEvent($this));
if($ev->isCancelled()){ if($ev->isCancelled()){
return false; return false;
} }
@ -772,7 +774,7 @@ class Player extends Human implements CommandSender, InventoryHolder, IPlayer{
if($this->connected === false){ if($this->connected === false){
return false; return false;
} }
$this->server->getPluginManager()->callEvent($ev = new DataPacketSendEvent($this, $packet)); $this->server->getPluginManager()->callEvent($ev = DataPacketSendEvent::createEvent($this, $packet));
if($ev->isCancelled()){ if($ev->isCancelled()){
return false; return false;
} }
@ -804,13 +806,13 @@ class Player extends Human implements CommandSender, InventoryHolder, IPlayer{
} }
} }
$this->server->getPluginManager()->callEvent($ev = new PlayerBedEnterEvent($this, $this->level->getBlock($pos))); $this->server->getPluginManager()->callEvent($ev = PlayerBedEnterEvent::createEvent($this, $this->level->getBlock($pos)));
if($ev->isCancelled()){ if($ev->isCancelled()){
return false; return false;
} }
$this->sleeping = $pos; $this->sleeping = clone $pos;
$this->teleport(new Position($pos->x + 0.5, $pos->y + 1, $pos->z + 0.5, $this->level)); $this->teleport(Position::createPosition($pos->x + 0.5, $pos->y + 1, $pos->z + 0.5, $this->level));
$this->sendMetadata($this->getViewers()); $this->sendMetadata($this->getViewers());
$this->sendMetadata($this); $this->sendMetadata($this);
@ -834,7 +836,7 @@ class Player extends Human implements CommandSender, InventoryHolder, IPlayer{
$level = $pos->getLevel(); $level = $pos->getLevel();
} }
$this->spawnPosition = new Position($pos->x, $pos->y, $pos->z, $level); $this->spawnPosition = new Position($pos->x, $pos->y, $pos->z, $level);
$pk = new SetSpawnPositionPacket; $pk = SetSpawnPositionPacket::getFromPool();
$pk->x = (int) $this->spawnPosition->x; $pk->x = (int) $this->spawnPosition->x;
$pk->y = (int) $this->spawnPosition->y; $pk->y = (int) $this->spawnPosition->y;
$pk->z = (int) $this->spawnPosition->z; $pk->z = (int) $this->spawnPosition->z;
@ -843,7 +845,7 @@ class Player extends Human implements CommandSender, InventoryHolder, IPlayer{
public function stopSleep(){ public function stopSleep(){
if($this->sleeping instanceof Vector3){ if($this->sleeping instanceof Vector3){
$this->server->getPluginManager()->callEvent($ev = new PlayerBedLeaveEvent($this, $this->level->getBlock($this->sleeping))); $this->server->getPluginManager()->callEvent($ev = PlayerBedLeaveEvent::createEvent($this, $this->level->getBlock($this->sleeping)));
$this->sleeping = null; $this->sleeping = null;
@ -893,7 +895,7 @@ class Player extends Human implements CommandSender, InventoryHolder, IPlayer{
return false; return false;
} }
} }
$this->server->getPluginManager()->callEvent($ev = new PlayerAchievementAwardedEvent($this, $achievementId)); $this->server->getPluginManager()->callEvent($ev = PlayerAchievementAwardedEvent::createEvent($this, $achievementId));
if(!$ev->isCancelled()){ if(!$ev->isCancelled()){
$this->achievements[$achievementId] = true; $this->achievements[$achievementId] = true;
Achievement::broadcast($this, $achievementId); Achievement::broadcast($this, $achievementId);
@ -927,7 +929,7 @@ class Player extends Human implements CommandSender, InventoryHolder, IPlayer{
return false; return false;
} }
$this->server->getPluginManager()->callEvent($ev = new PlayerGameModeChangeEvent($this, (int) $gm)); $this->server->getPluginManager()->callEvent($ev = PlayerGameModeChangeEvent::createEvent($this, (int) $gm));
if($ev->isCancelled()){ if($ev->isCancelled()){
return false; return false;
} }
@ -947,7 +949,7 @@ class Player extends Human implements CommandSender, InventoryHolder, IPlayer{
$spawnPosition = $this->getSpawn(); $spawnPosition = $this->getSpawn();
$pk = new StartGamePacket; $pk = StartGamePacket::getFromPool();
$pk->seed = $this->level->getSeed(); $pk->seed = $this->level->getSeed();
$pk->x = $this->x; $pk->x = $this->x;
$pk->y = $this->y + $this->getEyeHeight(); $pk->y = $this->y + $this->getEyeHeight();
@ -1017,7 +1019,7 @@ class Player extends Human implements CommandSender, InventoryHolder, IPlayer{
$flags |= 0x20; //Show Nametags $flags |= 0x20; //Show Nametags
} }
$pk = new AdventureSettingsPacket; $pk = AdventureSettingsPacket::getFromPool();
$pk->flags = $flags; $pk->flags = $flags;
$this->dataPacket($pk); $this->dataPacket($pk);
} }
@ -1057,8 +1059,7 @@ class Player extends Human implements CommandSender, InventoryHolder, IPlayer{
return; return;
} }
$oldPos = new Vector3($this->x, $this->y, $this->z); $distanceSquared = $this->newPosition->distanceSquared($this);
$distanceSquared = $oldPos->distanceSquared($this->newPosition);
$revert = false; $revert = false;
@ -1069,6 +1070,9 @@ class Player extends Human implements CommandSender, InventoryHolder, IPlayer{
$chunk = $this->level->getChunk($this->newPosition->x >> 4, $this->newPosition->z >> 4); $chunk = $this->level->getChunk($this->newPosition->x >> 4, $this->newPosition->z >> 4);
if(!($chunk instanceof FullChunk) or !$chunk->isGenerated()){ if(!($chunk instanceof FullChunk) or !$chunk->isGenerated()){
$revert = true; $revert = true;
$this->nextChunkOrderRun = 0;
}else{
$this->chunk = $chunk;
} }
} }
} }
@ -1118,7 +1122,7 @@ class Player extends Human implements CommandSender, InventoryHolder, IPlayer{
$this->lastYaw = $to->yaw; $this->lastYaw = $to->yaw;
$this->lastPitch = $to->pitch; $this->lastPitch = $to->pitch;
$ev = new PlayerMoveEvent($this, $from, $to); $ev = PlayerMoveEvent::createEvent($this, $from, $to);
$this->server->getPluginManager()->callEvent($ev); $this->server->getPluginManager()->callEvent($ev);
@ -1126,7 +1130,7 @@ class Player extends Human implements CommandSender, InventoryHolder, IPlayer{
if($to->distance($ev->getTo()) > 0.1){ //If plugins modify the destination if($to->distance($ev->getTo()) > 0.1){ //If plugins modify the destination
$this->teleport($ev->getTo()); $this->teleport($ev->getTo());
}else{ }else{
$pk = new MovePlayerPacket; $pk = MovePlayerPacket::getFromPool();
$pk->eid = $this->id; $pk->eid = $this->id;
$pk->x = $this->x; $pk->x = $this->x;
$pk->y = $this->y; $pk->y = $this->y;
@ -1141,10 +1145,10 @@ class Player extends Human implements CommandSender, InventoryHolder, IPlayer{
} }
if($revert){ if($revert){
$pk = new MovePlayerPacket; $pk = MovePlayerPacket::getFromPool();
$pk->eid = 0; $pk->eid = 0;
$pk->x = $from->x; $pk->x = $from->x;
$pk->y = $from->y + $this->getEyeHeight(); $pk->y = $from->y + $this->getEyeHeight() + 0.01;
$pk->z = $from->z; $pk->z = $from->z;
$pk->bodyYaw = $from->yaw; $pk->bodyYaw = $from->yaw;
$pk->pitch = $from->pitch; $pk->pitch = $from->pitch;
@ -1202,16 +1206,16 @@ class Player extends Human implements CommandSender, InventoryHolder, IPlayer{
continue; continue;
} }
$this->server->getPluginManager()->callEvent($ev = new InventoryPickupItemEvent($this->inventory, $item)); $this->server->getPluginManager()->callEvent($ev = InventoryPickupArrowEvent::createEvent($this->inventory, $entity));
if($ev->isCancelled()){ if($ev->isCancelled()){
continue; continue;
} }
$pk = new TakeItemEntityPacket; $pk = TakeItemEntityPacket::getFromPool();
$pk->eid = 0; $pk->eid = 0;
$pk->target = $entity->getID(); $pk->target = $entity->getID();
$this->dataPacket($pk); $this->dataPacket($pk);
$pk = new TakeItemEntityPacket; $pk = TakeItemEntityPacket::getFromPool();
$pk->eid = $this->getID(); $pk->eid = $this->getID();
$pk->target = $entity->getID(); $pk->target = $entity->getID();
Server::broadcastPacket($entity->getViewers(), $pk); Server::broadcastPacket($entity->getViewers(), $pk);
@ -1227,7 +1231,7 @@ class Player extends Human implements CommandSender, InventoryHolder, IPlayer{
continue; continue;
} }
$this->server->getPluginManager()->callEvent($ev = new InventoryPickupItemEvent($this->inventory, $item)); $this->server->getPluginManager()->callEvent($ev = InventoryPickupItemEvent::createEvent($this->inventory, $entity));
if($ev->isCancelled()){ if($ev->isCancelled()){
continue; continue;
} }
@ -1241,11 +1245,11 @@ class Player extends Human implements CommandSender, InventoryHolder, IPlayer{
break; break;
} }
$pk = new TakeItemEntityPacket; $pk = TakeItemEntityPacket::getFromPool();
$pk->eid = 0; $pk->eid = 0;
$pk->target = $entity->getID(); $pk->target = $entity->getID();
$this->dataPacket($pk); $this->dataPacket($pk);
$pk = new TakeItemEntityPacket; $pk = TakeItemEntityPacket::getFromPool();
$pk->eid = $this->getID(); $pk->eid = $this->getID();
$pk->target = $entity->getID(); $pk->target = $entity->getID();
Server::broadcastPacket($entity->getViewers(), $pk); Server::broadcastPacket($entity->getViewers(), $pk);
@ -1284,7 +1288,7 @@ class Player extends Human implements CommandSender, InventoryHolder, IPlayer{
return; return;
} }
$this->server->getPluginManager()->callEvent($ev = new DataPacketReceiveEvent($this, $packet)); $this->server->getPluginManager()->callEvent($ev = $packet->getReceiveEvent($this));
if($ev->isCancelled()){ if($ev->isCancelled()){
return; return;
} }
@ -1308,11 +1312,11 @@ class Player extends Human implements CommandSender, InventoryHolder, IPlayer{
} }
if($packet->protocol1 !== ProtocolInfo::CURRENT_PROTOCOL){ if($packet->protocol1 !== ProtocolInfo::CURRENT_PROTOCOL){
if($packet->protocol1 < ProtocolInfo::CURRENT_PROTOCOL){ if($packet->protocol1 < ProtocolInfo::CURRENT_PROTOCOL){
$pk = new LoginStatusPacket; $pk = LoginStatusPacket::getFromPool();
$pk->status = 1; $pk->status = 1;
$this->dataPacket($pk); $this->dataPacket($pk);
}else{ }else{
$pk = new LoginStatusPacket; $pk = LoginStatusPacket::getFromPool();
$pk->status = 2; $pk->status = 2;
$this->dataPacket($pk); $this->dataPacket($pk);
} }
@ -1326,7 +1330,7 @@ class Player extends Human implements CommandSender, InventoryHolder, IPlayer{
return; return;
} }
$this->server->getPluginManager()->callEvent($ev = new PlayerPreLoginEvent($this, "Plugin reason")); $this->server->getPluginManager()->callEvent($ev = PlayerPreLoginEvent::createEvent($this, "Plugin reason"));
if($ev->isCancelled()){ if($ev->isCancelled()){
$this->close("", $ev->getKickMessage()); $this->close("", $ev->getKickMessage());
@ -1401,7 +1405,7 @@ class Player extends Human implements CommandSender, InventoryHolder, IPlayer{
parent::__construct($this->level->getChunk($nbt["Pos"][0] >> 4, $nbt["Pos"][2] >> 4, true), $nbt); parent::__construct($this->level->getChunk($nbt["Pos"][0] >> 4, $nbt["Pos"][2] >> 4, true), $nbt);
$this->loggedIn = true; $this->loggedIn = true;
$this->server->getPluginManager()->callEvent($ev = new PlayerLoginEvent($this, "Plugin reason")); $this->server->getPluginManager()->callEvent($ev = PlayerLoginEvent::createEvent($this, "Plugin reason"));
if($ev->isCancelled()){ if($ev->isCancelled()){
$this->close(TextFormat::YELLOW . $this->username . " has left the game", $ev->getKickMessage()); $this->close(TextFormat::YELLOW . $this->username . " has left the game", $ev->getKickMessage());
@ -1414,7 +1418,7 @@ class Player extends Human implements CommandSender, InventoryHolder, IPlayer{
$this->inventory->setHeldItemSlot(0); $this->inventory->setHeldItemSlot(0);
} }
$pk = new LoginStatusPacket; $pk = LoginStatusPacket::getFromPool();
$pk->status = 0; $pk->status = 0;
$this->dataPacket($pk); $this->dataPacket($pk);
@ -1426,7 +1430,7 @@ class Player extends Human implements CommandSender, InventoryHolder, IPlayer{
$this->dead = false; $this->dead = false;
$pk = new StartGamePacket; $pk = StartGamePacket::getFromPool();
$pk->seed = $this->level->getSeed(); $pk->seed = $this->level->getSeed();
$pk->x = $this->x; $pk->x = $this->x;
$pk->y = $this->y; $pk->y = $this->y;
@ -1439,17 +1443,18 @@ class Player extends Human implements CommandSender, InventoryHolder, IPlayer{
$pk->eid = 0; //Always use EntityID as zero for the actual player $pk->eid = 0; //Always use EntityID as zero for the actual player
$this->dataPacket($pk); $this->dataPacket($pk);
$pk = new SetTimePacket(); $pk = SetTimePacket::getFromPool();
$pk->time = $this->level->getTime(); $pk->time = $this->level->getTime();
$pk->started = $this->level->stopTime == false;
$this->dataPacket($pk); $this->dataPacket($pk);
$pk = new SetSpawnPositionPacket; $pk = SetSpawnPositionPacket::getFromPool();
$pk->x = (int) $spawnPosition->x; $pk->x = (int) $spawnPosition->x;
$pk->y = (int) $spawnPosition->y; $pk->y = (int) $spawnPosition->y;
$pk->z = (int) $spawnPosition->z; $pk->z = (int) $spawnPosition->z;
$this->dataPacket($pk); $this->dataPacket($pk);
$pk = new SetHealthPacket(); $pk = SetHealthPacket::getFromPool();
$pk->health = $this->getHealth(); $pk->health = $this->getHealth();
$this->dataPacket($pk); $this->dataPacket($pk);
if($this->getHealth() <= 0){ if($this->getHealth() <= 0){
@ -1472,17 +1477,21 @@ class Player extends Human implements CommandSender, InventoryHolder, IPlayer{
$newPos = new Vector3($packet->x, $packet->y, $packet->z); $newPos = new Vector3($packet->x, $packet->y, $packet->z);
$revert = ($this->dead === true or $this->spawned !== true); $revert = false;
if($this->dead === true or $this->spawned !== true){
$revert = true;
$this->forceMovement = new Vector3($this->x, $this->y, $this->z);
}
if($revert or ($this->forceMovement instanceof Vector3 and $newPos->distance($this->forceMovement) > 0.2)){ if($this->forceMovement instanceof Vector3 and ($revert or $newPos->distance($this->forceMovement) > 0.2)){
$pk = new MovePlayerPacket(); $pk = MovePlayerPacket::getFromPool();
$pk->eid = 0; $pk->eid = 0;
$pk->x = $this->x; $pk->x = $this->forceMovement->x;
$pk->y = $this->y + $this->getEyeHeight(); $pk->y = $this->forceMovement->y + $this->getEyeHeight() + 0.01;
$pk->z = $this->z; $pk->z = $this->forceMovement->z;
$pk->bodyYaw = $this->yaw; $pk->bodyYaw = $packet->bodyYaw;
$pk->pitch = $this->pitch; $pk->pitch = $packet->pitch;
$pk->yaw = $this->yaw; $pk->yaw = $packet->yaw;
$pk->teleport = true; $pk->teleport = true;
$this->directDataPacket($pk); $this->directDataPacket($pk);
}else{ }else{
@ -1558,7 +1567,11 @@ class Player extends Human implements CommandSender, InventoryHolder, IPlayer{
} }
break; break;
case ProtocolInfo::USE_ITEM_PACKET: case ProtocolInfo::USE_ITEM_PACKET:
$blockVector = new Vector3($packet->x, $packet->y, $packet->z); if($this->spawned === false or $this->dead === true){
break;
}
$blockVector = Vector3::createVector($packet->x, $packet->y, $packet->z);
$this->craftingType = 0; $this->craftingType = 0;
@ -1566,7 +1579,7 @@ class Player extends Human implements CommandSender, InventoryHolder, IPlayer{
$target = $this->level->getBlock($blockVector); $target = $this->level->getBlock($blockVector);
$block = $target->getSide($packet->face); $block = $target->getSide($packet->face);
$pk = new UpdateBlockPacket; $pk = UpdateBlockPacket::getFromPool();
$pk->x = $target->x; $pk->x = $target->x;
$pk->y = $target->y; $pk->y = $target->y;
$pk->z = $target->z; $pk->z = $target->z;
@ -1574,7 +1587,7 @@ class Player extends Human implements CommandSender, InventoryHolder, IPlayer{
$pk->meta = $target->getDamage(); $pk->meta = $target->getDamage();
$this->dataPacket($pk); $this->dataPacket($pk);
$pk = new UpdateBlockPacket; $pk = UpdateBlockPacket::getFromPool();
$pk->x = $block->x; $pk->x = $block->x;
$pk->y = $block->y; $pk->y = $block->y;
$pk->z = $block->z; $pk->z = $block->z;
@ -1613,7 +1626,7 @@ class Player extends Human implements CommandSender, InventoryHolder, IPlayer{
$target = $this->level->getBlock($blockVector); $target = $this->level->getBlock($blockVector);
$block = $target->getSide($packet->face); $block = $target->getSide($packet->face);
$pk = new UpdateBlockPacket; $pk = UpdateBlockPacket::getFromPool();
$pk->x = $target->x; $pk->x = $target->x;
$pk->y = $target->y; $pk->y = $target->y;
$pk->z = $target->z; $pk->z = $target->z;
@ -1621,7 +1634,7 @@ class Player extends Human implements CommandSender, InventoryHolder, IPlayer{
$pk->meta = $target->getDamage(); $pk->meta = $target->getDamage();
$this->dataPacket($pk); $this->dataPacket($pk);
$pk = new UpdateBlockPacket; $pk = UpdateBlockPacket::getFromPool();
$pk->x = $block->x; $pk->x = $block->x;
$pk->y = $block->y; $pk->y = $block->y;
$pk->z = $block->z; $pk->z = $block->z;
@ -1630,7 +1643,42 @@ class Player extends Human implements CommandSender, InventoryHolder, IPlayer{
$this->dataPacket($pk); $this->dataPacket($pk);
break; break;
}elseif($packet->face === 0xff){ }elseif($packet->face === 0xff){
//TODO: add event $item = $this->inventory->getItemInHand();
if($item->getID() === Item::SNOWBALL){
$nbt = new Compound("", [
"Pos" => new Enum("Pos", [
new Double("", $this->x),
new Double("", $this->y + $this->getEyeHeight()),
new Double("", $this->z)
]),
"Motion" => new Enum("Motion", [
new Double("", -sin($this->yaw / 180 * M_PI) * cos($this->pitch / 180 * M_PI)),
new Double("", -sin($this->pitch / 180 * M_PI)),
new Double("", cos($this->yaw / 180 * M_PI) * cos($this->pitch / 180 * M_PI))
]),
"Rotation" => new Enum("Rotation", [
new Float("", $this->yaw),
new Float("", $this->pitch)
]),
]);
$f = 1.5;
$snowball = Entity::createEntity("Snowball", $this->chunk, $nbt, $this);
$snowball->setMotion($snowball->getMotion()->multiply($f));
if($this->isSurvival()){
$this->inventory->removeItem(Item::get(Item::SNOWBALL, 0, 1));
}
if($snowball instanceof Projectile){
$this->server->getPluginManager()->callEvent($projectileEv = ProjectileLaunchEvent::createEvent($snowball));
if($projectileEv->isCancelled()){
$snowball->kill();
}else{
$snowball->spawnToAll();
}
}else{
$snowball->spawnToAll();
}
}
$this->inAction = true; $this->inAction = true;
$this->startAction = microtime(true); $this->startAction = microtime(true);
$this->sendMetadata($this->getViewers()); $this->sendMetadata($this->getViewers());
@ -1674,7 +1722,7 @@ class Player extends Human implements CommandSender, InventoryHolder, IPlayer{
]); ]);
$f = 1.5; $f = 1.5;
$ev = new EntityShootBowEvent($this, $bow, new Arrow($this->chunk, $nbt, $this), $f); $ev = EntityShootBowEvent::createEvent($this, $bow, Entity::createEntity("Arrow", $this->chunk, $nbt, $this), $f);
$this->server->getPluginManager()->callEvent($ev); $this->server->getPluginManager()->callEvent($ev);
@ -1691,7 +1739,7 @@ class Player extends Human implements CommandSender, InventoryHolder, IPlayer{
} }
} }
if($ev->getProjectile() instanceof Projectile){ if($ev->getProjectile() instanceof Projectile){
$this->server->getPluginManager()->callEvent($projectileEv = new ProjectileLaunchEvent($ev->getProjectile())); $this->server->getPluginManager()->callEvent($projectileEv = ProjectileLaunchEvent::createEvent($ev->getProjectile()));
if($projectileEv->isCancelled()){ if($projectileEv->isCancelled()){
$ev->getProjectile()->kill(); $ev->getProjectile()->kill();
}else{ }else{
@ -1718,7 +1766,7 @@ class Player extends Human implements CommandSender, InventoryHolder, IPlayer{
} }
$this->craftingType = 0; $this->craftingType = 0;
$vector = new Vector3($packet->x, $packet->y, $packet->z); $vector = Vector3::createVector($packet->x, $packet->y, $packet->z);
if($this->isCreative()){ if($this->isCreative()){
@ -1739,7 +1787,7 @@ class Player extends Human implements CommandSender, InventoryHolder, IPlayer{
$target = $this->level->getBlock($vector); $target = $this->level->getBlock($vector);
$tile = $this->level->getTile($vector); $tile = $this->level->getTile($vector);
$pk = new UpdateBlockPacket; $pk = UpdateBlockPacket::getFromPool();
$pk->x = $target->x; $pk->x = $target->x;
$pk->y = $target->y; $pk->y = $target->y;
$pk->z = $target->z; $pk->z = $target->z;
@ -1853,11 +1901,13 @@ class Player extends Human implements CommandSender, InventoryHolder, IPlayer{
$damage[EntityDamageEvent::MODIFIER_ARMOR] = -intval($damage[EntityDamageEvent::MODIFIER_BASE] * $points * 0.04); $damage[EntityDamageEvent::MODIFIER_ARMOR] = -intval($damage[EntityDamageEvent::MODIFIER_BASE] * $points * 0.04);
} }
$ev = new EntityDamageByEntityEvent($this, $target, EntityDamageEvent::CAUSE_ENTITY_ATTACK, $damage); $ev = EntityDamageByEntityEvent::createEvent($this, $target, EntityDamageEvent::CAUSE_ENTITY_ATTACK, $damage);
if($cancelled){ if($cancelled){
$ev->setCancelled(); $ev->setCancelled();
} }
$this->server->getPluginManager()->callEvent($ev);
$target->attack($ev->getFinalDamage(), $ev);
if($ev->isCancelled()){ if($ev->isCancelled()){
if($item->isTool() and $this->isSurvival()){ if($item->isTool() and $this->isSurvival()){
$this->inventory->sendContents($this); $this->inventory->sendContents($this);
@ -1865,8 +1915,6 @@ class Player extends Human implements CommandSender, InventoryHolder, IPlayer{
break; break;
} }
$target->attack($ev->getFinalDamage(), $ev);
if($item->isTool() and $this->isSurvival()){ if($item->isTool() and $this->isSurvival()){
if($item->useOn($target) and $item->getDamage() >= $item->getMaxDurability()){ if($item->useOn($target) and $item->getDamage() >= $item->getMaxDurability()){
$this->inventory->setItemInHand(Item::get(Item::AIR, 0, 1), $this); $this->inventory->setItemInHand(Item::get(Item::AIR, 0, 1), $this);
@ -1883,12 +1931,12 @@ class Player extends Human implements CommandSender, InventoryHolder, IPlayer{
break; break;
} }
$this->server->getPluginManager()->callEvent($ev = new PlayerAnimationEvent($this, $packet->action)); $this->server->getPluginManager()->callEvent($ev = PlayerAnimationEvent::createEvent($this, $packet->action));
if($ev->isCancelled()){ if($ev->isCancelled()){
break; break;
} }
$pk = new AnimatePacket(); $pk = AnimatePacket::getFromPool();
$pk->eid = $this->getID(); $pk->eid = $this->getID();
$pk->action = $ev->getAnimationType(); $pk->action = $ev->getAnimationType();
Server::broadcastPacket($this->getViewers(), $pk); Server::broadcastPacket($this->getViewers(), $pk);
@ -1900,7 +1948,7 @@ class Player extends Human implements CommandSender, InventoryHolder, IPlayer{
$this->craftingType = 0; $this->craftingType = 0;
$this->server->getPluginManager()->callEvent($ev = new PlayerRespawnEvent($this, $this->getSpawn())); $this->server->getPluginManager()->callEvent($ev = PlayerRespawnEvent::createEvent($this, $this->getSpawn()));
$this->teleport($ev->getRespawnPosition()); $this->teleport($ev->getRespawnPosition());
$this->fireTicks = 0; $this->fireTicks = 0;
@ -1956,13 +2004,13 @@ class Player extends Human implements CommandSender, InventoryHolder, IPlayer{
]; ];
$slot = $this->inventory->getItemInHand(); $slot = $this->inventory->getItemInHand();
if($this->getHealth() < 20 and isset($items[$slot->getID()])){ if($this->getHealth() < 20 and isset($items[$slot->getID()])){
$this->server->getPluginManager()->callEvent($ev = new PlayerItemConsumeEvent($this, $slot)); $this->server->getPluginManager()->callEvent($ev = PlayerItemConsumeEvent::createEvent($this, $slot));
if($ev->isCancelled()){ if($ev->isCancelled()){
$this->inventory->sendContents($this); $this->inventory->sendContents($this);
break; break;
} }
$pk = new EntityEventPacket(); $pk = EntityEventPacket::getFromPool();
$pk->eid = 0; $pk->eid = 0;
$pk->event = 9; $pk->event = 9;
$this->dataPacket($pk); $this->dataPacket($pk);
@ -1970,7 +2018,7 @@ class Player extends Human implements CommandSender, InventoryHolder, IPlayer{
Server::broadcastPacket($this->getViewers(), $pk); Server::broadcastPacket($this->getViewers(), $pk);
$amount = $items[$slot->getID()]; $amount = $items[$slot->getID()];
$this->server->getPluginManager()->callEvent($ev = new EntityRegainHealthEvent($this, $amount, EntityRegainHealthEvent::CAUSE_EATING)); $this->server->getPluginManager()->callEvent($ev = EntityRegainHealthEvent::createEvent($this, $amount, EntityRegainHealthEvent::CAUSE_EATING));
if(!$ev->isCancelled()){ if(!$ev->isCancelled()){
$this->heal($ev->getAmount(), $ev); $this->heal($ev->getAmount(), $ev);
} }
@ -1990,7 +2038,7 @@ class Player extends Human implements CommandSender, InventoryHolder, IPlayer{
} }
$packet->eid = $this->id; $packet->eid = $this->id;
$item = $this->inventory->getItemInHand(); $item = $this->inventory->getItemInHand();
$ev = new PlayerDropItemEvent($this, $item); $ev = PlayerDropItemEvent::createEvent($this, $item);
$this->server->getPluginManager()->callEvent($ev); $this->server->getPluginManager()->callEvent($ev);
if($ev->isCancelled()){ if($ev->isCancelled()){
$this->inventory->sendContents($this); $this->inventory->sendContents($this);
@ -2015,7 +2063,7 @@ class Player extends Human implements CommandSender, InventoryHolder, IPlayer{
$packet->message = TextFormat::clean($packet->message); $packet->message = TextFormat::clean($packet->message);
if(trim($packet->message) != "" and strlen($packet->message) <= 255){ if(trim($packet->message) != "" and strlen($packet->message) <= 255){
$message = $packet->message; $message = $packet->message;
$this->server->getPluginManager()->callEvent($ev = new PlayerCommandPreprocessEvent($this, $message)); $this->server->getPluginManager()->callEvent($ev = PlayerCommandPreprocessEvent::createEvent($this, $message));
if($ev->isCancelled()){ if($ev->isCancelled()){
break; break;
} }
@ -2024,7 +2072,7 @@ class Player extends Human implements CommandSender, InventoryHolder, IPlayer{
$this->server->dispatchCommand($ev->getPlayer(), substr($ev->getMessage(), 1)); $this->server->dispatchCommand($ev->getPlayer(), substr($ev->getMessage(), 1));
Timings::$playerCommandTimer->stopTiming(); Timings::$playerCommandTimer->stopTiming();
}else{ }else{
$this->server->getPluginManager()->callEvent($ev = new PlayerChatEvent($this, $ev->getMessage())); $this->server->getPluginManager()->callEvent($ev = PlayerChatEvent::createEvent($this, $ev->getMessage()));
if(!$ev->isCancelled()){ if(!$ev->isCancelled()){
$this->server->broadcastMessage(sprintf($ev->getFormat(), $ev->getPlayer()->getDisplayName(), $ev->getMessage()), $ev->getRecipients()); $this->server->broadcastMessage(sprintf($ev->getFormat(), $ev->getPlayer()->getDisplayName(), $ev->getMessage()), $ev->getRecipients());
} }
@ -2038,7 +2086,7 @@ class Player extends Human implements CommandSender, InventoryHolder, IPlayer{
$this->craftingType = 0; $this->craftingType = 0;
$this->currentTransaction = null; $this->currentTransaction = null;
if(isset($this->windowIndex[$packet->windowid])){ if(isset($this->windowIndex[$packet->windowid])){
$this->server->getPluginManager()->callEvent(new InventoryCloseEvent($this->windowIndex[$packet->windowid], $this)); $this->server->getPluginManager()->callEvent(InventoryCloseEvent::createEvent($this->windowIndex[$packet->windowid], $this));
$this->removeWindow($this->windowIndex[$packet->windowid]); $this->removeWindow($this->windowIndex[$packet->windowid]);
}else{ }else{
unset($this->windowIndex[$packet->windowid]); unset($this->windowIndex[$packet->windowid]);
@ -2185,7 +2233,7 @@ class Player extends Human implements CommandSender, InventoryHolder, IPlayer{
} }
$this->craftingType = 0; $this->craftingType = 0;
$t = $this->level->getTile($v = new Vector3($packet->x, $packet->y, $packet->z)); $t = $this->level->getTile(Vector3::createVector($packet->x, $packet->y, $packet->z));
if($t instanceof Sign){ if($t instanceof Sign){
$nbt = new NBT(NBT::LITTLE_ENDIAN); $nbt = new NBT(NBT::LITTLE_ENDIAN);
$nbt->read($packet->namedtag); $nbt->read($packet->namedtag);
@ -2193,7 +2241,7 @@ class Player extends Human implements CommandSender, InventoryHolder, IPlayer{
if($nbt["id"] !== Tile::SIGN){ if($nbt["id"] !== Tile::SIGN){
$t->spawnTo($this); $t->spawnTo($this);
}else{ }else{
$ev = new SignChangeEvent($this->level->getBlock($v), $this, [ $ev = SignChangeEvent::createEvent($t->getBlock(), $this, [
$nbt["Text1"], $nbt["Text2"], $nbt["Text3"], $nbt["Text4"] $nbt["Text1"], $nbt["Text2"], $nbt["Text3"], $nbt["Text4"]
]); ]);
@ -2224,7 +2272,7 @@ class Player extends Human implements CommandSender, InventoryHolder, IPlayer{
* @return bool * @return bool
*/ */
public function kick($reason = ""){ public function kick($reason = ""){
$this->server->getPluginManager()->callEvent($ev = new PlayerKickEvent($this, $reason, TextFormat::YELLOW . $this->username . " has left the game")); $this->server->getPluginManager()->callEvent($ev = PlayerKickEvent::createEvent($this, $reason, TextFormat::YELLOW . $this->username . " has left the game"));
if(!$ev->isCancelled()){ if(!$ev->isCancelled()){
$message = "Kicked by admin." . ($reason !== "" ? " Reason: " . $reason : ""); $message = "Kicked by admin." . ($reason !== "" ? " Reason: " . $reason : "");
$this->sendMessage($message); $this->sendMessage($message);
@ -2248,7 +2296,7 @@ class Player extends Human implements CommandSender, InventoryHolder, IPlayer{
$mes = explode("\n", $message); $mes = explode("\n", $message);
foreach($mes as $m){ foreach($mes as $m){
if($m !== ""){ if($m !== ""){
$pk = new MessagePacket; $pk = MessagePacket::getFromPool();
$pk->source = ""; //Do not use this ;) $pk->source = ""; //Do not use this ;)
$pk->message = $m; $pk->message = $m;
$this->dataPacket($pk); $this->dataPacket($pk);
@ -2270,7 +2318,7 @@ class Player extends Human implements CommandSender, InventoryHolder, IPlayer{
if($this->connected and !$this->closed){ if($this->connected and !$this->closed){
$this->connected = false; $this->connected = false;
if($this->username != ""){ if($this->username != ""){
$this->server->getPluginManager()->callEvent($ev = new PlayerQuitEvent($this, $message)); $this->server->getPluginManager()->callEvent($ev = PlayerQuitEvent::createEvent($this, $message));
if($this->server->getAutoSave() and $this->loggedIn === true){ if($this->server->getAutoSave() and $this->loggedIn === true){
$this->save(); $this->save();
} }
@ -2310,7 +2358,7 @@ class Player extends Human implements CommandSender, InventoryHolder, IPlayer{
*/ */
public function save(){ public function save(){
if($this->closed){ if($this->closed){
throw new \Exception("Tried to save closed player"); throw new \InvalidStateException("Tried to save closed player");
} }
parent::saveNBT(); parent::saveNBT();
@ -2440,7 +2488,7 @@ class Player extends Human implements CommandSender, InventoryHolder, IPlayer{
Entity::kill(); Entity::kill();
$this->server->getPluginManager()->callEvent($ev = new PlayerDeathEvent($this, $this->getDrops(), $message)); $this->server->getPluginManager()->callEvent($ev = PlayerDeathEvent::createEvent($this, $this->getDrops(), $message));
if(!$ev->getKeepInventory()){ if(!$ev->getKeepInventory()){
foreach($ev->getDrops() as $item){ foreach($ev->getDrops() as $item){
@ -2463,7 +2511,7 @@ class Player extends Human implements CommandSender, InventoryHolder, IPlayer{
public function setHealth($amount){ public function setHealth($amount){
parent::setHealth($amount); parent::setHealth($amount);
if($this->spawned === true){ if($this->spawned === true){
$pk = new SetHealthPacket(); $pk = SetHealthPacket::getFromPool();
$pk->health = $this->getHealth(); $pk->health = $this->getHealth();
$this->dataPacket($pk); $this->dataPacket($pk);
} }
@ -2473,7 +2521,7 @@ class Player extends Human implements CommandSender, InventoryHolder, IPlayer{
if($this->dead === true){ if($this->dead === true){
return; return;
} }
if(($this->getGamemode() & 0x01) === 1){ if($this->isCreative()){
if($source instanceof EntityDamageEvent){ if($source instanceof EntityDamageEvent){
$cause = $source->getCause(); $cause = $source->getCause();
}else{ }else{
@ -2485,6 +2533,9 @@ class Player extends Human implements CommandSender, InventoryHolder, IPlayer{
and $cause !== EntityDamageEvent::CAUSE_SUICIDE and $cause !== EntityDamageEvent::CAUSE_SUICIDE
and $cause !== EntityDamageEvent::CAUSE_VOID and $cause !== EntityDamageEvent::CAUSE_VOID
){ ){
if($source instanceof EntityDamageEvent){
$source->setCancelled();
}
return; return;
} }
} }
@ -2492,8 +2543,12 @@ class Player extends Human implements CommandSender, InventoryHolder, IPlayer{
parent::attack($damage, $source); parent::attack($damage, $source);
if($source instanceof EntityDamageEvent and $source->isCancelled()){
return;
}
if($this->getLastDamageCause() === $source){ if($this->getLastDamageCause() === $source){
$pk = new EntityEventPacket(); $pk = EntityEventPacket::getFromPool();
$pk->eid = 0; $pk->eid = 0;
$pk->event = 2; $pk->event = 2;
$this->dataPacket($pk); $this->dataPacket($pk);
@ -2535,13 +2590,14 @@ class Player extends Human implements CommandSender, InventoryHolder, IPlayer{
$this->airTicks = 300; $this->airTicks = 300;
$this->fallDistance = 0; $this->fallDistance = 0;
$this->orderChunks(); $this->orderChunks();
$this->nextChunkOrderRun = 0;
$this->forceMovement = $pos; $this->forceMovement = $pos;
$this->newPosition = $pos; $this->newPosition = $pos;
$pk = new MovePlayerPacket; $pk = MovePlayerPacket::getFromPool();
$pk->eid = 0; $pk->eid = 0;
$pk->x = $this->x; $pk->x = $this->x;
$pk->y = $this->y + $this->getEyeHeight(); $pk->y = $this->y + $this->getEyeHeight() + 0.01;
$pk->z = $this->z; $pk->z = $this->z;
$pk->bodyYaw = $this->yaw; $pk->bodyYaw = $this->yaw;
$pk->pitch = $this->pitch; $pk->pitch = $this->pitch;

View File

@ -65,14 +65,13 @@ namespace {
} }
namespace pocketmine { namespace pocketmine {
use LogLevel;
use pocketmine\utils\Binary; use pocketmine\utils\Binary;
use pocketmine\utils\MainLogger; use pocketmine\utils\MainLogger;
use pocketmine\utils\Utils; use pocketmine\utils\Utils;
use pocketmine\wizard\Installer; use pocketmine\wizard\Installer;
const VERSION = "Alpha_1.4dev"; const VERSION = "Alpha_1.4dev";
const API_VERSION = "1.6.0"; const API_VERSION = "1.7.0";
const CODENAME = "絶好(Zekkou)ケーキ(Cake)"; const CODENAME = "絶好(Zekkou)ケーキ(Cake)";
const MINECRAFT_VERSION = "v0.10.0 alpha build2"; const MINECRAFT_VERSION = "v0.10.0 alpha build2";
@ -327,55 +326,7 @@ namespace pocketmine {
return rtrim(str_replace(["\\", ".php", "phar://", rtrim(str_replace(["\\", "phar://"], ["/", ""], \pocketmine\PATH), "/"), rtrim(str_replace(["\\", "phar://"], ["/", ""], \pocketmine\PLUGIN_PATH), "/")], ["/", "", "", "", ""], $path), "/"); return rtrim(str_replace(["\\", ".php", "phar://", rtrim(str_replace(["\\", "phar://"], ["/", ""], \pocketmine\PATH), "/"), rtrim(str_replace(["\\", "phar://"], ["/", ""], \pocketmine\PLUGIN_PATH), "/")], ["/", "", "", "", ""], $path), "/");
} }
function error_handler($errno, $errstr, $errfile, $errline, $context, $trace = null){ set_error_handler([\ExceptionHandler::class, "handler"], -1);
global $lastError;
if(error_reporting() === 0){ //@ error-con..trol
return false;
}
$errorConversion = [
E_ERROR => "E_ERROR",
E_WARNING => "E_WARNING",
E_PARSE => "E_PARSE",
E_NOTICE => "E_NOTICE",
E_CORE_ERROR => "E_CORE_ERROR",
E_CORE_WARNING => "E_CORE_WARNING",
E_COMPILE_ERROR => "E_COMPILE_ERROR",
E_COMPILE_WARNING => "E_COMPILE_WARNING",
E_USER_ERROR => "E_USER_ERROR",
E_USER_WARNING => "E_USER_WARNING",
E_USER_NOTICE => "E_USER_NOTICE",
E_STRICT => "E_STRICT",
E_RECOVERABLE_ERROR => "E_RECOVERABLE_ERROR",
E_DEPRECATED => "E_DEPRECATED",
E_USER_DEPRECATED => "E_USER_DEPRECATED",
];
$type = ($errno === E_ERROR or $errno === E_USER_ERROR) ? LogLevel::ERROR : (($errno === E_USER_WARNING or $errno === E_WARNING) ? LogLevel::WARNING : LogLevel::NOTICE);
$errno = isset($errorConversion[$errno]) ? $errorConversion[$errno] : $errno;
if(($pos = strpos($errstr, "\n")) !== false){
$errstr = substr($errstr, 0, $pos);
}
$logger = MainLogger::getLogger();
$oldFile = $errfile;
$errfile = cleanPath($errfile);
$logger->log($type, "An $errno error happened: \"$errstr\" in \"$errfile\" at line $errline");
foreach(($trace = getTrace($trace === null ? 3 : 0, $trace)) as $i => $line){
$logger->debug($line);
}
$lastError = [
"type" => $type,
"message" => $errstr,
"fullFile" => $oldFile,
"file" => $errfile,
"line" => $errline,
"trace" => $trace
];
return true;
}
set_error_handler("\\pocketmine\\error_handler", E_ALL);
$errors = 0; $errors = 0;

View File

@ -31,6 +31,16 @@ use pocketmine\command\CommandSender;
use pocketmine\command\ConsoleCommandSender; use pocketmine\command\ConsoleCommandSender;
use pocketmine\command\PluginIdentifiableCommand; use pocketmine\command\PluginIdentifiableCommand;
use pocketmine\command\SimpleCommandMap; use pocketmine\command\SimpleCommandMap;
use pocketmine\entity\Arrow;
use pocketmine\entity\Entity;
use pocketmine\entity\FallingSand;
use pocketmine\entity\Human;
use pocketmine\entity\Item as DroppedItem;
use pocketmine\entity\PrimedTNT;
use pocketmine\entity\Snowball;
use pocketmine\entity\Villager;
use pocketmine\entity\Zombie;
use pocketmine\event\Event;
use pocketmine\event\HandlerList; use pocketmine\event\HandlerList;
use pocketmine\event\level\LevelInitEvent; use pocketmine\event\level\LevelInitEvent;
use pocketmine\event\level\LevelLoadEvent; use pocketmine\event\level\LevelLoadEvent;
@ -50,6 +60,9 @@ use pocketmine\level\generator\GenerationRequestManager;
use pocketmine\level\generator\Generator; use pocketmine\level\generator\Generator;
use pocketmine\level\generator\Normal; use pocketmine\level\generator\Normal;
use pocketmine\level\Level; use pocketmine\level\Level;
use pocketmine\level\Position;
use pocketmine\math\AxisAlignedBB;
use pocketmine\math\Vector3;
use pocketmine\metadata\EntityMetadataStore; use pocketmine\metadata\EntityMetadataStore;
use pocketmine\metadata\LevelMetadataStore; use pocketmine\metadata\LevelMetadataStore;
use pocketmine\metadata\PlayerMetadataStore; use pocketmine\metadata\PlayerMetadataStore;
@ -78,11 +91,17 @@ use pocketmine\plugin\PluginManager;
use pocketmine\scheduler\CallbackTask; use pocketmine\scheduler\CallbackTask;
use pocketmine\scheduler\SendUsageTask; use pocketmine\scheduler\SendUsageTask;
use pocketmine\scheduler\ServerScheduler; use pocketmine\scheduler\ServerScheduler;
use pocketmine\tile\Chest;
use pocketmine\tile\Furnace;
use pocketmine\tile\Sign;
use pocketmine\tile\Tile;
use pocketmine\updater\AutoUpdater; use pocketmine\updater\AutoUpdater;
use pocketmine\utils\Binary; use pocketmine\utils\Binary;
use pocketmine\utils\Cache; use pocketmine\utils\Cache;
use pocketmine\utils\Config; use pocketmine\utils\Config;
use pocketmine\utils\LevelException;
use pocketmine\utils\MainLogger; use pocketmine\utils\MainLogger;
use pocketmine\utils\ServerException;
use pocketmine\utils\TextFormat; use pocketmine\utils\TextFormat;
use pocketmine\utils\TextWrapper; use pocketmine\utils\TextWrapper;
use pocketmine\utils\Utils; use pocketmine\utils\Utils;
@ -915,6 +934,7 @@ class Server{
*/ */
public function unloadLevel(Level $level, $forceUnload = false){ public function unloadLevel(Level $level, $forceUnload = false){
if($level->unload($forceUnload) === true){ if($level->unload($forceUnload) === true){
Position::clearPositions();
unset($this->levels[$level->getID()]); unset($this->levels[$level->getID()]);
return true; return true;
@ -930,11 +950,11 @@ class Server{
* *
* @return bool * @return bool
* *
* @throws \Exception * @throws LevelException
*/ */
public function loadLevel($name){ public function loadLevel($name){
if(trim($name) === ""){ if(trim($name) === ""){
throw new \Exception("Invalid empty level name"); throw new LevelException("Invalid empty level name");
} }
if($this->isLevelLoaded($name)){ if($this->isLevelLoaded($name)){
return true; return true;
@ -970,7 +990,7 @@ class Server{
$level->initLevel(); $level->initLevel();
$this->getPluginManager()->callEvent(new LevelLoadEvent($level)); $this->getPluginManager()->callEvent(LevelLoadEvent::createEvent($level));
/*foreach($entities->getAll() as $entity){ /*foreach($entities->getAll() as $entity){
if(!isset($entity["id"])){ if(!isset($entity["id"])){
@ -1105,9 +1125,9 @@ class Server{
$level->initLevel(); $level->initLevel();
$this->getPluginManager()->callEvent(new LevelInitEvent($level)); $this->getPluginManager()->callEvent(LevelInitEvent::createEvent($level));
$this->getPluginManager()->callEvent(new LevelLoadEvent($level)); $this->getPluginManager()->callEvent(LevelLoadEvent::createEvent($level));
$this->getLogger()->notice("Spawn terrain for level \"$name\" is being generated in the background"); $this->getLogger()->notice("Spawn terrain for level \"$name\" is being generated in the background");
@ -1548,6 +1568,9 @@ class Server{
$this->consoleSender = new ConsoleCommandSender(); $this->consoleSender = new ConsoleCommandSender();
$this->commandMap = new SimpleCommandMap($this); $this->commandMap = new SimpleCommandMap($this);
$this->registerEntities();
$this->registerTiles();
InventoryType::init(); InventoryType::init();
Block::init(); Block::init();
Item::init(); Item::init();
@ -1697,6 +1720,9 @@ class Server{
foreach($players as $player){ foreach($players as $player){
$player->dataPacket($packet); $player->dataPacket($packet);
} }
if(isset($packet->__encapsulatedPacket)){
unset($packet->__encapsulatedPacket);
}
} }
@ -1739,7 +1765,7 @@ class Server{
public function checkConsole(){ public function checkConsole(){
Timings::$serverCommandTimer->startTiming(); Timings::$serverCommandTimer->startTiming();
if(($line = $this->console->getLine()) !== null){ if(($line = $this->console->getLine()) !== null){
$this->pluginManager->callEvent($ev = new ServerCommandEvent($this->consoleSender, $line)); $this->pluginManager->callEvent($ev = ServerCommandEvent::createEvent($this->consoleSender, $line));
if(!$ev->isCancelled()){ if(!$ev->isCancelled()){
$this->dispatchCommand($ev->getSender(), $ev->getCommand()); $this->dispatchCommand($ev->getSender(), $ev->getCommand());
} }
@ -1759,7 +1785,7 @@ class Server{
*/ */
public function dispatchCommand(CommandSender $sender, $commandLine){ public function dispatchCommand(CommandSender $sender, $commandLine){
if(!($sender instanceof CommandSender)){ if(!($sender instanceof CommandSender)){
throw new \Exception("CommandSender is not valid"); throw new ServerException("CommandSender is not valid");
} }
if($this->commandMap->dispatch($sender, $commandLine)){ if($this->commandMap->dispatch($sender, $commandLine)){
@ -1929,12 +1955,38 @@ class Server{
} }
} }
public function exceptionHandler(\Exception $e){ public function exceptionHandler(\Exception $e, $trace = null){
if($e === null){ if($e === null){
return; return;
} }
error_handler(E_ERROR, $e->getMessage(), $e->getFile(), $e->getLine(), [], $e->getTrace()); global $lastError;
$errstr = $e->getMessage();
$errfile = $e->getFile();
$errno = $e->getCode();
$errline = $e->getLine();
$type = ($errno === E_ERROR or $errno === E_USER_ERROR) ? \LogLevel::ERROR : (($errno === E_USER_WARNING or $errno === E_WARNING) ? \LogLevel::WARNING : \LogLevel::NOTICE);
if(($pos = strpos($errstr, "\n")) !== false){
$errstr = substr($errstr, 0, $pos);
}
$errfile = cleanPath($errfile);
if($this->logger instanceof MainLogger){
$this->logger->logException($e, $trace);
}
$lastError = [
"type" => $type,
"message" => $errstr,
"fullFile" => $e->getFile(),
"file" => $errfile,
"line" => $errline,
"trace" => getTrace($trace === null ? 3 : 0, $trace)
];
global $lastExceptionError, $lastError; global $lastExceptionError, $lastError;
$lastExceptionError = $lastError; $lastExceptionError = $lastError;
$this->crashDump(); $this->crashDump();
@ -2111,6 +2163,20 @@ class Server{
$this->generationManager->process(); $this->generationManager->process();
Vector3::clearVectorList();
Position::clearPositionList();
if(($this->tickCounter % 4) === 0){
Event::clearAllPools();
if(($this->tickCounter % 80) === 0){
foreach($this->levels as $level){
$level->clearCache();
}
AxisAlignedBB::clearBoundingBoxPool();
}
}
Timings::$serverTickTimer->stopTiming(); Timings::$serverTickTimer->stopTiming();
TimingsHandler::tick(); TimingsHandler::tick();
@ -2129,4 +2195,22 @@ class Server{
return true; return true;
} }
private function registerEntities(){
Entity::registerEntity(Arrow::class);
Entity::registerEntity(DroppedItem::class);
Entity::registerEntity(FallingSand::class);
Entity::registerEntity(PrimedTNT::class);
Entity::registerEntity(Snowball::class);
Entity::registerEntity(Villager::class);
Entity::registerEntity(Zombie::class);
Entity::registerEntity(Human::class, true);
}
private function registerTiles(){
Tile::registerTile(Chest::class);
Tile::registerTile(Furnace::class);
Tile::registerTile(Sign::class);
}
} }

View File

@ -35,12 +35,8 @@ class Bed extends Transparent{
$this->hardness = 1; $this->hardness = 1;
} }
public function getBoundingBox(){ protected function recalculateBoundingBox(){
if($this->boundingBox !== null){ return AxisAlignedBB::getBoundingBoxFromPool(
return $this->boundingBox;
}
return $this->boundingBox = new AxisAlignedBB(
$this->x, $this->x,
$this->y, $this->y,
$this->z, $this->z,
@ -57,7 +53,7 @@ class Bed extends Transparent{
$isNight = ($time >= Level::TIME_NIGHT and $time < Level::TIME_SUNRISE); $isNight = ($time >= Level::TIME_NIGHT and $time < Level::TIME_SUNRISE);
if($player instanceof Player and !$isNight){ if($player instanceof Player and !$isNight){
$pk = new ChatPacket; $pk = ChatPacket::getFromPool();
$pk->message = "You can only sleep at night"; $pk->message = "You can only sleep at night";
$player->dataPacket($pk); $player->dataPacket($pk);
@ -81,7 +77,7 @@ class Bed extends Transparent{
$b = $blockWest; $b = $blockWest;
}else{ }else{
if($player instanceof Player){ if($player instanceof Player){
$pk = new ChatPacket; $pk = ChatPacket::getFromPool();
$pk->message = "This bed is incomplete"; $pk->message = "This bed is incomplete";
$player->dataPacket($pk); $player->dataPacket($pk);
} }
@ -91,7 +87,7 @@ class Bed extends Transparent{
} }
if($player instanceof Player and $player->sleepOn($b) === false){ if($player instanceof Player and $player->sleepOn($b) === false){
$pk = new ChatPacket; $pk = ChatPacket::getFromPool();
$pk->message = "This bed is occupied"; $pk->message = "This bed is occupied";
$player->dataPacket($pk); $player->dataPacket($pk);
} }

View File

@ -533,7 +533,6 @@ class Block extends Position implements Metadatable{
protected $name = "Unknown"; protected $name = "Unknown";
protected $breakTime = 0.20; protected $breakTime = 0.20;
protected $hardness = 10; protected $hardness = 10;
protected $boundingBox = null;
public $hasEntityCollision = false; public $hasEntityCollision = false;
public $isActivable = false; public $isActivable = false;
public $breakable = true; public $breakable = true;
@ -550,6 +549,9 @@ class Block extends Position implements Metadatable{
public $z = 0; public $z = 0;
public $frictionFactor = 0.6; public $frictionFactor = 0.6;
/** @var AxisAlignedBB */
protected $boundingBox = null;
public static function init(){ public static function init(){
if(count(self::$list) === 0){ if(count(self::$list) === 0){
self::$list = [ self::$list = [
@ -719,7 +721,7 @@ class Block extends Position implements Metadatable{
$block = new Block($id, $meta); $block = new Block($id, $meta);
} }
if($pos instanceof Position){ if($pos !== null){
$block->x = $pos->x; $block->x = $pos->x;
$block->y = $pos->y; $block->y = $pos->y;
$block->z = $pos->z; $block->z = $pos->z;
@ -852,7 +854,6 @@ class Block extends Position implements Metadatable{
$this->y = (int) $v->y; $this->y = (int) $v->y;
$this->z = (int) $v->z; $this->z = (int) $v->z;
$this->level = $v->level; $this->level = $v->level;
$this->boundingBox = null;
} }
/** /**
@ -933,9 +934,16 @@ class Block extends Position implements Metadatable{
public function getBoundingBox(){ public function getBoundingBox(){
if($this->boundingBox !== null){ if($this->boundingBox !== null){
return $this->boundingBox; return $this->boundingBox;
}else{
return $this->boundingBox = $this->recalculateBoundingBox();
} }
}
return $this->boundingBox = new AxisAlignedBB( /**
* @return AxisAlignedBB
*/
protected function recalculateBoundingBox(){
return AxisAlignedBB::getBoundingBoxFromPool(
$this->x, $this->x,
$this->y, $this->y,
$this->z, $this->z,

View File

@ -55,7 +55,7 @@ class BurningFurnace extends Solid{
new Int("z", $this->z) new Int("z", $this->z)
]); ]);
$nbt->Items->setTagType(NBT::TAG_Compound); $nbt->Items->setTagType(NBT::TAG_Compound);
new Furnace($this->getLevel()->getChunk($this->x >> 4, $this->z >> 4), $nbt); Tile::createTile("Furnace", $this->getLevel()->getChunk($this->x >> 4, $this->z >> 4), $nbt);
return true; return true;
} }
@ -81,7 +81,7 @@ class BurningFurnace extends Solid{
new Int("z", $this->z) new Int("z", $this->z)
]); ]);
$nbt->Items->setTagType(NBT::TAG_Compound); $nbt->Items->setTagType(NBT::TAG_Compound);
$furnace = new Furnace($this->getLevel()->getChunk($this->x >> 4, $this->z >> 4), $nbt); $furnace = Tile::createTile("Furnace", $this->getLevel()->getChunk($this->x >> 4, $this->z >> 4), $nbt);
} }
if(($player->getGamemode() & 0x01) === 0x01){ if(($player->getGamemode() & 0x01) === 0x01){

View File

@ -28,7 +28,7 @@ use pocketmine\event\entity\EntityDamageEvent;
use pocketmine\item\Item; use pocketmine\item\Item;
use pocketmine\level\Level; use pocketmine\level\Level;
use pocketmine\math\AxisAlignedBB; use pocketmine\math\AxisAlignedBB;
use pocketmine\math\Vector3 as Vector3; use pocketmine\math\Vector3;
use pocketmine\Player; use pocketmine\Player;
use pocketmine\Server; use pocketmine\Server;
@ -42,12 +42,9 @@ class Cactus extends Transparent{
$this->hardness = 2; $this->hardness = 2;
} }
public function getBoundingBox(){ protected function recalculateBoundingBox(){
if($this->boundingBox !== null){
return $this->boundingBox;
}
return $this->boundingBox = new AxisAlignedBB( return AxisAlignedBB::getBoundingBoxFromPool(
$this->x + 0.0625, $this->x + 0.0625,
$this->y, $this->y,
$this->z + 0.0625, $this->z + 0.0625,
@ -58,11 +55,8 @@ class Cactus extends Transparent{
} }
public function onEntityCollide(Entity $entity){ public function onEntityCollide(Entity $entity){
$ev = new EntityDamageByBlockEvent($this, $entity, EntityDamageEvent::CAUSE_CONTACT, 1); $ev = EntityDamageByBlockEvent::createEvent($this, $entity, EntityDamageEvent::CAUSE_CONTACT, 1);
Server::getInstance()->getPluginManager()->callEvent($ev); $entity->attack($ev->getFinalDamage(), $ev);
if(!$ev->isCancelled()){
$entity->attack($ev->getFinalDamage(), $ev);
}
} }
public function onUpdate($type){ public function onUpdate($type){
@ -82,9 +76,9 @@ class Cactus extends Transparent{
if($this->getSide(0)->getID() !== self::CACTUS){ if($this->getSide(0)->getID() !== self::CACTUS){
if($this->meta == 0x0F){ if($this->meta == 0x0F){
for($y = 1; $y < 3; ++$y){ for($y = 1; $y < 3; ++$y){
$b = $this->getLevel()->getBlock(new Vector3($this->x, $this->y + $y, $this->z)); $b = $this->getLevel()->getBlock(Vector3::createVector($this->x, $this->y + $y, $this->z));
if($b->getID() === self::AIR){ if($b->getID() === self::AIR){
Server::getInstance()->getPluginManager()->callEvent($ev = new BlockGrowEvent($b, new Cactus())); Server::getInstance()->getPluginManager()->callEvent($ev = BlockGrowEvent::createEvent($b, new Cactus()));
if(!$ev->isCancelled()){ if(!$ev->isCancelled()){
$this->getLevel()->setBlock($b, $ev->getNewState(), true); $this->getLevel()->setBlock($b, $ev->getNewState(), true);
} }

View File

@ -37,14 +37,11 @@ class Cake extends Transparent{
$this->hardness = 2.5; $this->hardness = 2.5;
} }
public function getBoundingBox(){ protected function recalculateBoundingBox(){
if($this->boundingBox !== null){
return $this->boundingBox;
}
$f = (1 + $this->getDamage() * 2) / 16; $f = (1 + $this->getDamage() * 2) / 16;
return $this->boundingBox = new AxisAlignedBB( return AxisAlignedBB::getBoundingBoxFromPool(
$this->x + $f, $this->x + $f,
$this->y, $this->y,
$this->z + 0.0625, $this->z + 0.0625,
@ -84,7 +81,7 @@ class Cake extends Transparent{
public function onActivate(Item $item, Player $player = null){ public function onActivate(Item $item, Player $player = null){
if($player instanceof Player and $player->getHealth() < 20){ if($player instanceof Player and $player->getHealth() < 20){
++$this->meta; ++$this->meta;
Server::getInstance()->getPluginManager()->callEvent($ev = new EntityRegainHealthEvent($player, 3, EntityRegainHealthEvent::CAUSE_EATING)); Server::getInstance()->getPluginManager()->callEvent($ev = EntityRegainHealthEvent::createEvent($player, 3, EntityRegainHealthEvent::CAUSE_EATING));
if(!$ev->isCancelled()){ if(!$ev->isCancelled()){
$player->heal($ev->getAmount(), $ev); $player->heal($ev->getAmount(), $ev);
} }

View File

@ -53,12 +53,9 @@ class Carpet extends Flowable{
$this->isSolid = true; $this->isSolid = true;
} }
public function getBoundingBox(){ protected function recalculateBoundingBox(){
if($this->boundingBox !== null){
return $this->boundingBox;
}
return $this->boundingBox = new AxisAlignedBB( return AxisAlignedBB::getBoundingBoxFromPool(
$this->x, $this->x,
$this->y, $this->y,
$this->z, $this->z,

View File

@ -42,12 +42,9 @@ class Chest extends Transparent{
$this->hardness = 15; $this->hardness = 15;
} }
public function getBoundingBox(){ protected function recalculateBoundingBox(){
if($this->boundingBox !== null){
return $this->boundingBox;
}
return $this->boundingBox = new AxisAlignedBB( return AxisAlignedBB::getBoundingBoxFromPool(
$this->x + 0.0625, $this->x + 0.0625,
$this->y, $this->y,
$this->z + 0.0625, $this->z + 0.0625,
@ -65,7 +62,7 @@ class Chest extends Transparent{
3 => 3, 3 => 3,
]; ];
$chest = false; $chest = null;
$this->meta = $faces[$player instanceof Player ? $player->getDirection() : 0]; $this->meta = $faces[$player instanceof Player ? $player->getDirection() : 0];
for($side = 2; $side <= 5; ++$side){ for($side = 2; $side <= 5; ++$side){
@ -93,9 +90,9 @@ class Chest extends Transparent{
new Int("z", $this->z) new Int("z", $this->z)
]); ]);
$nbt->Items->setTagType(NBT::TAG_Compound); $nbt->Items->setTagType(NBT::TAG_Compound);
$tile = new TileChest($this->getLevel()->getChunk($this->x >> 4, $this->z >> 4), $nbt); $tile = Tile::createTile("Chest", $this->getLevel()->getChunk($this->x >> 4, $this->z >> 4), $nbt);
if($chest instanceof TileChest){ if($chest instanceof TileChest and $tile instanceof TileChest){
$chest->pairWith($tile); $chest->pairWith($tile);
$tile->pairWith($chest); $tile->pairWith($chest);
} }
@ -133,11 +130,11 @@ class Chest extends Transparent{
new Int("z", $this->z) new Int("z", $this->z)
]); ]);
$nbt->Items->setTagType(NBT::TAG_Compound); $nbt->Items->setTagType(NBT::TAG_Compound);
$chest = new TileChest($this->getLevel()->getChunk($this->x >> 4, $this->z >> 4), $nbt); $chest = Tile::createTile("Chest", $this->getLevel()->getChunk($this->x >> 4, $this->z >> 4), $nbt);
} }
if(($player->gamemode & 0x01) === 0x01){ if($player->isCreative()){
return true; return true;
} }
$player->addWindow($chest->getInventory()); $player->addWindow($chest->getInventory());

View File

@ -57,7 +57,7 @@ abstract class Crops extends Flowable{
$block->meta = 7; $block->meta = 7;
} }
Server::getInstance()->getPluginManager()->callEvent($ev = new BlockGrowEvent($this, $block)); Server::getInstance()->getPluginManager()->callEvent($ev = BlockGrowEvent::createEvent($this, $block));
if(!$ev->isCancelled()){ if(!$ev->isCancelled()){
$this->getLevel()->setBlock($this, $ev->getNewState(), true, true); $this->getLevel()->setBlock($this, $ev->getNewState(), true, true);
@ -82,7 +82,7 @@ abstract class Crops extends Flowable{
if($this->meta < 0x07){ if($this->meta < 0x07){
$block = clone $this; $block = clone $this;
++$block->meta; ++$block->meta;
Server::getInstance()->getPluginManager()->callEvent($ev = new BlockGrowEvent($this, $block)); Server::getInstance()->getPluginManager()->callEvent($ev = BlockGrowEvent::createEvent($this, $block));
if(!$ev->isCancelled()){ if(!$ev->isCancelled()){
$this->getLevel()->setBlock($this, $ev->getNewState(), true, true); $this->getLevel()->setBlock($this, $ev->getNewState(), true, true);

View File

@ -52,15 +52,12 @@ abstract class Door extends Transparent{
return $first & 0x07 | ($flag ? 8 : 0) | ($flag1 ? 0x10 : 0); return $first & 0x07 | ($flag ? 8 : 0) | ($flag1 ? 0x10 : 0);
} }
public function getBoundingBox(){ protected function recalculateBoundingBox(){
if($this->boundingBox !== null){
return $this->boundingBox;
}
$f = 0.1875; $f = 0.1875;
$damage = $this->getFullDamage(); $damage = $this->getFullDamage();
$bb = new AxisAlignedBB( $bb = AxisAlignedBB::getBoundingBoxFromPool(
$this->x, $this->x,
$this->y, $this->y,
$this->z, $this->z,
@ -76,7 +73,7 @@ abstract class Door extends Transparent{
if($j === 0){ if($j === 0){
if($flag){ if($flag){
if(!$flag1){ if(!$flag1){
$bb = new AxisAlignedBB( $bb->setBounds(
$this->x, $this->x,
$this->y, $this->y,
$this->z, $this->z,
@ -85,7 +82,7 @@ abstract class Door extends Transparent{
$this->z + $f $this->z + $f
); );
}else{ }else{
$bb = new AxisAlignedBB( $bb->setBounds(
$this->x, $this->x,
$this->y, $this->y,
$this->z + 1 - $f, $this->z + 1 - $f,
@ -95,7 +92,7 @@ abstract class Door extends Transparent{
); );
} }
}else{ }else{
$bb = new AxisAlignedBB( $bb->setBounds(
$this->x, $this->x,
$this->y, $this->y,
$this->z, $this->z,
@ -107,7 +104,7 @@ abstract class Door extends Transparent{
}elseif($j === 1){ }elseif($j === 1){
if($flag){ if($flag){
if(!$flag1){ if(!$flag1){
$bb = new AxisAlignedBB( $bb->setBounds(
$this->x + 1 - $f, $this->x + 1 - $f,
$this->y, $this->y,
$this->z, $this->z,
@ -116,7 +113,7 @@ abstract class Door extends Transparent{
$this->z + 1 $this->z + 1
); );
}else{ }else{
$bb = new AxisAlignedBB( $bb->setBounds(
$this->x, $this->x,
$this->y, $this->y,
$this->z, $this->z,
@ -126,7 +123,7 @@ abstract class Door extends Transparent{
); );
} }
}else{ }else{
$bb = new AxisAlignedBB( $bb->setBounds(
$this->x, $this->x,
$this->y, $this->y,
$this->z, $this->z,
@ -138,7 +135,7 @@ abstract class Door extends Transparent{
}elseif($j === 2){ }elseif($j === 2){
if($flag){ if($flag){
if(!$flag1){ if(!$flag1){
$bb = new AxisAlignedBB( $bb->setBounds(
$this->x, $this->x,
$this->y, $this->y,
$this->z + 1 - $f, $this->z + 1 - $f,
@ -147,7 +144,7 @@ abstract class Door extends Transparent{
$this->z + 1 $this->z + 1
); );
}else{ }else{
$bb = new AxisAlignedBB( $bb->setBounds(
$this->x, $this->x,
$this->y, $this->y,
$this->z, $this->z,
@ -157,7 +154,7 @@ abstract class Door extends Transparent{
); );
} }
}else{ }else{
$bb = new AxisAlignedBB( $bb->setBounds(
$this->x + 1 - $f, $this->x + 1 - $f,
$this->y, $this->y,
$this->z, $this->z,
@ -169,7 +166,7 @@ abstract class Door extends Transparent{
}elseif($j === 3){ }elseif($j === 3){
if($flag){ if($flag){
if(!$flag1){ if(!$flag1){
$bb = new AxisAlignedBB( $bb->setBounds(
$this->x, $this->x,
$this->y, $this->y,
$this->z, $this->z,
@ -178,7 +175,7 @@ abstract class Door extends Transparent{
$this->z + 1 $this->z + 1
); );
}else{ }else{
$bb = new AxisAlignedBB( $bb->setBounds(
$this->x + 1 - $f, $this->x + 1 - $f,
$this->y, $this->y,
$this->z, $this->z,
@ -188,7 +185,7 @@ abstract class Door extends Transparent{
); );
} }
}else{ }else{
$bb = new AxisAlignedBB( $bb->setBounds(
$this->x, $this->x,
$this->y, $this->y,
$this->z + 1 - $f, $this->z + 1 - $f,
@ -199,7 +196,7 @@ abstract class Door extends Transparent{
} }
} }
return $this->boundingBox = $bb; return $bb;
} }
public function onUpdate($type){ public function onUpdate($type){
@ -274,7 +271,7 @@ abstract class Door extends Transparent{
if($player instanceof Player){ if($player instanceof Player){
unset($players[$player->getID()]); unset($players[$player->getID()]);
} }
$pk = new LevelEventPacket; $pk = LevelEventPacket::getFromPool();
$pk->x = $this->x; $pk->x = $this->x;
$pk->y = $this->y; $pk->y = $this->y;
$pk->z = $this->z; $pk->z = $this->z;
@ -293,7 +290,7 @@ abstract class Door extends Transparent{
if($player instanceof Player){ if($player instanceof Player){
unset($players[$player->getID()]); unset($players[$player->getID()]);
} }
$pk = new LevelEventPacket; $pk = LevelEventPacket::getFromPool();
$pk->x = $this->x; $pk->x = $this->x;
$pk->y = $this->y; $pk->y = $this->y;
$pk->z = $this->z; $pk->z = $this->z;

View File

@ -29,12 +29,9 @@ class EndPortal extends Solid{
$this->hardness = 18000000; $this->hardness = 18000000;
} }
public function getBoundingBox(){ protected function recalculateBoundingBox(){
if($this->boundingBox !== null){
return $this->boundingBox;
}
return $this->boundingBox = new AxisAlignedBB( return AxisAlignedBB::getBoundingBoxFromPool(
$this->x, $this->x,
$this->y, $this->y,
$this->z, $this->z,

View File

@ -21,7 +21,7 @@
namespace pocketmine\block; namespace pocketmine\block;
use pocketmine\entity\FallingBlock; use pocketmine\entity\Entity;
use pocketmine\item\Item; use pocketmine\item\Item;
use pocketmine\level\Level; use pocketmine\level\Level;
use pocketmine\nbt\tag\Byte; use pocketmine\nbt\tag\Byte;
@ -29,6 +29,7 @@ use pocketmine\nbt\tag\Compound;
use pocketmine\nbt\tag\Double; use pocketmine\nbt\tag\Double;
use pocketmine\nbt\tag\Enum; use pocketmine\nbt\tag\Enum;
use pocketmine\nbt\tag\Float; use pocketmine\nbt\tag\Float;
use pocketmine\nbt\tag\Int;
use pocketmine\Player; use pocketmine\Player;
abstract class Fallable extends Solid{ abstract class Fallable extends Solid{
@ -45,7 +46,7 @@ abstract class Fallable extends Solid{
if($this->hasPhysics === true and $type === Level::BLOCK_UPDATE_NORMAL){ if($this->hasPhysics === true and $type === Level::BLOCK_UPDATE_NORMAL){
$down = $this->getSide(0); $down = $this->getSide(0);
if($down->getID() === self::AIR or ($down instanceof Liquid)){ if($down->getID() === self::AIR or ($down instanceof Liquid)){
$fall = new FallingBlock($this->getLevel()->getChunk($this->x >> 4, $this->z >> 4), new Compound("", [ $fall = Entity::createEntity("FallingSand", $this->getLevel()->getChunk($this->x >> 4, $this->z >> 4), new Compound("", [
"Pos" => new Enum("Pos", [ "Pos" => new Enum("Pos", [
new Double("", $this->x + 0.5), new Double("", $this->x + 0.5),
new Double("", $this->y), new Double("", $this->y),
@ -60,13 +61,12 @@ abstract class Fallable extends Solid{
new Float("", 0), new Float("", 0),
new Float("", 0) new Float("", 0)
]), ]),
"Tile" => new Byte("Tile", $this->getID()) "TileID" => new Int("TileID", $this->getID()),
"Data" => new Byte("Data", $this->getDamage()),
])); ]));
$fall->spawnToAll(); $fall->spawnToAll();
} }
return false;
} }
} }
} }

View File

@ -30,12 +30,9 @@ class Farmland extends Solid{
$this->hardness = 3; $this->hardness = 3;
} }
public function getBoundingBox(){ protected function recalculateBoundingBox(){
if($this->boundingBox !== null){
return $this->boundingBox;
}
return $this->boundingBox = new AxisAlignedBB( return AxisAlignedBB::getBoundingBoxFromPool(
$this->x, $this->x,
$this->y, $this->y,
$this->z, $this->z,

View File

@ -30,10 +30,7 @@ class Fence extends Transparent{
$this->hardness = 15; $this->hardness = 15;
} }
public function getBoundingBox(){ protected function recalculateBoundingBox(){
if($this->boundingBox !== null){
return $this->boundingBox;
}
$flag = $this->canConnect($this->getSide(2)); $flag = $this->canConnect($this->getSide(2));
$flag1 = $this->canConnect($this->getSide(3)); $flag1 = $this->canConnect($this->getSide(3));
@ -45,12 +42,12 @@ class Fence extends Transparent{
$f2 = $flag ? 0 : 0.375; $f2 = $flag ? 0 : 0.375;
$f3 = $flag1 ? 1 : 0.625; $f3 = $flag1 ? 1 : 0.625;
return $this->boundingBox = new AxisAlignedBB( return AxisAlignedBB::getBoundingBoxFromPool(
$this->x + $f, $this->x + $f,
$this->y, $this->y,
$this->z + $f2, $this->z + $f2,
$this->x + $f1, $this->x + $f1,
$this->y + 1, //TODO: check this, add extra bounding box $this->y + 1,
$this->z + $f3 $this->z + $f3
); );
} }

View File

@ -38,10 +38,7 @@ class FenceGate extends Transparent{
} }
public function getBoundingBox(){ protected function recalculateBoundingBox(){
if($this->boundingBox !== null){
return $this->boundingBox;
}
if(($this->getDamage() & 0x04) > 0){ if(($this->getDamage() & 0x04) > 0){
return null; return null;
@ -49,7 +46,7 @@ class FenceGate extends Transparent{
$i = ($this->getDamage() & 0x03); $i = ($this->getDamage() & 0x03);
if($i === 2 and $i === 0){ if($i === 2 and $i === 0){
return $this->boundingBox = new AxisAlignedBB( return AxisAlignedBB::getBoundingBoxFromPool(
$this->x, $this->x,
$this->y, $this->y,
$this->z + 0.375, $this->z + 0.375,
@ -58,7 +55,7 @@ class FenceGate extends Transparent{
$this->z + 0.625 $this->z + 0.625
); );
}else{ }else{
return $this->boundingBox = new AxisAlignedBB( return AxisAlignedBB::getBoundingBoxFromPool(
$this->x + 0.375, $this->x + 0.375,
$this->y, $this->y,
$this->z, $this->z,

View File

@ -46,13 +46,10 @@ class Fire extends Flowable{
} }
public function onEntityCollide(Entity $entity){ public function onEntityCollide(Entity $entity){
$ev = new EntityDamageByBlockEvent($this, $entity, EntityDamageEvent::CAUSE_FIRE, 1); $ev = EntityDamageByBlockEvent::createEvent($this, $entity, EntityDamageEvent::CAUSE_FIRE, 1);
Server::getInstance()->getPluginManager()->callEvent($ev); $entity->attack($ev->getFinalDamage(), $ev);
if(!$ev->isCancelled()){
$entity->attack($ev->getFinalDamage(), $ev);
}
$ev = new EntityCombustByBlockEvent($this, $entity, 8); $ev = EntityCombustByBlockEvent::createEvent($this, $entity, 8);
Server::getInstance()->getPluginManager()->callEvent($ev); Server::getInstance()->getPluginManager()->callEvent($ev);
if(!$ev->isCancelled()){ if(!$ev->isCancelled()){
$entity->setOnFire($ev->getDuration()); $entity->setOnFire($ev->getDuration());

View File

@ -26,6 +26,7 @@ use pocketmine\item\Item;
use pocketmine\level\generator\object\TallGrass as TallGrassObject; use pocketmine\level\generator\object\TallGrass as TallGrassObject;
use pocketmine\level\Level; use pocketmine\level\Level;
use pocketmine\level\Position; use pocketmine\level\Position;
use pocketmine\math\Vector3;
use pocketmine\Player; use pocketmine\Player;
use pocketmine\Server; use pocketmine\Server;
use pocketmine\utils\Random; use pocketmine\utils\Random;
@ -54,11 +55,10 @@ class Grass extends Solid{
$x = mt_rand($this->x - 1, $this->x + 1); $x = mt_rand($this->x - 1, $this->x + 1);
$y = mt_rand($this->y - 2, $this->y + 2); $y = mt_rand($this->y - 2, $this->y + 2);
$z = mt_rand($this->z - 1, $this->z + 1); $z = mt_rand($this->z - 1, $this->z + 1);
$block = $this->getLevel()->getBlockIdAt($x, $y, $z); $block = $this->getLevel()->getBlock(Vector3::createVector($x, $y, $z));
if($block === Block::DIRT){ if($block->getID() === Block::DIRT){
$block = Block::get($block, $this->getLevel()->getBlockDataAt($x, $y, $z), new Position($x, $y, $z, $this->getLevel()));
if($block->getSide(1) instanceof Transparent){ if($block->getSide(1) instanceof Transparent){
Server::getInstance()->getPluginManager()->callEvent($ev = new BlockSpreadEvent($block, $this, new Grass())); Server::getInstance()->getPluginManager()->callEvent($ev = BlockSpreadEvent::createEvent($block, $this, new Grass()));
if(!$ev->isCancelled()){ if(!$ev->isCancelled()){
$this->getLevel()->setBlock($block, $ev->getNewState()); $this->getLevel()->setBlock($block, $ev->getNewState());
} }

View File

@ -43,15 +43,12 @@ class Ladder extends Transparent{
$entity->onGround = true; $entity->onGround = true;
} }
public function getBoundingBox(){ protected function recalculateBoundingBox(){
if($this->boundingBox !== null){
return $this->boundingBox;
}
$f = 0.125; $f = 0.125;
if($this->meta === 2){ if($this->meta === 2){
return $this->boundingBox = new AxisAlignedBB( return AxisAlignedBB::getBoundingBoxFromPool(
$this->x, $this->x,
$this->y, $this->y,
$this->z + 1 - $f, $this->z + 1 - $f,
@ -60,7 +57,7 @@ class Ladder extends Transparent{
$this->z + 1 $this->z + 1
); );
}elseif($this->meta === 3){ }elseif($this->meta === 3){
return $this->boundingBox = new AxisAlignedBB( return AxisAlignedBB::getBoundingBoxFromPool(
$this->x, $this->x,
$this->y, $this->y,
$this->z, $this->z,
@ -69,7 +66,7 @@ class Ladder extends Transparent{
$this->z + $f $this->z + $f
); );
}elseif($this->meta === 4){ }elseif($this->meta === 4){
return $this->boundingBox = new AxisAlignedBB( return AxisAlignedBB::getBoundingBoxFromPool(
$this->x + 1 - $f, $this->x + 1 - $f,
$this->y, $this->y,
$this->z, $this->z,
@ -78,7 +75,7 @@ class Ladder extends Transparent{
$this->z + 1 $this->z + 1
); );
}elseif($this->meta === 5){ }elseif($this->meta === 5){
return $this->boundingBox = new AxisAlignedBB( return AxisAlignedBB::getBoundingBoxFromPool(
$this->x, $this->x,
$this->y, $this->y,
$this->z, $this->z,

View File

@ -38,17 +38,18 @@ class Lava extends Liquid{
public function onEntityCollide(Entity $entity){ public function onEntityCollide(Entity $entity){
$entity->fallDistance *= 0.5; $entity->fallDistance *= 0.5;
$ev = new EntityDamageByBlockEvent($this, $entity, EntityDamageEvent::CAUSE_LAVA, 4); $ev = EntityDamageByBlockEvent::createEvent($this, $entity, EntityDamageEvent::CAUSE_LAVA, 4);
Server::getInstance()->getPluginManager()->callEvent($ev); $entity->attack($ev->getFinalDamage(), $ev);
if(!$ev->isCancelled()){
$entity->attack($ev->getFinalDamage(), $ev);
}
$ev = new EntityCombustByBlockEvent($this, $entity, 15); $ev = EntityCombustByBlockEvent::createEvent($this, $entity, 15);
Server::getInstance()->getPluginManager()->callEvent($ev); Server::getInstance()->getPluginManager()->callEvent($ev);
if(!$ev->isCancelled()){ if(!$ev->isCancelled()){
$entity->setOnFire($ev->getDuration()); $entity->setOnFire($ev->getDuration());
} }
if($entity instanceof Player){
$entity->onGround = true;
}
} }
public function place(Item $item, Block $block, Block $target, $face, $fx, $fy, $fz, Player $player = null){ public function place(Item $item, Block $block, Block $target, $face, $fx, $fy, $fz, Player $player = null){

View File

@ -124,7 +124,7 @@ class Leaves extends Transparent{
$visited = []; $visited = [];
$check = 0; $check = 0;
Server::getInstance()->getPluginManager()->callEvent($ev = new LeavesDecayEvent($this)); Server::getInstance()->getPluginManager()->callEvent($ev = LeavesDecayEvent::createEvent($this));
if($ev->isCancelled() or $this->findLog($this, $visited, 0, $check) === true){ if($ev->isCancelled() or $this->findLog($this, $visited, 0, $check) === true){
$this->getLevel()->setBlock($this, $this, false, false); $this->getLevel()->setBlock($this, $this, false, false);

View File

@ -116,7 +116,7 @@ class Leaves2 extends Leaves{
$visited = []; $visited = [];
$check = 0; $check = 0;
Server::getInstance()->getPluginManager()->callEvent($ev = new LeavesDecayEvent($this)); Server::getInstance()->getPluginManager()->callEvent($ev = LeavesDecayEvent::createEvent($this));
if($ev->isCancelled() or $this->findLog($this, $visited, 0, $check) === true){ if($ev->isCancelled() or $this->findLog($this, $visited, 0, $check) === true){
$this->getLevel()->setBlock($this, $this, false, false); $this->getLevel()->setBlock($this, $this, false, false);

View File

@ -80,7 +80,7 @@ abstract class Liquid extends Transparent{
} }
public function getFlowVector(){ public function getFlowVector(){
$vector = new Vector3(0, 0, 0); $vector = Vector3::createVector(0, 0, 0);
$decay = $this->getEffectiveFlowDecay($this); $decay = $this->getEffectiveFlowDecay($this);
@ -99,7 +99,7 @@ abstract class Liquid extends Transparent{
}elseif($j === 3){ }elseif($j === 3){
++$z; ++$z;
} }
$sideBlock = $this->getLevel()->getBlock(new Vector3($x, $y, $z)); $sideBlock = $this->getLevel()->getBlock(Vector3::createVector($x, $y, $z));
$blockDecay = $this->getEffectiveFlowDecay($sideBlock); $blockDecay = $this->getEffectiveFlowDecay($sideBlock);
if($blockDecay < 0){ if($blockDecay < 0){
@ -314,7 +314,7 @@ abstract class Liquid extends Transparent{
}elseif($j === 3){ }elseif($j === 3){
++$z; ++$z;
} }
$blockSide = $this->getLevel()->getBlock(new Vector3($x, $y, $z)); $blockSide = $this->getLevel()->getBlock(Vector3::createVector($x, $y, $z));
if(!$blockSide->isFlowable and !($blockSide instanceof Liquid)){ if(!$blockSide->isFlowable and !($blockSide instanceof Liquid)){
continue; continue;
@ -356,7 +356,7 @@ abstract class Liquid extends Transparent{
}elseif($j === 3){ }elseif($j === 3){
++$z; ++$z;
} }
$block = $this->getLevel()->getBlock(new Vector3($x, $y, $z)); $block = $this->getLevel()->getBlock(Vector3::createVector($x, $y, $z));
if(!$block->isFlowable and !($block instanceof Liquid)){ if(!$block->isFlowable and !($block instanceof Liquid)){
continue; continue;

View File

@ -42,7 +42,7 @@ class MelonStem extends Crops{
if($this->meta < 0x07){ if($this->meta < 0x07){
$block = clone $this; $block = clone $this;
++$block->meta; ++$block->meta;
Server::getInstance()->getPluginManager()->callEvent($ev = new BlockGrowEvent($this, $block)); Server::getInstance()->getPluginManager()->callEvent($ev = BlockGrowEvent::createEvent($this, $block));
if(!$ev->isCancelled()){ if(!$ev->isCancelled()){
$this->getLevel()->setBlock($this, $ev->getNewState(), true); $this->getLevel()->setBlock($this, $ev->getNewState(), true);
} }
@ -58,7 +58,7 @@ class MelonStem extends Crops{
$side = $this->getSide(mt_rand(2, 5)); $side = $this->getSide(mt_rand(2, 5));
$d = $side->getSide(0); $d = $side->getSide(0);
if($side->getID() === self::AIR and ($d->getID() === self::FARMLAND or $d->getID() === self::GRASS or $d->getID() === self::DIRT)){ if($side->getID() === self::AIR and ($d->getID() === self::FARMLAND or $d->getID() === self::GRASS or $d->getID() === self::DIRT)){
Server::getInstance()->getPluginManager()->callEvent($ev = new BlockGrowEvent($side, new Melon())); Server::getInstance()->getPluginManager()->callEvent($ev = BlockGrowEvent::createEvent($side, new Melon()));
if(!$ev->isCancelled()){ if(!$ev->isCancelled()){
$this->getLevel()->setBlock($side, $ev->getNewState(), true); $this->getLevel()->setBlock($side, $ev->getNewState(), true);
} }

View File

@ -25,6 +25,7 @@ use pocketmine\event\block\BlockSpreadEvent;
use pocketmine\item\Item; use pocketmine\item\Item;
use pocketmine\level\Level; use pocketmine\level\Level;
use pocketmine\level\Position; use pocketmine\level\Position;
use pocketmine\math\Vector3;
use pocketmine\Server; use pocketmine\Server;
class Mycelium extends Solid{ class Mycelium extends Solid{
@ -45,11 +46,10 @@ class Mycelium extends Solid{
$x = mt_rand($this->x - 1, $this->x + 1); $x = mt_rand($this->x - 1, $this->x + 1);
$y = mt_rand($this->y - 2, $this->y + 2); $y = mt_rand($this->y - 2, $this->y + 2);
$z = mt_rand($this->z - 1, $this->z + 1); $z = mt_rand($this->z - 1, $this->z + 1);
$block = $this->getLevel()->getBlockIdAt($x, $y, $z); $block = $this->getLevel()->getBlock(Vector3::createVector($x, $y, $z));
if($block === Block::DIRT){ if($block->getID() === Block::DIRT){
$block = Block::get($block, $this->getLevel()->getBlockDataAt($x, $y, $z), new Position($x, $y, $z, $this->getLevel()));
if($block->getSide(1) instanceof Transparent){ if($block->getSide(1) instanceof Transparent){
Server::getInstance()->getPluginManager()->callEvent($ev = new BlockSpreadEvent($block, $this, new Mycelium())); Server::getInstance()->getPluginManager()->callEvent($ev = BlockSpreadEvent::createEvent($block, $this, new Mycelium()));
if(!$ev->isCancelled()){ if(!$ev->isCancelled()){
$this->getLevel()->setBlock($block, $ev->getNewState()); $this->getLevel()->setBlock($block, $ev->getNewState());
} }

View File

@ -42,7 +42,7 @@ class PumpkinStem extends Crops{
if($this->meta < 0x07){ if($this->meta < 0x07){
$block = clone $this; $block = clone $this;
++$block->meta; ++$block->meta;
Server::getInstance()->getPluginManager()->callEvent($ev = new BlockGrowEvent($this, $block)); Server::getInstance()->getPluginManager()->callEvent($ev = BlockGrowEvent::createEvent($this, $block));
if(!$ev->isCancelled()){ if(!$ev->isCancelled()){
$this->getLevel()->setBlock($this, $ev->getNewState(), true); $this->getLevel()->setBlock($this, $ev->getNewState(), true);
} }
@ -58,7 +58,7 @@ class PumpkinStem extends Crops{
$side = $this->getSide(mt_rand(2, 5)); $side = $this->getSide(mt_rand(2, 5));
$d = $side->getSide(0); $d = $side->getSide(0);
if($side->getID() === self::AIR and ($d->getID() === self::FARMLAND or $d->getID() === self::GRASS or $d->getID() === self::DIRT)){ if($side->getID() === self::AIR and ($d->getID() === self::FARMLAND or $d->getID() === self::GRASS or $d->getID() === self::DIRT)){
Server::getInstance()->getPluginManager()->callEvent($ev = new BlockGrowEvent($side, new Pumpkin())); Server::getInstance()->getPluginManager()->callEvent($ev = BlockGrowEvent::createEvent($side, new Pumpkin()));
if(!$ev->isCancelled()){ if(!$ev->isCancelled()){
$this->getLevel()->setBlock($side, $ev->getNewState(), true); $this->getLevel()->setBlock($side, $ev->getNewState(), true);
} }

View File

@ -47,13 +47,10 @@ class Slab extends Transparent{
$this->hardness = 30; $this->hardness = 30;
} }
public function getBoundingBox(){ protected function recalculateBoundingBox(){
if($this->boundingBox !== null){
return $this->boundingBox;
}
if(($this->meta & 0x08) > 0){ if(($this->meta & 0x08) > 0){
return $this->boundingBox = new AxisAlignedBB( return AxisAlignedBB::getBoundingBoxFromPool(
$this->x, $this->x,
$this->y + 0.5, $this->y + 0.5,
$this->z, $this->z,
@ -62,7 +59,7 @@ class Slab extends Transparent{
$this->z + 1 $this->z + 1
); );
}else{ }else{
return $this->boundingBox = new AxisAlignedBB( return AxisAlignedBB::getBoundingBoxFromPool(
$this->x, $this->x,
$this->y, $this->y,
$this->z, $this->z,

View File

@ -30,12 +30,9 @@ class SoulSand extends Solid{
$this->hardness = 2.5; $this->hardness = 2.5;
} }
public function getBoundingBox(){ protected function recalculateBoundingBox(){
if($this->boundingBox !== null){
return $this->boundingBox;
}
return $this->boundingBox = new AxisAlignedBB( return AxisAlignedBB::getBoundingBoxFromPool(
$this->x, $this->x,
$this->y, $this->y,
$this->z, $this->z,

View File

@ -54,7 +54,7 @@ abstract class Stair extends Transparent{
$f3 = 0.5; $f3 = 0.5;
} }
if($bb->intersectsWith($bb2 = new AxisAlignedBB( if($bb->intersectsWith($bb2 = AxisAlignedBB::getBoundingBoxFromPool(
$this->x, $this->x,
$this->y + $f, $this->y + $f,
$this->z, $this->z,
@ -66,7 +66,7 @@ abstract class Stair extends Transparent{
} }
if($j === 0){ if($j === 0){
if($bb->intersectsWith($bb2 = new AxisAlignedBB( if($bb->intersectsWith($bb2 = AxisAlignedBB::getBoundingBoxFromPool(
$this->x + 0.5, $this->x + 0.5,
$this->y + $f2, $this->y + $f2,
$this->z, $this->z,
@ -77,7 +77,7 @@ abstract class Stair extends Transparent{
$list[] = $bb2; $list[] = $bb2;
} }
}elseif($j === 1){ }elseif($j === 1){
if($bb->intersectsWith($bb2 = new AxisAlignedBB( if($bb->intersectsWith($bb2 = AxisAlignedBB::getBoundingBoxFromPool(
$this->x, $this->x,
$this->y + $f2, $this->y + $f2,
$this->z, $this->z,
@ -88,7 +88,7 @@ abstract class Stair extends Transparent{
$list[] = $bb2; $list[] = $bb2;
} }
}elseif($j === 2){ }elseif($j === 2){
if($bb->intersectsWith($bb2 = new AxisAlignedBB( if($bb->intersectsWith($bb2 = AxisAlignedBB::getBoundingBoxFromPool(
$this->x, $this->x,
$this->y + $f2, $this->y + $f2,
$this->z + 0.5, $this->z + 0.5,
@ -99,7 +99,7 @@ abstract class Stair extends Transparent{
$list[] = $bb2; $list[] = $bb2;
} }
}elseif($j === 3){ }elseif($j === 3){
if($bb->intersectsWith($bb2 = new AxisAlignedBB( if($bb->intersectsWith($bb2 = AxisAlignedBB::getBoundingBoxFromPool(
$this->x, $this->x,
$this->y + $f2, $this->y + $f2,
$this->z, $this->z,
@ -113,13 +113,10 @@ abstract class Stair extends Transparent{
} }
*/ */
public function getBoundingBox(){ protected function recalculateBoundingBox(){
if($this->boundingBox !== null){
return $this->boundingBox;
}
if(($this->getDamage() & 0x04) > 0){ if(($this->getDamage() & 0x04) > 0){
return $this->boundingBox = new AxisAlignedBB( return AxisAlignedBB::getBoundingBoxFromPool(
$this->x, $this->x,
$this->y + 0.5, $this->y + 0.5,
$this->z, $this->z,
@ -128,7 +125,7 @@ abstract class Stair extends Transparent{
$this->z + 1 $this->z + 1
); );
}else{ }else{
return $this->boundingBox = new AxisAlignedBB( return AxisAlignedBB::getBoundingBoxFromPool(
$this->x, $this->x,
$this->y, $this->y,
$this->z, $this->z,

View File

@ -36,10 +36,7 @@ class StoneWall extends Transparent{
$this->hardness = 30; $this->hardness = 30;
} }
public function getBoundingBox(){ protected function recalculateBoundingBox(){
if($this->boundingBox !== null){
return $this->boundingBox;
}
$flag = $this->canConnect($this->getSide(2)); $flag = $this->canConnect($this->getSide(2));
$flag1 = $this->canConnect($this->getSide(3)); $flag1 = $this->canConnect($this->getSide(3));
@ -62,7 +59,7 @@ class StoneWall extends Transparent{
$f3 = 0.6875; $f3 = 0.6875;
} }
return $this->boundingBox = new AxisAlignedBB( return AxisAlignedBB::getBoundingBoxFromPool(
$this->x + $f, $this->x + $f,
$this->y, $this->y,
$this->z + $f2, $this->z + $f2,

View File

@ -49,9 +49,9 @@ class Sugarcane extends Flowable{
if($item->getID() === Item::DYE and $item->getDamage() === 0x0F){ //Bonemeal if($item->getID() === Item::DYE and $item->getDamage() === 0x0F){ //Bonemeal
if($this->getSide(0)->getID() !== self::SUGARCANE_BLOCK){ if($this->getSide(0)->getID() !== self::SUGARCANE_BLOCK){
for($y = 1; $y < 3; ++$y){ for($y = 1; $y < 3; ++$y){
$b = $this->getLevel()->getBlock(new Vector3($this->x, $this->y + $y, $this->z)); $b = $this->getLevel()->getBlock(Vector3::createVector($this->x, $this->y + $y, $this->z));
if($b->getID() === self::AIR){ if($b->getID() === self::AIR){
Server::getInstance()->getPluginManager()->callEvent($ev = new BlockGrowEvent($b, new Sugarcane())); Server::getInstance()->getPluginManager()->callEvent($ev = BlockGrowEvent::createEvent($b, new Sugarcane()));
if(!$ev->isCancelled()){ if(!$ev->isCancelled()){
$this->getLevel()->setBlock($b, $ev->getNewState(), true); $this->getLevel()->setBlock($b, $ev->getNewState(), true);
} }
@ -83,7 +83,7 @@ class Sugarcane extends Flowable{
if($this->getSide(0)->getID() !== self::SUGARCANE_BLOCK){ if($this->getSide(0)->getID() !== self::SUGARCANE_BLOCK){
if($this->meta === 0x0F){ if($this->meta === 0x0F){
for($y = 1; $y < 3; ++$y){ for($y = 1; $y < 3; ++$y){
$b = $this->getLevel()->getBlock(new Vector3($this->x, $this->y + $y, $this->z)); $b = $this->getLevel()->getBlock(Vector3::createVector($this->x, $this->y + $y, $this->z));
if($b->getID() === self::AIR){ if($b->getID() === self::AIR){
$this->getLevel()->setBlock($b, new Sugarcane(), true); $this->getLevel()->setBlock($b, new Sugarcane(), true);
break; break;

View File

@ -21,7 +21,7 @@
namespace pocketmine\block; namespace pocketmine\block;
use pocketmine\entity\PrimedTNT; use pocketmine\entity\Entity;
use pocketmine\item\Item; use pocketmine\item\Item;
use pocketmine\nbt\tag\Byte; use pocketmine\nbt\tag\Byte;
use pocketmine\nbt\tag\Compound; use pocketmine\nbt\tag\Compound;
@ -44,7 +44,7 @@ class TNT extends Solid{
$this->getLevel()->setBlock($this, new Air(), true); $this->getLevel()->setBlock($this, new Air(), true);
$mot = (new Random())->nextSignedFloat() * M_PI * 2; $mot = (new Random())->nextSignedFloat() * M_PI * 2;
$tnt = new PrimedTNT($this->getLevel()->getChunk($this->x >> 4, $this->z >> 4), new Compound("", [ $tnt = Entity::createEntity("PrimedTNT", $this->getLevel()->getChunk($this->x >> 4, $this->z >> 4), new Compound("", [
"Pos" => new Enum("Pos", [ "Pos" => new Enum("Pos", [
new Double("", $this->x + 0.5), new Double("", $this->x + 0.5),
new Double("", $this->y), new Double("", $this->y),

View File

@ -29,10 +29,7 @@ abstract class Thin extends Transparent{
public $isFullBlock = false; public $isFullBlock = false;
public $isSolid = false; public $isSolid = false;
public function getBoundingBox(){ protected function recalculateBoundingBox(){
if($this->boundingBox !== null){
return $this->boundingBox;
}
$f = 0.4375; $f = 0.4375;
$f1 = 0.5625; $f1 = 0.5625;
@ -66,7 +63,7 @@ abstract class Thin extends Transparent{
$f3 = 1; $f3 = 1;
} }
return $this->boundingBox = new AxisAlignedBB( return AxisAlignedBB::getBoundingBoxFromPool(
$this->x + $f, $this->x + $f,
$this->y, $this->y,
$this->z + $f2, $this->z + $f2,

View File

@ -37,19 +37,14 @@ class Trapdoor extends Transparent{
$this->hardness = 15; $this->hardness = 15;
} }
public function getBoundingBox(){ protected function recalculateBoundingBox(){
if($this->boundingBox !== null){
return $this->boundingBox;
}
$damage = $this->getDamage(); $damage = $this->getDamage();
$f = 0.1875; $f = 0.1875;
$bb = null;
if(($damage & 0x08) > 0){ if(($damage & 0x08) > 0){
$bb = new AxisAlignedBB( $bb = AxisAlignedBB::getBoundingBoxFromPool(
$this->x, $this->x,
$this->y + 1 - $f, $this->y + 1 - $f,
$this->z, $this->z,
@ -58,7 +53,7 @@ class Trapdoor extends Transparent{
$this->z + 1 $this->z + 1
); );
}else{ }else{
$bb = new AxisAlignedBB( $bb = AxisAlignedBB::getBoundingBoxFromPool(
$this->x, $this->x,
$this->y, $this->y,
$this->z, $this->z,
@ -70,7 +65,7 @@ class Trapdoor extends Transparent{
if(($damage & 0x04) > 0){ if(($damage & 0x04) > 0){
if(($damage & 0x03) === 0){ if(($damage & 0x03) === 0){
$bb = new AxisAlignedBB( $bb->setBounds(
$this->x, $this->x,
$this->y, $this->y,
$this->z + 1 - $f, $this->z + 1 - $f,
@ -79,7 +74,7 @@ class Trapdoor extends Transparent{
$this->z + 1 $this->z + 1
); );
}elseif(($damage & 0x03) === 1){ }elseif(($damage & 0x03) === 1){
$bb = new AxisAlignedBB( $bb->setBounds(
$this->x, $this->x,
$this->y, $this->y,
$this->z, $this->z,
@ -88,7 +83,7 @@ class Trapdoor extends Transparent{
$this->z + $f $this->z + $f
); );
}if(($damage & 0x03) === 2){ }if(($damage & 0x03) === 2){
$bb = new AxisAlignedBB( $bb->setBounds(
$this->x + 1 - $f, $this->x + 1 - $f,
$this->y, $this->y,
$this->z, $this->z,
@ -97,7 +92,7 @@ class Trapdoor extends Transparent{
$this->z + 1 $this->z + 1
); );
}if(($damage & 0x03) === 3){ }if(($damage & 0x03) === 3){
$bb = new AxisAlignedBB( $bb->setBounds(
$this->x, $this->x,
$this->y, $this->y,
$this->z, $this->z,
@ -108,7 +103,7 @@ class Trapdoor extends Transparent{
} }
} }
return $this->boundingBox = $bb; return $bb;
} }
public function place(Item $item, Block $block, Block $target, $face, $fx, $fy, $fz, Player $player = null){ public function place(Item $item, Block $block, Block $target, $face, $fx, $fy, $fz, Player $player = null){

View File

@ -43,10 +43,7 @@ class Vine extends Transparent{
$entity->fallDistance = 0; $entity->fallDistance = 0;
} }
public function getBoundingBox(){ protected function recalculateBoundingBox(){
if($this->boundingBox !== null){
return $this->boundingBox;
}
$f1 = 1; $f1 = 1;
$f2 = 1; $f2 = 1;
@ -96,7 +93,7 @@ class Vine extends Transparent{
$f6 = 1; $f6 = 1;
} }
return $this->boundingBox = new AxisAlignedBB( return AxisAlignedBB::getBoundingBoxFromPool(
$this->x + $f1, $this->x + $f1,
$this->y + $f2, $this->y + $f2,
$this->z + $f3, $this->z + $f3,

View File

@ -36,6 +36,10 @@ class Water extends Liquid{
if($entity->fireTicks > 0){ if($entity->fireTicks > 0){
$entity->extinguish(); $entity->extinguish();
} }
if($entity instanceof Player){
$entity->onGround = true;
}
} }
public function place(Item $item, Block $block, Block $target, $face, $fx, $fy, $fz, Player $player = null){ public function place(Item $item, Block $block, Block $target, $face, $fx, $fy, $fz, Player $player = null){

View File

@ -22,8 +22,6 @@
namespace pocketmine\block; namespace pocketmine\block;
use pocketmine\item\Item; use pocketmine\item\Item;
use pocketmine\level\Level;
use pocketmine\Player;
class Wheat extends Crops{ class Wheat extends Crops{
public function __construct($meta = 0){ public function __construct($meta = 0){

View File

@ -45,13 +45,10 @@ class WoodSlab extends Transparent{
$this->hardness = 15; $this->hardness = 15;
} }
public function getBoundingBox(){ protected function recalculateBoundingBox(){
if($this->boundingBox !== null){
return $this->boundingBox;
}
if(($this->meta & 0x08) > 0){ if(($this->meta & 0x08) > 0){
return $this->boundingBox = new AxisAlignedBB( return AxisAlignedBB::getBoundingBoxFromPool(
$this->x, $this->x,
$this->y + 0.5, $this->y + 0.5,
$this->z, $this->z,
@ -60,7 +57,7 @@ class WoodSlab extends Transparent{
$this->z + 1 $this->z + 1
); );
}else{ }else{
return $this->boundingBox = new AxisAlignedBB( return AxisAlignedBB::getBoundingBoxFromPool(
$this->x, $this->x,
$this->y, $this->y,
$this->z, $this->z,

View File

@ -24,7 +24,6 @@ namespace pocketmine\command\defaults;
use pocketmine\command\CommandSender; use pocketmine\command\CommandSender;
use pocketmine\event\entity\EntityDamageEvent; use pocketmine\event\entity\EntityDamageEvent;
use pocketmine\Player; use pocketmine\Player;
use pocketmine\Server;
use pocketmine\utils\TextFormat; use pocketmine\utils\TextFormat;
class KillCommand extends VanillaCommand{ class KillCommand extends VanillaCommand{
@ -45,7 +44,7 @@ class KillCommand extends VanillaCommand{
} }
if($sender instanceof Player){ if($sender instanceof Player){
$sender->getServer()->getPluginManager()->callEvent($ev = new EntityDamageEvent($sender, EntityDamageEvent::CAUSE_SUICIDE, 1000)); $sender->getServer()->getPluginManager()->callEvent($ev = EntityDamageEvent::createEvent($sender, EntityDamageEvent::CAUSE_SUICIDE, 1000));
if($ev->isCancelled()){ if($ev->isCancelled()){
return true; return true;

View File

@ -46,7 +46,8 @@ class SetWorldSpawnCommand extends VanillaCommand{
if(count($args) === 0){ if(count($args) === 0){
if($sender instanceof Player){ if($sender instanceof Player){
$level = $sender->getLevel(); $level = $sender->getLevel();
$pos = $sender->round(); $pos = Vector3::cloneVector($sender);
$pos = $pos->round();
}else{ }else{
$sender->sendMessage(TextFormat::RED . "You can only perform this command as a player"); $sender->sendMessage(TextFormat::RED . "You can only perform this command as a player");

View File

@ -70,14 +70,14 @@ class SpawnpointCommand extends VanillaCommand{
$x = (int) $this->getRelativeDouble($pos->x, $sender, $args[1]); $x = (int) $this->getRelativeDouble($pos->x, $sender, $args[1]);
$y = $this->getRelativeDouble($pos->y, $sender, $args[2], 0, 128); $y = $this->getRelativeDouble($pos->y, $sender, $args[2], 0, 128);
$z = $this->getRelativeDouble($pos->z, $sender, $args[3]); $z = $this->getRelativeDouble($pos->z, $sender, $args[3]);
$target->setSpawn(new Position($x, $y, $z, $level)); $target->setSpawn(Position::createPosition($x, $y, $z, $level));
Command::broadcastCommandMessage($sender, "Set " . $target->getDisplayName() . "'s spawnpoint to " . $x . ", " . $y . ", " . $z); Command::broadcastCommandMessage($sender, "Set " . $target->getDisplayName() . "'s spawnpoint to " . $x . ", " . $y . ", " . $z);
return true; return true;
} }
}elseif(count($args) <= 1){ }elseif(count($args) <= 1){
if($sender instanceof Player){ if($sender instanceof Player){
$pos = new Position((int) $sender->x, (int) $sender->y, (int) $sender->z, $sender->getLevel()); $pos = Position::createPosition((int) $sender->x, (int) $sender->y, (int) $sender->z, $sender->getLevel());
$target->setSpawn($pos); $target->setSpawn($pos);
Command::broadcastCommandMessage($sender, "Set " . $target->getDisplayName() . "'s spawnpoint to " . $pos->x . ", " . $pos->y . ", " . $pos->z); Command::broadcastCommandMessage($sender, "Set " . $target->getDisplayName() . "'s spawnpoint to " . $pos->x . ", " . $pos->y . ", " . $pos->z);

View File

@ -88,7 +88,7 @@ class TeleportCommand extends VanillaCommand{
} }
if(count($args) < 3){ if(count($args) < 3){
$pos = new Position($target->x, $target->y, $target->z, $target->getLevel()); $pos = Position::clonePosition($target);
$origin->teleport($pos); $origin->teleport($pos);
Command::broadcastCommandMessage($sender, "Teleported " . $origin->getDisplayName() . " to " . $target->getDisplayName()); Command::broadcastCommandMessage($sender, "Teleported " . $origin->getDisplayName() . " to " . $target->getDisplayName());
@ -98,7 +98,7 @@ class TeleportCommand extends VanillaCommand{
$x = $this->getRelativeDouble($target->x, $sender, $args[$pos++]); $x = $this->getRelativeDouble($target->x, $sender, $args[$pos++]);
$y = $this->getRelativeDouble($target->y, $sender, $args[$pos++], 0, 128); $y = $this->getRelativeDouble($target->y, $sender, $args[$pos++], 0, 128);
$z = $this->getRelativeDouble($target->z, $sender, $args[$pos]); $z = $this->getRelativeDouble($target->z, $sender, $args[$pos]);
$target->teleport(new Vector3($x, $y, $z)); $target->teleport(Vector3::createVector($x, $y, $z));
Command::broadcastCommandMessage($sender, "Teleported " . $target->getDisplayName() . " to " . round($x, 2) . ", " . round($y, 2) . ", " . round($z, 2)); Command::broadcastCommandMessage($sender, "Teleported " . $target->getDisplayName() . " to " . round($x, 2) . ", " . round($y, 2) . ", " . round($z, 2));
return true; return true;

View File

@ -21,17 +21,8 @@
namespace pocketmine\entity; namespace pocketmine\entity;
use pocketmine\event\entity\EntityCombustByEntityEvent;
use pocketmine\event\entity\EntityDamageByEntityEvent;
use pocketmine\event\entity\EntityDamageEvent;
use pocketmine\event\entity\EntityRegainHealthEvent;
use pocketmine\event\entity\ProjectileHitEvent;
use pocketmine\level\format\FullChunk; use pocketmine\level\format\FullChunk;
use pocketmine\level\MovingObjectPosition;
use pocketmine\math\Vector3;
use pocketmine\nbt\tag\Compound; use pocketmine\nbt\tag\Compound;
use pocketmine\nbt\tag\Short;
use pocketmine\nbt\tag\String; use pocketmine\nbt\tag\String;
use pocketmine\network\protocol\AddEntityPacket; use pocketmine\network\protocol\AddEntityPacket;
use pocketmine\network\protocol\SetEntityMotionPacket; use pocketmine\network\protocol\SetEntityMotionPacket;
@ -44,13 +35,10 @@ class Arrow extends Projectile{
public $length = 0.5; public $length = 0.5;
public $height = 0.5; public $height = 0.5;
/** @var Entity */
public $shootingEntity = null;
protected $gravity = 0.05; protected $gravity = 0.05;
protected $drag = 0.01; protected $drag = 0.01;
private $damage = 6; protected $damage = 6;
public function __construct(FullChunk $chunk, Compound $nbt, Entity $shootingEntity = null){ public function __construct(FullChunk $chunk, Compound $nbt, Entity $shootingEntity = null){
$this->shootingEntity = $shootingEntity; $this->shootingEntity = $shootingEntity;
@ -59,11 +47,7 @@ class Arrow extends Projectile{
protected function initEntity(){ protected function initEntity(){
$this->namedtag->id = new String("id", "Arrow"); $this->namedtag->id = new String("id", "Arrow");
$this->setMaxHealth(1); parent::initEntity();
$this->setHealth(1);
if(isset($this->namedtag->Age)){
$this->age = $this->namedtag["Age"];
}
} }
@ -74,105 +58,11 @@ class Arrow extends Projectile{
$this->timings->startTiming(); $this->timings->startTiming();
$tickDiff = max(1, $currentTick - $this->lastUpdate); $hasUpdate = parent::onUpdate($currentTick);
$this->lastUpdate = $currentTick;
$hasUpdate = $this->entityBaseTick($tickDiff);
if(!$this->dead){
$movingObjectPosition = null;
$this->motionY -= $this->gravity;
$this->keepMovement = $this->checkObstruction($this->x, ($this->boundingBox->minY + $this->boundingBox->maxY) / 2, $this->z);
$moveVector = new Vector3($this->x + $this->motionX, $this->y + $this->motionY, $this->z + $this->motionZ);
$list = $this->getLevel()->getCollidingEntities($this->boundingBox->addCoord($this->motionX, $this->motionY, $this->motionZ)->expand(1, 1, 1), $this);
$nearDistance = PHP_INT_MAX;
$nearEntity = null;
foreach($list as $entity){
if(/*!$entity->canCollideWith($this) or */
($entity === $this->shootingEntity and $this->ticksLived < 5)
){
continue;
}
$axisalignedbb = $entity->boundingBox->grow(0.3, 0.3, 0.3);
$ob = $axisalignedbb->calculateIntercept($this, $moveVector);
if($ob === null){
continue;
}
$distance = $this->distance($ob->hitVector);
if($distance < $nearDistance){
$nearDistance = $distance;
$nearEntity = $entity;
}
}
if($nearEntity !== null){
$movingObjectPosition = MovingObjectPosition::fromEntity($nearEntity);
}
if($movingObjectPosition !== null){
if($movingObjectPosition->entityHit !== null){
$this->server->getPluginManager()->callEvent(new ProjectileHitEvent($this));
$motion = sqrt($this->motionX ** 2 + $this->motionY ** 2 + $this->motionZ ** 2);
$damage = ceil($motion * $this->damage);
$ev = new EntityDamageByEntityEvent($this->shootingEntity === null ? $this : $this->shootingEntity, $movingObjectPosition->entityHit, EntityDamageEvent::CAUSE_PROJECTILE, $damage);
$this->server->getPluginManager()->callEvent($ev);
if(!$ev->isCancelled()){
$movingObjectPosition->entityHit->attack($ev->getFinalDamage(), $ev);
}
if($this->fireTicks > 0){
$ev = new EntityCombustByEntityEvent($this, $movingObjectPosition->entityHit, 5);
$this->server->getPluginManager()->callEvent($ev);
if(!$ev->isCancelled()){
$movingObjectPosition->entityHit->setOnFire($ev->getDuration());
}
}
$this->kill();
return true;
}
}
$this->move($this->motionX, $this->motionY, $this->motionZ);
if($this->onGround and ($this->motionX != 0 or $this->motionY != 0 or $this->motionZ != 0)){
$this->motionX = 0;
$this->motionY = 0;
$this->motionZ = 0;
$this->server->getPluginManager()->callEvent(new ProjectileHitEvent($this));
}
if(!$this->onGround or $this->motionX != 0 or $this->motionY != 0 or $this->motionZ != 0){
$f = sqrt(($this->motionX ** 2) + ($this->motionZ ** 2));
$this->yaw = (atan2($this->motionX, $this->motionZ) * 180 / M_PI);
$this->pitch = (atan2($this->motionY, $f) * 180 / M_PI);
$hasUpdate = true;
}
if($this->age > 1200){
$this->kill();
$hasUpdate = true;
}
$this->updateMovement();
if($this->age > 1200){
$this->kill();
$hasUpdate = true;
} }
$this->timings->stopTiming(); $this->timings->stopTiming();
@ -180,36 +70,8 @@ class Arrow extends Projectile{
return $hasUpdate; return $hasUpdate;
} }
public function attack($damage, $source = EntityDamageEvent::CAUSE_MAGIC){
}
public function heal($amount, $source = EntityRegainHealthEvent::CAUSE_MAGIC){
}
public function saveNBT(){
parent::saveNBT();
$this->namedtag->Age = new Short("Age", $this->age);
}
public function getData(){
$flags = 0;
$flags |= $this->fireTicks > 0 ? 1 : 0;
return [
0 => ["type" => 0, "value" => $flags],
1 => ["type" => 1, "value" => $this->airTicks],
16 => ["type" => 0, "value" => 0] //Is critical
];
}
public function canCollideWith(Entity $entity){
return $entity instanceof Living and !$this->onGround;
}
public function spawnTo(Player $player){ public function spawnTo(Player $player){
$pk = new AddEntityPacket(); $pk = AddEntityPacket::getFromPool();
$pk->type = Arrow::NETWORK_ID; $pk->type = Arrow::NETWORK_ID;
$pk->eid = $this->getID(); $pk->eid = $this->getID();
$pk->x = $this->x; $pk->x = $this->x;
@ -218,7 +80,7 @@ class Arrow extends Projectile{
$pk->did = 0; //TODO: send motion here $pk->did = 0; //TODO: send motion here
$player->dataPacket($pk); $player->dataPacket($pk);
$pk = new SetEntityMotionPacket(); $pk = SetEntityMotionPacket::getFromPool();
$pk->entities = [ $pk->entities = [
[$this->getID(), $this->motionX, $this->motionY, $this->motionZ] [$this->getID(), $this->motionX, $this->motionY, $this->motionZ]
]; ];

View File

@ -40,7 +40,7 @@ use pocketmine\level\Location;
use pocketmine\level\Position; use pocketmine\level\Position;
use pocketmine\math\AxisAlignedBB; use pocketmine\math\AxisAlignedBB;
use pocketmine\math\Math; use pocketmine\math\Math;
use pocketmine\math\Vector3 as Vector3; use pocketmine\math\Vector3;
use pocketmine\metadata\Metadatable; use pocketmine\metadata\Metadatable;
use pocketmine\metadata\MetadataValue; use pocketmine\metadata\MetadataValue;
use pocketmine\nbt\tag\Byte; use pocketmine\nbt\tag\Byte;
@ -59,12 +59,16 @@ use pocketmine\network\protocol\SetTimePacket;
use pocketmine\Player; use pocketmine\Player;
use pocketmine\plugin\Plugin; use pocketmine\plugin\Plugin;
use pocketmine\Server; use pocketmine\Server;
use pocketmine\utils\ChunkException;
abstract class Entity extends Location implements Metadatable{ abstract class Entity extends Location implements Metadatable{
const NETWORK_ID = -1; const NETWORK_ID = -1;
public static $entityCount = 1; public static $entityCount = 1;
/** @var Entity[] */
private static $knownEntities = [];
/** /**
* @var Player[] * @var Player[]
@ -155,7 +159,7 @@ abstract class Entity extends Location implements Metadatable{
public function __construct(FullChunk $chunk, Compound $nbt){ public function __construct(FullChunk $chunk, Compound $nbt){
if($chunk === null or $chunk->getProvider() === null){ if($chunk === null or $chunk->getProvider() === null){
throw new \Exception("Invalid garbage Chunk given to Entity"); throw new ChunkException("Invalid garbage Chunk given to Entity");
} }
$this->timings = Timings::getEntityTimings($this); $this->timings = Timings::getEntityTimings($this);
@ -173,7 +177,7 @@ abstract class Entity extends Location implements Metadatable{
$this->boundingBox = new AxisAlignedBB(0, 0, 0, 0, 0, 0); $this->boundingBox = new AxisAlignedBB(0, 0, 0, 0, 0, 0);
$this->setPositionAndRotation( $this->setPositionAndRotation(
new Vector3( Vector3::createVector(
$this->namedtag["Pos"][0], $this->namedtag["Pos"][0],
$this->namedtag["Pos"][1], $this->namedtag["Pos"][1],
$this->namedtag["Pos"][2] $this->namedtag["Pos"][2]
@ -182,7 +186,7 @@ abstract class Entity extends Location implements Metadatable{
$this->namedtag->Rotation[1], $this->namedtag->Rotation[1],
true true
); );
$this->setMotion(new Vector3($this->namedtag["Motion"][0], $this->namedtag["Motion"][1], $this->namedtag["Motion"][2])); $this->setMotion(Vector3::createVector($this->namedtag["Motion"][0], $this->namedtag["Motion"][1], $this->namedtag["Motion"][2]));
if(!isset($this->namedtag->FallDistance)){ if(!isset($this->namedtag->FallDistance)){
$this->namedtag->FallDistance = new Float("FallDistance", 0); $this->namedtag->FallDistance = new Float("FallDistance", 0);
@ -213,12 +217,45 @@ abstract class Entity extends Location implements Metadatable{
$this->level->addEntity($this); $this->level->addEntity($this);
$this->initEntity(); $this->initEntity();
$this->lastUpdate = $this->server->getTick(); $this->lastUpdate = $this->server->getTick();
$this->server->getPluginManager()->callEvent(new EntitySpawnEvent($this)); $this->server->getPluginManager()->callEvent(EntitySpawnEvent::createEvent($this));
$this->scheduleUpdate(); $this->scheduleUpdate();
} }
/**
* @param int|string $type
* @param FullChunk $chunk
* @param Compound $nbt
* @param $args
*
* @return Entity
*/
public static function createEntity($type, FullChunk $chunk, Compound $nbt, ...$args){
if(isset(self::$knownEntities[$type])){
$class = self::$knownEntities[$type];
return new $class($chunk, $nbt, ...$args);
}
return null;
}
public static function registerEntity($className, $force = false){
$class = new \ReflectionClass($className);
if(is_a($className, Entity::class, true) and !$class->isAbstract()){
if($className::NETWORK_ID !== -1){
self::$knownEntities[$className::NETWORK_ID] = $className;
}elseif(!$force){
return false;
}
self::$knownEntities[$class->getShortName()] = $className;
return true;
}
return false;
}
public function saveNBT(){ public function saveNBT(){
$this->namedtag->Pos = new Enum("Pos", [ $this->namedtag->Pos = new Enum("Pos", [
new Double(0, $this->x), new Double(0, $this->x),
@ -270,7 +307,7 @@ abstract class Entity extends Location implements Metadatable{
$player = [$player]; $player = [$player];
} }
$pk = new SetEntityDataPacket(); $pk = SetEntityDataPacket::getFromPool();
$pk->eid = $this->id; $pk->eid = $this->id;
$pk->metadata = $this->getData(); $pk->metadata = $this->getData();
$pk->encode(); $pk->encode();
@ -278,7 +315,7 @@ abstract class Entity extends Location implements Metadatable{
foreach($player as $p){ foreach($player as $p){
if($p === $this){ if($p === $this){
/** @var Player $p */ /** @var Player $p */
$pk2 = new SetEntityDataPacket(); $pk2 = SetEntityDataPacket::getFromPool();
$pk2->eid = 0; $pk2->eid = 0;
$pk2->metadata = $this->getData(); $pk2->metadata = $this->getData();
$p->dataPacket($pk2); $p->dataPacket($pk2);
@ -293,7 +330,7 @@ abstract class Entity extends Location implements Metadatable{
*/ */
public function despawnFrom(Player $player){ public function despawnFrom(Player $player){
if(isset($this->hasSpawned[$player->getID()])){ if(isset($this->hasSpawned[$player->getID()])){
$pk = new RemoveEntityPacket; $pk = RemoveEntityPacket::getFromPool();
$pk->eid = $this->id; $pk->eid = $this->id;
$player->dataPacket($pk); $player->dataPacket($pk);
unset($this->hasSpawned[$player->getID()]); unset($this->hasSpawned[$player->getID()]);
@ -347,7 +384,7 @@ abstract class Entity extends Location implements Metadatable{
* @param int|EntityDamageEvent $type * @param int|EntityDamageEvent $type
*/ */
public function setLastDamageCause($type){ public function setLastDamageCause($type){
$this->lastDamageCause = $type; $this->lastDamageCause = $type instanceof EntityDamageEvent ? clone $type : $type;
} }
/** /**
@ -387,15 +424,17 @@ abstract class Entity extends Location implements Metadatable{
$list = $this->level->getCollisionBlocks($this->boundingBox); $list = $this->level->getCollisionBlocks($this->boundingBox);
if(count($list) === 0 and !$this->level->isFullBlock(new Vector3($i, $j, $k))){ $v = Vector3::createVector($i, $j, $k);
if(count($list) === 0 and !$this->level->isFullBlock($v->setComponents($i, $j, $k))){
return false; return false;
}else{ }else{
$flag = !$this->level->isFullBlock(new Vector3($i - 1, $j, $k)); $flag = !$this->level->isFullBlock($v->setComponents($i - 1, $j, $k));
$flag1 = !$this->level->isFullBlock(new Vector3($i + 1, $j, $k)); $flag1 = !$this->level->isFullBlock($v->setComponents($i + 1, $j, $k));
//$flag2 = !$this->level->isFullBlock(new Vector3($i, $j - 1, $k)); //$flag2 = !$this->level->isFullBlock($v->setComponents($i, $j - 1, $k));
$flag3 = !$this->level->isFullBlock(new Vector3($i, $j + 1, $k)); $flag3 = !$this->level->isFullBlock($v->setComponents($i, $j + 1, $k));
$flag4 = !$this->level->isFullBlock(new Vector3($i, $j, $k - 1)); $flag4 = !$this->level->isFullBlock($v->setComponents($i, $j, $k - 1));
$flag5 = !$this->level->isFullBlock(new Vector3($i, $j, $k + 1)); $flag5 = !$this->level->isFullBlock($v->setComponents($i, $j, $k + 1));
$direction = 3; //UP! $direction = 3; //UP!
$limit = 9999; $limit = 9999;
@ -483,10 +522,8 @@ abstract class Entity extends Location implements Metadatable{
$this->checkBlockCollision(); $this->checkBlockCollision();
if($this->y < 0 and $this->dead !== true){ if($this->y < 0 and $this->dead !== true){
$this->server->getPluginManager()->callEvent($ev = new EntityDamageEvent($this, EntityDamageEvent::CAUSE_VOID, 10)); $ev = EntityDamageEvent::createEvent($this, EntityDamageEvent::CAUSE_VOID, 10);
if(!$ev->isCancelled()){ $this->attack($ev->getFinalDamage(), $ev);
$this->attack($ev->getFinalDamage(), $ev);
}
$hasUpdate = true; $hasUpdate = true;
} }
@ -498,11 +535,8 @@ abstract class Entity extends Location implements Metadatable{
} }
}else{ }else{
if(($this->fireTicks % 20) === 0 or $tickDiff > 20){ if(($this->fireTicks % 20) === 0 or $tickDiff > 20){
$ev = new EntityDamageEvent($this, EntityDamageEvent::CAUSE_FIRE_TICK, 1); $ev = EntityDamageEvent::createEvent($this, EntityDamageEvent::CAUSE_FIRE_TICK, 1);
$this->server->getPluginManager()->callEvent($ev); $this->attack($ev->getFinalDamage(), $ev);
if(!$ev->isCancelled()){
$this->attack($ev->getFinalDamage(), $ev);
}
} }
$this->fireTicks -= $tickDiff; $this->fireTicks -= $tickDiff;
} }
@ -532,7 +566,7 @@ abstract class Entity extends Location implements Metadatable{
$this->lastPitch = $this->pitch; $this->lastPitch = $this->pitch;
if($this instanceof Human){ if($this instanceof Human){
$pk = new MovePlayerPacket; $pk = MovePlayerPacket::getFromPool();
$pk->eid = $this->id; $pk->eid = $this->id;
$pk->x = $this->x; $pk->x = $this->x;
$pk->y = $this->y; $pk->y = $this->y;
@ -542,7 +576,7 @@ abstract class Entity extends Location implements Metadatable{
$pk->bodyYaw = $this->yaw; $pk->bodyYaw = $this->yaw;
}else{ }else{
//TODO: add to move list //TODO: add to move list
$pk = new MoveEntityPacket(); $pk = MoveEntityPacket::getFromPool();
$pk->entities = [ $pk->entities = [
[$this->id, $this->x, $this->y + $this->getEyeHeight(), $this->z, $this->yaw, $this->pitch] [$this->id, $this->x, $this->y + $this->getEyeHeight(), $this->z, $this->yaw, $this->pitch]
]; ];
@ -556,7 +590,7 @@ abstract class Entity extends Location implements Metadatable{
$this->lastMotionY = $this->motionY; $this->lastMotionY = $this->motionY;
$this->lastMotionZ = $this->motionZ; $this->lastMotionZ = $this->motionZ;
$pk = new SetEntityMotionPacket; $pk = SetEntityMotionPacket::getFromPool();
$pk->entities = [ $pk->entities = [
[$this->getID(), $this->motionX, $this->motionY, $this->motionZ] [$this->getID(), $this->motionX, $this->motionY, $this->motionZ]
]; ];
@ -583,7 +617,7 @@ abstract class Entity extends Location implements Metadatable{
$x = -$xz * sin(deg2rad($this->yaw)); $x = -$xz * sin(deg2rad($this->yaw));
$z = $xz * cos(deg2rad($this->yaw)); $z = $xz * cos(deg2rad($this->yaw));
return new Vector3($x, $y, $z); return Vector3::createVector($x, $y, $z);
} }
public function onUpdate($currentTick){ public function onUpdate($currentTick){
@ -675,10 +709,7 @@ abstract class Entity extends Location implements Metadatable{
public function fall($fallDistance){ public function fall($fallDistance){
$damage = floor($fallDistance - 3); $damage = floor($fallDistance - 3);
if($damage > 0){ if($damage > 0){
$this->server->getPluginManager()->callEvent($ev = new EntityDamageEvent($this, EntityDamageEvent::CAUSE_FALL, $damage)); $ev = EntityDamageEvent::createEvent($this, EntityDamageEvent::CAUSE_FALL, $damage);
if($ev->isCancelled()){
return;
}
$this->attack($ev->getFinalDamage(), $ev); $this->attack($ev->getFinalDamage(), $ev);
} }
} }
@ -701,7 +732,7 @@ abstract class Entity extends Location implements Metadatable{
protected function switchLevel(Level $targetLevel){ protected function switchLevel(Level $targetLevel){
if($this->isValid()){ if($this->isValid()){
$this->server->getPluginManager()->callEvent($ev = new EntityLevelChangeEvent($this, $this->level, $targetLevel)); $this->server->getPluginManager()->callEvent($ev = EntityLevelChangeEvent::createEvent($this, $this->level, $targetLevel));
if($ev->isCancelled()){ if($ev->isCancelled()){
return false; return false;
} }
@ -726,7 +757,7 @@ abstract class Entity extends Location implements Metadatable{
$this->level->addEntity($this); $this->level->addEntity($this);
if($this instanceof Player){ if($this instanceof Player){
$this->usedChunks = []; $this->usedChunks = [];
$pk = new SetTimePacket(); $pk = SetTimePacket::getFromPool();
$pk->time = $this->level->getTime(); $pk->time = $this->level->getTime();
$pk->started = $this->level->stopTime == false; $pk->started = $this->level->stopTime == false;
$this->dataPacket($pk); $this->dataPacket($pk);
@ -737,7 +768,7 @@ abstract class Entity extends Location implements Metadatable{
} }
public function getPosition(){ public function getPosition(){
return new Position($this->x, $this->y, $this->z, $this->level); return Position::createPosition($this->x, $this->y, $this->z, $this->level);
} }
public function getLocation(){ public function getLocation(){
@ -745,10 +776,10 @@ abstract class Entity extends Location implements Metadatable{
} }
public function isInsideOfWater(){ public function isInsideOfWater(){
$block = $this->level->getBlock($pos = (new Vector3($this->x, $y = ($this->y + $this->getEyeHeight()), $this->z))->floor()); $block = $this->level->getBlock(Vector3::createVector(Math::floorFloat($this->x), Math::floorFloat($y = ($this->y + $this->getEyeHeight())), Math::floorFloat($this->z)));
if($block instanceof Water){ if($block instanceof Water){
$f = ($pos->y + 1) - ($block->getFluidHeightPercent() - 0.1111111); $f = ($block->y + 1) - ($block->getFluidHeightPercent() - 0.1111111);
return $y < $f; return $y < $f;
} }
@ -756,7 +787,7 @@ abstract class Entity extends Location implements Metadatable{
} }
public function isInsideOfSolid(){ public function isInsideOfSolid(){
$block = $this->level->getBlock($pos = (new Vector3($this->x, $y = ($this->y + $this->getEyeHeight()), $this->z))->floor()); $block = $this->level->getBlock(Vector3::createVector(Math::floorFloat($this->x), Math::floorFloat($y = ($this->y + $this->getEyeHeight())), Math::floorFloat($this->z)));
$bb = $block->getBoundingBox(); $bb = $block->getBoundingBox();
@ -779,8 +810,8 @@ abstract class Entity extends Location implements Metadatable{
if($this->keepMovement){ if($this->keepMovement){
$this->boundingBox->offset($dx, $dy, $dz); $this->boundingBox->offset($dx, $dy, $dz);
$pos = new Vector3(($this->boundingBox->minX + $this->boundingBox->maxX) / 2, $this->boundingBox->minY - $this->ySize, ($this->boundingBox->minZ + $this->boundingBox->maxZ) / 2); $this->setPosition(Vector3::createVector(($this->boundingBox->minX + $this->boundingBox->maxX) / 2, $this->boundingBox->minY - $this->ySize, ($this->boundingBox->minZ + $this->boundingBox->maxZ) / 2));
$this->setPosition($pos); $this->onGround = $this instanceof Player ? true : false;
}else{ }else{
Timings::$entityMoveTimer->startTiming(); Timings::$entityMoveTimer->startTiming();
@ -803,7 +834,7 @@ abstract class Entity extends Location implements Metadatable{
$movY = $dy; $movY = $dy;
$movZ = $dz; $movZ = $dz;
$axisalignedbb = clone $this->boundingBox; $axisalignedbb = AxisAlignedBB::cloneBoundingBoxFromPool($this->boundingBox);
/*$sneakFlag = $this->onGround and $this instanceof Player; /*$sneakFlag = $this->onGround and $this instanceof Player;
@ -881,7 +912,7 @@ abstract class Entity extends Location implements Metadatable{
$dy = $this->stepHeight; $dy = $this->stepHeight;
$dz = $movZ; $dz = $movZ;
$axisalignedbb1 = clone $this->boundingBox; $axisalignedbb1 = AxisAlignedBB::cloneBoundingBoxFromPool($this->boundingBox);
$this->boundingBox->setBB($axisalignedbb); $this->boundingBox->setBB($axisalignedbb);
@ -941,7 +972,7 @@ abstract class Entity extends Location implements Metadatable{
} }
$pos = new Vector3( $pos = Vector3::createVector(
($this->boundingBox->minX + $this->boundingBox->maxX) / 2, ($this->boundingBox->minX + $this->boundingBox->maxX) / 2,
$this->boundingBox->minY - $this->ySize, $this->boundingBox->minY - $this->ySize,
($this->boundingBox->minZ + $this->boundingBox->maxZ) / 2 ($this->boundingBox->minZ + $this->boundingBox->maxZ) / 2
@ -956,7 +987,7 @@ abstract class Entity extends Location implements Metadatable{
if($this instanceof Player){ if($this instanceof Player){
if(!$this->onGround or $movY != 0){ if(!$this->onGround or $movY != 0){
$bb = clone $this->boundingBox; $bb = AxisAlignedBB::cloneBoundingBoxFromPool($this->boundingBox);
$bb->maxY = $bb->minY + 1; $bb->maxY = $bb->minY + 1;
if(count($this->level->getCollisionBlocks($bb->expand(0.01, 0.01, 0.01))) > 0){ if(count($this->level->getCollisionBlocks($bb->expand(0.01, 0.01, 0.01))) > 0){
$this->onGround = true; $this->onGround = true;
@ -998,12 +1029,13 @@ abstract class Entity extends Location implements Metadatable{
$maxY = Math::floorFloat($this->boundingBox->maxY - 0.001); $maxY = Math::floorFloat($this->boundingBox->maxY - 0.001);
$maxZ = Math::floorFloat($this->boundingBox->maxZ - 0.001); $maxZ = Math::floorFloat($this->boundingBox->maxZ - 0.001);
$vector = new Vector3(0, 0, 0); $vector = Vector3::createVector(0, 0, 0);
$v = Vector3::createVector(0, 0, 0);
for($z = $minZ; $z <= $maxZ; ++$z){ for($v->z = $minZ; $v->z <= $maxZ; ++$v->z){
for($x = $minX; $x <= $maxX; ++$x){ for($v->x = $minX; $v->x <= $maxX; ++$v->x){
for($y = $minY; $y <= $maxY; ++$y){ for($v->y = $minY; $v->y <= $maxY; ++$v->y){
$block = $this->level->getBlock(new Vector3($x, $y, $z)); $block = $this->level->getBlock($v);
if($block !== null and $block->hasEntityCollision){ if($block !== null and $block->hasEntityCollision){
$block->onEntityCollide($this); $block->onEntityCollide($this);
if(!($this instanceof Player)){ if(!($this instanceof Player)){
@ -1082,12 +1114,12 @@ abstract class Entity extends Location implements Metadatable{
} }
public function getMotion(){ public function getMotion(){
return new Vector3($this->motionX, $this->motionY, $this->motionZ); return Vector3::createVector($this->motionX, $this->motionY, $this->motionZ);
} }
public function setMotion(Vector3 $motion){ public function setMotion(Vector3 $motion){
if(!$this->justCreated){ if(!$this->justCreated){
$this->server->getPluginManager()->callEvent($ev = new EntityMotionEvent($this, $motion)); $this->server->getPluginManager()->callEvent($ev = EntityMotionEvent::createEvent($this, $motion));
if($ev->isCancelled()){ if($ev->isCancelled()){
return false; return false;
} }
@ -1099,7 +1131,7 @@ abstract class Entity extends Location implements Metadatable{
if(!$this->justCreated){ if(!$this->justCreated){
if($this instanceof Player){ if($this instanceof Player){
$pk = new SetEntityMotionPacket; $pk = SetEntityMotionPacket::getFromPool();
$pk->entities = [ $pk->entities = [
[0, $this->motionX, $this->motionY, $this->motionZ] [0, $this->motionX, $this->motionY, $this->motionZ]
]; ];
@ -1138,14 +1170,14 @@ abstract class Entity extends Location implements Metadatable{
} }
$from = Position::fromObject($this, $this->level); $from = Position::fromObject($this, $this->level);
$to = Position::fromObject($pos, $pos instanceof Position ? $pos->getLevel() : $this->level); $to = Position::fromObject($pos, $pos instanceof Position ? $pos->getLevel() : $this->level);
$this->server->getPluginManager()->callEvent($ev = new EntityTeleportEvent($this, $from, $to)); $this->server->getPluginManager()->callEvent($ev = EntityTeleportEvent::createEvent($this, $from, $to));
if($ev->isCancelled()){ if($ev->isCancelled()){
return false; return false;
} }
$this->ySize = 0; $this->ySize = 0;
$pos = $ev->getTo(); $pos = $ev->getTo();
$this->setMotion(new Vector3(0, 0, 0)); $this->setMotion(Vector3::createVector(0, 0, 0));
if($this->setPositionAndRotation($pos, $yaw === null ? $this->yaw : $yaw, $pitch === null ? $this->pitch : $pitch, true) !== false){ if($this->setPositionAndRotation($pos, $yaw === null ? $this->yaw : $yaw, $pitch === null ? $this->pitch : $pitch, true) !== false){
$this->fallDistance = 0; $this->fallDistance = 0;
$this->onGround = true; $this->onGround = true;
@ -1176,7 +1208,7 @@ abstract class Entity extends Location implements Metadatable{
public function close(){ public function close(){
if(!$this->closed){ if(!$this->closed){
$this->server->getPluginManager()->callEvent(new EntityDespawnEvent($this)); $this->server->getPluginManager()->callEvent(EntityDespawnEvent::createEvent($this));
$this->closed = true; $this->closed = true;
unset($this->level->updateEntities[$this->id]); unset($this->level->updateEntities[$this->id]);
if($this->chunk instanceof FullChunk){ if($this->chunk instanceof FullChunk){

View File

@ -26,15 +26,16 @@ use pocketmine\block\Block;
use pocketmine\event\entity\EntityBlockChangeEvent; use pocketmine\event\entity\EntityBlockChangeEvent;
use pocketmine\event\entity\EntityDamageEvent; use pocketmine\event\entity\EntityDamageEvent;
use pocketmine\event\entity\EntityRegainHealthEvent; use pocketmine\event\entity\EntityRegainHealthEvent;
use pocketmine\item\Item; use pocketmine\item\Item as ItemItem;
use pocketmine\math\Vector3;
use pocketmine\nbt\tag\Byte; use pocketmine\nbt\tag\Byte;
use pocketmine\nbt\tag\Int;
use pocketmine\nbt\tag\String; use pocketmine\nbt\tag\String;
use pocketmine\network\protocol\AddEntityPacket; use pocketmine\network\protocol\AddEntityPacket;
use pocketmine\network\protocol\SetEntityMotionPacket; use pocketmine\network\protocol\SetEntityMotionPacket;
use pocketmine\Player; use pocketmine\Player;
class FallingBlock extends Entity{ class FallingSand extends Entity{
const NETWORK_ID = 66; const NETWORK_ID = 66;
public $width = 0.98; public $width = 0.98;
@ -44,13 +45,21 @@ class FallingBlock extends Entity{
protected $gravity = 0.04; protected $gravity = 0.04;
protected $drag = 0.02; protected $drag = 0.02;
protected $blockId = 0; protected $blockId = 0;
protected $damage;
public $canCollide = false; public $canCollide = false;
protected function initEntity(){ protected function initEntity(){
$this->namedtag->id = new String("id", "FallingSand"); $this->namedtag->id = new String("id", "FallingSand");
if(isset($this->namedtag->Tile)){ if(isset($this->namedtag->TileID)){
$this->blockId = $this->namedtag["TileID"];
}elseif(isset($this->namedtag->Tile)){
$this->blockId = $this->namedtag["Tile"]; $this->blockId = $this->namedtag["Tile"];
$this->namedtag["TileID"] = new Int("TileID", $this->blockId);
}
if(isset($this->namedtag->Data)){
$this->damage = $this->namedtag["Data"];
} }
if($this->blockId === 0){ if($this->blockId === 0){
@ -81,12 +90,13 @@ class FallingBlock extends Entity{
if(!$this->dead){ if(!$this->dead){
if($this->ticksLived === 1){ if($this->ticksLived === 1){
$block = $this->level->getBlock($this->floor()); $pos = Vector3::cloneVector($this);
$block = $this->level->getBlock($pos->floor());
if($block->getID() != $this->blockId){ if($block->getID() != $this->blockId){
$this->kill(); $this->kill();
return true; return true;
} }
$this->level->setBlock($this->floor(), Block::get(0), true); $this->level->setBlock($pos, Block::get(0), true);
} }
@ -100,15 +110,16 @@ class FallingBlock extends Entity{
$this->motionY *= 1 - $this->drag; $this->motionY *= 1 - $this->drag;
$this->motionZ *= $friction; $this->motionZ *= $friction;
$pos = $this->floor(); $pos = Vector3::cloneVector($this);
$pos = $pos->floor();
if($this->onGround){ if($this->onGround){
$this->kill(); $this->kill();
$block = $this->level->getBlock($pos); $block = $this->level->getBlock($pos);
if(!$block->isFullBlock){ if(!$block->isFullBlock){
$this->getLevel()->dropItem($this, Item::get($this->getBlock(), 0, 1)); $this->getLevel()->dropItem($this, ItemItem::get($this->getBlock(), $this->getDamage(), 1));
}else{ }else{
$this->server->getPluginManager()->callEvent($ev = new EntityBlockChangeEvent($this, $block, Block::get($this->getBlock(), 0))); $this->server->getPluginManager()->callEvent($ev = EntityBlockChangeEvent::createEvent($this, $block, Block::get($this->getBlock(), $this->getDamage())));
if(!$ev->isCancelled()){ if(!$ev->isCancelled()){
$this->getLevel()->setBlock($pos, $ev->getTo(), true); $this->getLevel()->setBlock($pos, $ev->getTo(), true);
} }
@ -119,15 +130,19 @@ class FallingBlock extends Entity{
$this->updateMovement(); $this->updateMovement();
} }
return $hasUpdate or !$this->onGround or ($this->motionX == 0 and $this->motionY == 0 and $this->motionZ == 0); return $hasUpdate or !$this->onGround or $this->motionX != 0 or $this->motionY != 0 or $this->motionZ != 0;
} }
public function getBlock(){ public function getBlock(){
return $this->blockId; return $this->blockId;
} }
public function getDamage(){
return $this->damage;
}
public function saveNBT(){ public function saveNBT(){
$this->namedtag->Tile = new Byte("Tile", $this->blockId); $this->namedtag->TileID = new Int("TileID", $this->blockId);
$this->namedtag->Data = new Byte("Data", $this->damage);
} }
public function attack($damage, $source = EntityDamageEvent::CAUSE_MAGIC){ public function attack($damage, $source = EntityDamageEvent::CAUSE_MAGIC){
@ -139,16 +154,16 @@ class FallingBlock extends Entity{
} }
public function spawnTo(Player $player){ public function spawnTo(Player $player){
$pk = new AddEntityPacket; $pk = AddEntityPacket::getFromPool();
$pk->type = FallingBlock::NETWORK_ID; $pk->type = FallingSand::NETWORK_ID;
$pk->eid = $this->getID(); $pk->eid = $this->getID();
$pk->x = $this->x; $pk->x = $this->x;
$pk->y = $this->y; $pk->y = $this->y;
$pk->z = $this->z; $pk->z = $this->z;
$pk->did = -$this->getBlock(); $pk->did = -($this->getBlock() | $this->getDamage() << 0x10);
$player->dataPacket($pk); $player->dataPacket($pk);
$pk = new SetEntityMotionPacket; $pk = SetEntityMotionPacket::getFromPool();
$pk->entities = [ $pk->entities = [
[$this->getID(), $this->motionX, $this->motionY, $this->motionZ] [$this->getID(), $this->motionX, $this->motionY, $this->motionZ]
]; ];
@ -156,4 +171,4 @@ class FallingBlock extends Entity{
parent::spawnTo($player); parent::spawnTo($player);
} }
} }

View File

@ -23,7 +23,7 @@ namespace pocketmine\entity;
use pocketmine\inventory\InventoryHolder; use pocketmine\inventory\InventoryHolder;
use pocketmine\inventory\PlayerInventory; use pocketmine\inventory\PlayerInventory;
use pocketmine\item\Item; use pocketmine\item\Item as ItemItem;
use pocketmine\nbt\NBT; use pocketmine\nbt\NBT;
use pocketmine\nbt\tag\Byte; use pocketmine\nbt\tag\Byte;
use pocketmine\nbt\tag\Compound; use pocketmine\nbt\tag\Compound;
@ -67,9 +67,9 @@ class Human extends Creature implements ProjectileSource, InventoryHolder{
if($item["Slot"] >= 0 and $item["Slot"] < 9){ //Hotbar if($item["Slot"] >= 0 and $item["Slot"] < 9){ //Hotbar
$this->inventory->setHotbarSlotIndex($item["Slot"], isset($item["TrueSlot"]) ? $item["TrueSlot"] : -1); $this->inventory->setHotbarSlotIndex($item["Slot"], isset($item["TrueSlot"]) ? $item["TrueSlot"] : -1);
}elseif($item["Slot"] >= 100 and $item["Slot"] < 104){ //Armor }elseif($item["Slot"] >= 100 and $item["Slot"] < 104){ //Armor
$this->inventory->setItem($this->inventory->getSize() + $item["Slot"] - 100, Item::get($item["id"], $item["Damage"], $item["Count"]), $this); $this->inventory->setItem($this->inventory->getSize() + $item["Slot"] - 100, ItemItem::get($item["id"], $item["Damage"], $item["Count"]), $this);
}else{ }else{
$this->inventory->setItem($item["Slot"] - 9, Item::get($item["id"], $item["Damage"], $item["Count"]), $this); $this->inventory->setItem($item["Slot"] - 9, ItemItem::get($item["id"], $item["Damage"], $item["Count"]), $this);
} }
} }
@ -140,7 +140,7 @@ class Human extends Creature implements ProjectileSource, InventoryHolder{
//Armor //Armor
for($slot = 100; $slot < 104; ++$slot){ for($slot = 100; $slot < 104; ++$slot){
$item = $this->inventory->getItem($this->inventory->getSize() + $slot - 100); $item = $this->inventory->getItem($this->inventory->getSize() + $slot - 100);
if($item instanceof Item and $item->getID() !== Item::AIR){ if($item instanceof ItemItem and $item->getID() !== ItemItem::AIR){
$this->namedtag->Inventory[$slot] = new Compound(false, [ $this->namedtag->Inventory[$slot] = new Compound(false, [
new Byte("Count", $item->getCount()), new Byte("Count", $item->getCount()),
new Short("Damage", $item->getDamage()), new Short("Damage", $item->getDamage()),
@ -156,7 +156,7 @@ class Human extends Creature implements ProjectileSource, InventoryHolder{
if($player !== $this and !isset($this->hasSpawned[$player->getID()])){ if($player !== $this and !isset($this->hasSpawned[$player->getID()])){
$this->hasSpawned[$player->getID()] = $player; $this->hasSpawned[$player->getID()] = $player;
$pk = new AddPlayerPacket; $pk = AddPlayerPacket::getFromPool();
$pk->clientID = 0; $pk->clientID = 0;
if($player->getRemoveFormat()){ if($player->getRemoveFormat()){
$pk->username = TextFormat::clean($this->nameTag); $pk->username = TextFormat::clean($this->nameTag);
@ -174,7 +174,7 @@ class Human extends Creature implements ProjectileSource, InventoryHolder{
$pk->metadata = $this->getData(); $pk->metadata = $this->getData();
$player->dataPacket($pk); $player->dataPacket($pk);
$pk = new SetEntityMotionPacket; $pk = SetEntityMotionPacket::getFromPool();
$pk->entities = [ $pk->entities = [
[$this->getID(), $this->motionX, $this->motionY, $this->motionZ] [$this->getID(), $this->motionX, $this->motionY, $this->motionZ]
]; ];
@ -188,7 +188,7 @@ class Human extends Creature implements ProjectileSource, InventoryHolder{
public function despawnFrom(Player $player){ public function despawnFrom(Player $player){
if(isset($this->hasSpawned[$player->getID()])){ if(isset($this->hasSpawned[$player->getID()])){
$pk = new RemovePlayerPacket; $pk = RemovePlayerPacket::getFromPool();
$pk->eid = $this->id; $pk->eid = $this->id;
$pk->clientID = 0; $pk->clientID = 0;
$player->dataPacket($pk); $player->dataPacket($pk);
@ -208,21 +208,6 @@ class Human extends Creature implements ProjectileSource, InventoryHolder{
17 => ["type" => 6, "value" => [0, 0, 0]], 17 => ["type" => 6, "value" => [0, 0, 0]],
]; ];
/*if($this->class === ENTITY_MOB and $this->type === MOB_SHEEP){
if(!isset($this->data["Sheared"])){
$this->data["Sheared"] = 0;
$this->data["Color"] = mt_rand(0,15);
}
$d[16]["value"] = (($this->data["Sheared"] == 1 ? 1:0) << 4) | ($this->data["Color"] & 0x0F);
}elseif($this->type === OBJECT_PRIMEDTNT){
$d[16]["value"] = (int) max(0, $this->data["fuse"] - (microtime(true) - $this->spawntime) * 20);
}elseif($this->class === ENTITY_PLAYER){
if($this->player->sleeping !== false){
$d[16]["value"] = 2;
$d[17]["value"] = array($this->player->sleeping->x, $this->player->sleeping->y, $this->player->sleeping->z);
}
}*/
return $d; return $d;
} }

View File

@ -25,7 +25,7 @@ use pocketmine\event\entity\EntityDamageEvent;
use pocketmine\event\entity\EntityRegainHealthEvent; use pocketmine\event\entity\EntityRegainHealthEvent;
use pocketmine\event\entity\ItemDespawnEvent; use pocketmine\event\entity\ItemDespawnEvent;
use pocketmine\event\entity\ItemSpawnEvent; use pocketmine\event\entity\ItemSpawnEvent;
use pocketmine\item\Item; use pocketmine\item\Item as ItemItem;
use pocketmine\math\Vector3; use pocketmine\math\Vector3;
use pocketmine\nbt\tag\Byte; use pocketmine\nbt\tag\Byte;
use pocketmine\nbt\tag\Compound; use pocketmine\nbt\tag\Compound;
@ -35,12 +35,13 @@ use pocketmine\network\protocol\AddItemEntityPacket;
use pocketmine\network\protocol\SetEntityMotionPacket; use pocketmine\network\protocol\SetEntityMotionPacket;
use pocketmine\Player; use pocketmine\Player;
class DroppedItem extends Entity{ class Item extends Entity{
const NETWORK_ID = 64;
protected $owner = null; protected $owner = null;
protected $thrower = null; protected $thrower = null;
protected $pickupDelay = 0; protected $pickupDelay = 0;
/** @var Item */ /** @var ItemItem */
protected $item; protected $item;
public $width = 0.25; public $width = 0.25;
@ -67,10 +68,10 @@ class DroppedItem extends Entity{
if(isset($this->namedtag->Thrower)){ if(isset($this->namedtag->Thrower)){
$this->thrower = $this->namedtag["Thrower"]; $this->thrower = $this->namedtag["Thrower"];
} }
$this->item = Item::get($this->namedtag->Item["id"], $this->namedtag->Item["Damage"], $this->namedtag->Item["Count"]); $this->item = ItemItem::get($this->namedtag->Item["id"], $this->namedtag->Item["Damage"], $this->namedtag->Item["Count"]);
$this->server->getPluginManager()->callEvent(new ItemSpawnEvent($this)); $this->server->getPluginManager()->callEvent(ItemSpawnEvent::createEvent($this));
} }
public function onUpdate($currentTick){ public function onUpdate($currentTick){
@ -99,7 +100,7 @@ class DroppedItem extends Entity{
$friction = 1 - $this->drag; $friction = 1 - $this->drag;
if($this->onGround and ($this->motionX != 0 or $this->motionZ != 0)){ if($this->onGround and ($this->motionX != 0 or $this->motionZ != 0)){
$friction = $this->getLevel()->getBlock(new Vector3($this->getFloorX(), $this->getFloorY() - 1, $this->getFloorZ()))->frictionFactor * $friction; $friction = $this->getLevel()->getBlock(Vector3::createVector($this->getFloorX(), $this->getFloorY() - 1, $this->getFloorZ()))->frictionFactor * $friction;
} }
$this->motionX *= $friction; $this->motionX *= $friction;
@ -113,7 +114,7 @@ class DroppedItem extends Entity{
} }
if($this->age > 6000){ if($this->age > 6000){
$this->server->getPluginManager()->callEvent($ev = new ItemDespawnEvent($this)); $this->server->getPluginManager()->callEvent($ev = ItemDespawnEvent::createEvent($this));
if($ev->isCancelled()){ if($ev->isCancelled()){
$this->age = 0; $this->age = 0;
}else{ }else{
@ -130,6 +131,13 @@ class DroppedItem extends Entity{
} }
public function attack($damage, $source = EntityDamageEvent::CAUSE_MAGIC){ public function attack($damage, $source = EntityDamageEvent::CAUSE_MAGIC){
if($source instanceof EntityDamageEvent){
$this->server->getPluginManager()->callEvent($source);
$damage = $source->getFinalDamage();
if($source->isCancelled()){
return;
}
}
$this->setLastDamageCause($source); $this->setLastDamageCause($source);
$this->setHealth($this->getHealth() - $damage); $this->setHealth($this->getHealth() - $damage);
} }
@ -166,7 +174,7 @@ class DroppedItem extends Entity{
} }
/** /**
* @return Item * @return ItemItem
*/ */
public function getItem(){ public function getItem(){
return $this->item; return $this->item;
@ -219,7 +227,7 @@ class DroppedItem extends Entity{
} }
public function spawnTo(Player $player){ public function spawnTo(Player $player){
$pk = new AddItemEntityPacket(); $pk = AddItemEntityPacket::getFromPool();
$pk->eid = $this->getID(); $pk->eid = $this->getID();
$pk->x = $this->x; $pk->x = $this->x;
$pk->y = $this->y; $pk->y = $this->y;
@ -230,7 +238,7 @@ class DroppedItem extends Entity{
$pk->item = $this->getItem(); $pk->item = $this->getItem();
$player->dataPacket($pk); $player->dataPacket($pk);
$pk = new SetEntityMotionPacket; $pk = SetEntityMotionPacket::getFromPool();
$pk->entities = [ $pk->entities = [
[$this->getID(), $this->motionX, $this->motionY, $this->motionZ] [$this->getID(), $this->motionX, $this->motionY, $this->motionZ]
]; ];

View File

@ -28,7 +28,7 @@ use pocketmine\event\entity\EntityDamageEvent;
use pocketmine\event\entity\EntityDeathEvent; use pocketmine\event\entity\EntityDeathEvent;
use pocketmine\event\entity\EntityRegainHealthEvent; use pocketmine\event\entity\EntityRegainHealthEvent;
use pocketmine\event\Timings; use pocketmine\event\Timings;
use pocketmine\item\Item; use pocketmine\item\Item as ItemItem;
use pocketmine\math\Vector3; use pocketmine\math\Vector3;
use pocketmine\nbt\tag\Short; use pocketmine\nbt\tag\Short;
use pocketmine\network\protocol\EntityEventPacket; use pocketmine\network\protocol\EntityEventPacket;
@ -65,18 +65,33 @@ abstract class Living extends Entity implements Damageable{
public function hasLineOfSight(Entity $entity){ public function hasLineOfSight(Entity $entity){
//TODO: head height //TODO: head height
return true; return true;
//return $this->getLevel()->rayTraceBlocks(new Vector3($this->x, $this->y + $this->height, $this->z), new Vector3($entity->x, $entity->y + $entity->height, $entity->z)) === null; //return $this->getLevel()->rayTraceBlocks(Vector3::createVector($this->x, $this->y + $this->height, $this->z), Vector3::createVector($entity->x, $entity->y + $entity->height, $entity->z)) === null;
} }
public function attack($damage, $source = EntityDamageEvent::CAUSE_MAGIC){ public function attack($damage, $source = EntityDamageEvent::CAUSE_MAGIC){
if($this->attackTime > 0){ if($this->attackTime > 0){
$lastCause = $this->getLastDamageCause(); $lastCause = $this->getLastDamageCause();
if($lastCause instanceof EntityDamageEvent and $lastCause->getDamage() >= $damage){ if($lastCause instanceof EntityDamageEvent and $lastCause->getDamage() >= $damage){
if($source instanceof EntityDamageEvent){
$source->setCancelled();
$this->server->getPluginManager()->callEvent($source);
$damage = $source->getFinalDamage();
if($source->isCancelled()){
return;
}
}else{
return;
}
}
}elseif($source instanceof EntityDamageEvent){
$this->server->getPluginManager()->callEvent($source);
$damage = $source->getFinalDamage();
if($source->isCancelled()){
return; return;
} }
} }
$pk = new EntityEventPacket(); $pk = EntityEventPacket::getFromPool();
$pk->eid = $this->getID(); $pk->eid = $this->getID();
$pk->event = 2; //Ouch! $pk->event = 2; //Ouch!
Server::broadcastPacket($this->hasSpawned, $pk); Server::broadcastPacket($this->hasSpawned, $pk);
@ -99,7 +114,7 @@ abstract class Living extends Entity implements Damageable{
$f = sqrt($x ** 2 + $z ** 2); $f = sqrt($x ** 2 + $z ** 2);
$base = 0.4; $base = 0.4;
$motion = new Vector3($this->motionX, $this->motionY, $this->motionZ); $motion = Vector3::createVector($this->motionX, $this->motionY, $this->motionZ);
$motion->x /= 2; $motion->x /= 2;
$motion->y /= 2; $motion->y /= 2;
@ -124,7 +139,7 @@ abstract class Living extends Entity implements Damageable{
return; return;
} }
parent::kill(); parent::kill();
$this->server->getPluginManager()->callEvent($ev = new EntityDeathEvent($this, $this->getDrops())); $this->server->getPluginManager()->callEvent($ev = EntityDeathEvent::createEvent($this, $this->getDrops()));
foreach($ev->getDrops() as $item){ foreach($ev->getDrops() as $item){
$this->getLevel()->dropItem($this, $item); $this->getLevel()->dropItem($this, $item);
} }
@ -135,10 +150,8 @@ abstract class Living extends Entity implements Damageable{
parent::entityBaseTick(); parent::entityBaseTick();
if($this->dead !== true and $this->isInsideOfSolid()){ if($this->dead !== true and $this->isInsideOfSolid()){
$this->server->getPluginManager()->callEvent($ev = new EntityDamageEvent($this, EntityDamageEvent::CAUSE_SUFFOCATION, 1)); $ev = EntityDamageEvent::createEvent($this, EntityDamageEvent::CAUSE_SUFFOCATION, 1);
if(!$ev->isCancelled()){ $this->attack($ev->getFinalDamage(), $ev);
$this->attack($ev->getFinalDamage(), $ev);
}
} }
if($this->dead !== true and $this->isInsideOfWater()){ if($this->dead !== true and $this->isInsideOfWater()){
@ -146,10 +159,8 @@ abstract class Living extends Entity implements Damageable{
if($this->airTicks <= -20){ if($this->airTicks <= -20){
$this->airTicks = 0; $this->airTicks = 0;
$this->server->getPluginManager()->callEvent($ev = new EntityDamageEvent($this, EntityDamageEvent::CAUSE_DROWNING, 2)); $ev = EntityDamageEvent::createEvent($this, EntityDamageEvent::CAUSE_DROWNING, 2);
if(!$ev->isCancelled()){ $this->attack($ev->getFinalDamage(), $ev);
$this->attack($ev->getFinalDamage(), $ev);
}
} }
}else{ }else{
$this->airTicks = 300; $this->airTicks = 300;
@ -163,7 +174,7 @@ abstract class Living extends Entity implements Damageable{
} }
/** /**
* @return Item[] * @return ItemItem[]
*/ */
public function getDrops(){ public function getDrops(){
return []; return [];

View File

@ -116,7 +116,7 @@ class PrimedTNT extends Entity implements Explosive{
} }
return $hasUpdate or $this->fuse > 0 or ($this->motionX == 0 and $this->motionY == 0 and $this->motionZ == 0); return $hasUpdate or $this->fuse >= 0 or $this->motionX != 0 or $this->motionY != 0 or $this->motionZ != 0;
} }
public function attack($damage, $source = EntityDamageEvent::CAUSE_MAGIC){ public function attack($damage, $source = EntityDamageEvent::CAUSE_MAGIC){
@ -128,7 +128,7 @@ class PrimedTNT extends Entity implements Explosive{
} }
public function explode(){ public function explode(){
$this->server->getPluginManager()->callEvent($ev = new ExplosionPrimeEvent($this, 4)); $this->server->getPluginManager()->callEvent($ev = ExplosionPrimeEvent::createEvent($this, 4));
if(!$ev->isCancelled()){ if(!$ev->isCancelled()){
$explosion = new Explosion($this, $ev->getForce(), $this); $explosion = new Explosion($this, $ev->getForce(), $this);
@ -140,7 +140,7 @@ class PrimedTNT extends Entity implements Explosive{
} }
public function spawnTo(Player $player){ public function spawnTo(Player $player){
$pk = new AddEntityPacket(); $pk = AddEntityPacket::getFromPool();
$pk->type = PrimedTNT::NETWORK_ID; $pk->type = PrimedTNT::NETWORK_ID;
$pk->eid = $this->getID(); $pk->eid = $this->getID();
$pk->x = $this->x; $pk->x = $this->x;
@ -149,7 +149,7 @@ class PrimedTNT extends Entity implements Explosive{
$pk->did = 0; $pk->did = 0;
$player->dataPacket($pk); $player->dataPacket($pk);
$pk = new SetEntityMotionPacket(); $pk = SetEntityMotionPacket::getFromPool();
$pk->entities = [ $pk->entities = [
[$this->getID(), $this->motionX, $this->motionY, $this->motionZ] [$this->getID(), $this->motionX, $this->motionY, $this->motionZ]
]; ];

View File

@ -22,6 +22,158 @@
namespace pocketmine\entity; namespace pocketmine\entity;
use pocketmine\event\entity\EntityCombustByEntityEvent;
use pocketmine\event\entity\EntityDamageByEntityEvent;
use pocketmine\event\entity\EntityDamageEvent;
use pocketmine\event\entity\EntityRegainHealthEvent;
use pocketmine\event\entity\ProjectileHitEvent;
use pocketmine\level\MovingObjectPosition;
use pocketmine\math\Vector3;
use pocketmine\nbt\tag\Short;
abstract class Projectile extends Entity{ abstract class Projectile extends Entity{
/** @var Entity */
public $shootingEntity = null;
protected $damage = 0;
protected function initEntity(){
$this->setMaxHealth(1);
$this->setHealth(1);
if(isset($this->namedtag->Age)){
$this->age = $this->namedtag["Age"];
}
}
public function canCollideWith(Entity $entity){
return $entity instanceof Living and !$this->onGround;
}
public function getData(){
$flags = 0;
$flags |= $this->fireTicks > 0 ? 1 : 0;
return [
0 => ["type" => 0, "value" => $flags],
1 => ["type" => 1, "value" => $this->airTicks],
16 => ["type" => 0, "value" => 0] //Is critical
];
}
public function saveNBT(){
parent::saveNBT();
$this->namedtag->Age = new Short("Age", $this->age);
}
public function attack($damage, $source = EntityDamageEvent::CAUSE_MAGIC){
}
public function heal($amount, $source = EntityRegainHealthEvent::CAUSE_MAGIC){
}
public function onUpdate($currentTick){
if($this->closed){
return false;
}
$tickDiff = max(1, $currentTick - $this->lastUpdate);
$this->lastUpdate = $currentTick;
$hasUpdate = $this->entityBaseTick($tickDiff);
if(!$this->dead){
$movingObjectPosition = null;
$this->motionY -= $this->gravity;
$this->keepMovement = $this->checkObstruction($this->x, ($this->boundingBox->minY + $this->boundingBox->maxY) / 2, $this->z);
$moveVector = Vector3::createVector($this->x + $this->motionX, $this->y + $this->motionY, $this->z + $this->motionZ);
$list = $this->getLevel()->getCollidingEntities($this->boundingBox->addCoord($this->motionX, $this->motionY, $this->motionZ)->expand(1, 1, 1), $this);
$nearDistance = PHP_INT_MAX;
$nearEntity = null;
foreach($list as $entity){
if(/*!$entity->canCollideWith($this) or */
($entity === $this->shootingEntity and $this->ticksLived < 5)
){
continue;
}
$axisalignedbb = $entity->boundingBox->grow(0.3, 0.3, 0.3);
$ob = $axisalignedbb->calculateIntercept($this, $moveVector);
if($ob === null){
continue;
}
$distance = $this->distance($ob->hitVector);
if($distance < $nearDistance){
$nearDistance = $distance;
$nearEntity = $entity;
}
}
if($nearEntity !== null){
$movingObjectPosition = MovingObjectPosition::fromEntity($nearEntity);
}
if($movingObjectPosition !== null){
if($movingObjectPosition->entityHit !== null){
$this->server->getPluginManager()->callEvent(ProjectileHitEvent::createEvent($this));
$motion = sqrt($this->motionX ** 2 + $this->motionY ** 2 + $this->motionZ ** 2);
$damage = ceil($motion * $this->damage);
$ev = EntityDamageByEntityEvent::createEvent($this->shootingEntity === null ? $this : $this->shootingEntity, $movingObjectPosition->entityHit, EntityDamageEvent::CAUSE_PROJECTILE, $damage);
$movingObjectPosition->entityHit->attack($ev->getFinalDamage(), $ev);
if($this->fireTicks > 0){
$ev = EntityCombustByEntityEvent::createEvent($this, $movingObjectPosition->entityHit, 5);
$this->server->getPluginManager()->callEvent($ev);
if(!$ev->isCancelled()){
$movingObjectPosition->entityHit->setOnFire($ev->getDuration());
}
}
$this->kill();
return true;
}
}
$this->move($this->motionX, $this->motionY, $this->motionZ);
if($this->onGround and ($this->motionX != 0 or $this->motionY != 0 or $this->motionZ != 0)){
$this->motionX = 0;
$this->motionY = 0;
$this->motionZ = 0;
$this->server->getPluginManager()->callEvent(ProjectileHitEvent::createEvent($this));
}
if(!$this->onGround or $this->motionX != 0 or $this->motionY != 0 or $this->motionZ != 0){
$f = sqrt(($this->motionX ** 2) + ($this->motionZ ** 2));
$this->yaw = (atan2($this->motionX, $this->motionZ) * 180 / M_PI);
$this->pitch = (atan2($this->motionY, $f) * 180 / M_PI);
$hasUpdate = true;
}
$this->updateMovement();
}
return $hasUpdate;
}
} }

View File

@ -22,10 +22,68 @@
namespace pocketmine\entity; namespace pocketmine\entity;
use pocketmine\level\format\FullChunk;
use pocketmine\nbt\tag\Compound;
use pocketmine\nbt\tag\String; use pocketmine\nbt\tag\String;
use pocketmine\network\protocol\AddEntityPacket;
use pocketmine\network\protocol\SetEntityMotionPacket;
use pocketmine\Player;
class Snowball extends Projectile{ class Snowball extends Projectile{
const NETWORK_ID = 81;
public $width = 0.25;
public $length = 0.25;
public $height = 0.25;
protected $gravity = 0.03;
protected $drag = 0.01;
public function __construct(FullChunk $chunk, Compound $nbt, Entity $shootingEntity = null){
$this->shootingEntity = $shootingEntity;
parent::__construct($chunk, $nbt);
}
public function onUpdate($currentTick){
if($this->closed){
return false;
}
$this->timings->startTiming();
$hasUpdate = parent::onUpdate($currentTick);
if($this->age > 1200 or $this->onGround){
$this->kill();
$hasUpdate = true;
}
$this->timings->stopTiming();
return $hasUpdate;
}
protected function initEntity(){ protected function initEntity(){
$this->namedtag->id = new String("id", "Snowball"); $this->namedtag->id = new String("id", "Snowball");
parent::initEntity();
}
public function spawnTo(Player $player){
$pk = AddEntityPacket::getFromPool();
$pk->type = Snowball::NETWORK_ID;
$pk->eid = $this->getID();
$pk->x = $this->x;
$pk->y = $this->y;
$pk->z = $this->z;
$pk->did = 0; //TODO: send motion here
$player->dataPacket($pk);
$pk = SetEntityMotionPacket::getFromPool();
$pk->entities = [
[$this->getID(), $this->motionX, $this->motionY, $this->motionZ]
];
$player->dataPacket($pk);
parent::spawnTo($player);
} }
} }

View File

@ -55,7 +55,7 @@ class Villager extends Creature implements NPC, Ageable{
} }
public function spawnTo(Player $player){ public function spawnTo(Player $player){
$pk = new AddMobPacket(); $pk = AddMobPacket::getFromPool();
$pk->eid = $this->getID(); $pk->eid = $this->getID();
$pk->type = Villager::NETWORK_ID; $pk->type = Villager::NETWORK_ID;
$pk->x = $this->x; $pk->x = $this->x;
@ -66,7 +66,7 @@ class Villager extends Creature implements NPC, Ageable{
$pk->metadata = $this->getData(); $pk->metadata = $this->getData();
$player->dataPacket($pk); $player->dataPacket($pk);
$pk = new SetEntityMotionPacket(); $pk = SetEntityMotionPacket::getFromPool();
$pk->entities = [ $pk->entities = [
[$this->getID(), $this->motionX, $this->motionY, $this->motionZ] [$this->getID(), $this->motionX, $this->motionY, $this->motionZ]
]; ];

View File

@ -23,7 +23,7 @@ namespace pocketmine\entity;
use pocketmine\event\entity\EntityDamageByEntityEvent; use pocketmine\event\entity\EntityDamageByEntityEvent;
use pocketmine\item\Item; use pocketmine\item\Item as ItemItem;
use pocketmine\nbt\tag\String; use pocketmine\nbt\tag\String;
use pocketmine\network\protocol\AddMobPacket; use pocketmine\network\protocol\AddMobPacket;
use pocketmine\network\protocol\SetEntityMotionPacket; use pocketmine\network\protocol\SetEntityMotionPacket;
@ -46,7 +46,7 @@ class Zombie extends Monster{
public function spawnTo(Player $player){ public function spawnTo(Player $player){
$pk = new AddMobPacket(); $pk = AddMobPacket::getFromPool();
$pk->eid = $this->getID(); $pk->eid = $this->getID();
$pk->type = Zombie::NETWORK_ID; $pk->type = Zombie::NETWORK_ID;
$pk->x = $this->x; $pk->x = $this->x;
@ -57,7 +57,7 @@ class Zombie extends Monster{
$pk->metadata = $this->getData(); $pk->metadata = $this->getData();
$player->dataPacket($pk); $player->dataPacket($pk);
$pk = new SetEntityMotionPacket(); $pk = SetEntityMotionPacket::getFromPool();
$pk->entities = [ $pk->entities = [
[$this->getID(), $this->motionX, $this->motionY, $this->motionZ] [$this->getID(), $this->motionX, $this->motionY, $this->motionZ]
]; ];
@ -83,19 +83,19 @@ class Zombie extends Monster{
public function getDrops(){ public function getDrops(){
$drops = [ $drops = [
Item::get(Item::FEATHER, 0, 1) ItemItem::get(ItemItem::FEATHER, 0, 1)
]; ];
if($this->lastDamageCause instanceof EntityDamageByEntityEvent and $this->lastDamageCause->getEntity() instanceof Player){ if($this->lastDamageCause instanceof EntityDamageByEntityEvent and $this->lastDamageCause->getEntity() instanceof Player){
if(mt_rand(0, 199) < 5){ if(mt_rand(0, 199) < 5){
switch(mt_rand(0, 2)){ switch(mt_rand(0, 2)){
case 0: case 0:
$drops[] = Item::get(Item::IRON_INGOT, 0, 1); $drops[] = ItemItem::get(ItemItem::IRON_INGOT, 0, 1);
break; break;
case 1: case 1:
$drops[] = Item::get(Item::CARROT, 0, 1); $drops[] = ItemItem::get(ItemItem::CARROT, 0, 1);
break; break;
case 2: case 2:
$drops[] = Item::get(Item::POTATO, 0, 1); $drops[] = ItemItem::get(ItemItem::POTATO, 0, 1);
break; break;
} }
} }

View File

@ -30,10 +30,19 @@ abstract class Event{
* Any callable event must declare the static variable * Any callable event must declare the static variable
* *
* public static $handlerList = null; * public static $handlerList = null;
* public static $eventPool = [];
* public static $nextEvent = 0;
* *
* Not doing so will deny the proper event initialization * Not doing so will deny the proper event initialization
*/ */
/** @var Event[] */
public static $eventPool = [];
public static $nextEvent = 0;
/** @var Event[] */
private static $knownEvents = [];
protected $eventName = null; protected $eventName = null;
private $isCancelled = false; private $isCancelled = false;
@ -41,7 +50,7 @@ abstract class Event{
* @return string * @return string
*/ */
final public function getEventName(){ final public function getEventName(){
return $this->eventName !== null ? get_class($this) : $this->eventName; return $this->eventName === null ? get_class($this) : $this->eventName;
} }
/** /**
@ -85,4 +94,40 @@ abstract class Event{
return static::$handlerList; return static::$handlerList;
} }
public static function clearEventPool(){
static::$nextEvent = 0;
}
public static function clearAllPools(){
foreach(self::$knownEvents as $event){
$event::clearEventPool();
}
}
/**
* @param $params
*
* @return static
*/
public static function createEvent(...$params){
if(static::$nextEvent >= count(static::$eventPool)){
static::$eventPool[] = new static(...$params);
return static::$eventPool[static::$nextEvent++];
}
$ev = static::$eventPool[static::$nextEvent++];
$ev->__construct(...$params);
if($ev instanceof Cancellable){
$ev->setCancelled(false);
}
return $ev;
}
public static function onClassLoaded(){
self::$knownEvents[static::class] = static::class;
}
public static function getKnownEvents(){
return self::$knownEvents;
}
} }

View File

@ -90,7 +90,7 @@ class HandlerList{
return; return;
} }
if(isset($this->handlerSlots[$listener->getPriority()][spl_object_hash($listener)])){ if(isset($this->handlerSlots[$listener->getPriority()][spl_object_hash($listener)])){
throw new \Exception("This listener is already registered to priority " . $listener->getPriority()); throw new \InvalidStateException("This listener is already registered to priority " . $listener->getPriority());
} }
$this->handlers = null; $this->handlers = null;
$this->handlerSlots[$listener->getPriority()][spl_object_hash($listener)] = $listener; $this->handlerSlots[$listener->getPriority()][spl_object_hash($listener)] = $listener;

View File

@ -56,6 +56,11 @@ class LevelTimings{
/** @var TimingsHandler */ /** @var TimingsHandler */
public $tickEntities; public $tickEntities;
/** @var TimingsHandler */
public $syncChunkSendTimer;
/** @var TimingsHandler */
public $syncChunkSendPrepareTimer;
/** @var TimingsHandler */ /** @var TimingsHandler */
public $syncChunkLoadTimer; public $syncChunkLoadTimer;
/** @var TimingsHandler */ /** @var TimingsHandler */
@ -87,6 +92,9 @@ class LevelTimings{
$this->tileEntityTick = new TimingsHandler("** " . $name . "tileEntityTick"); $this->tileEntityTick = new TimingsHandler("** " . $name . "tileEntityTick");
$this->tileEntityPending = new TimingsHandler("** " . $name . "tileEntityPending"); $this->tileEntityPending = new TimingsHandler("** " . $name . "tileEntityPending");
$this->syncChunkSendTimer = new TimingsHandler("** " . $name . "syncChunkSend");
$this->syncChunkSendPrepareTimer = new TimingsHandler("** " . $name . "syncChunkSendPrepare");
$this->syncChunkLoadTimer = new TimingsHandler("** " . $name . "syncChunkLoad"); $this->syncChunkLoadTimer = new TimingsHandler("** " . $name . "syncChunkLoad");
$this->syncChunkLoadDataTimer = new TimingsHandler("** " . $name . "syncChunkLoad - Data"); $this->syncChunkLoadDataTimer = new TimingsHandler("** " . $name . "syncChunkLoad - Data");
$this->syncChunkLoadStructuresTimer = new TimingsHandler("** " . $name . "syncChunkLoad - Structures"); $this->syncChunkLoadStructuresTimer = new TimingsHandler("** " . $name . "syncChunkLoad - Structures");

View File

@ -28,6 +28,8 @@ use pocketmine\Player;
class BlockBreakEvent extends BlockEvent implements Cancellable{ class BlockBreakEvent extends BlockEvent implements Cancellable{
public static $handlerList = null; public static $handlerList = null;
public static $eventPool = [];
public static $nextEvent = 0;
/** @var \pocketmine\Player */ /** @var \pocketmine\Player */
protected $player; protected $player;

View File

@ -26,6 +26,8 @@ use pocketmine\event\Cancellable;
class BlockFormEvent extends BlockGrowEvent implements Cancellable{ class BlockFormEvent extends BlockGrowEvent implements Cancellable{
public static $handlerList = null; public static $handlerList = null;
public static $eventPool = [];
public static $nextEvent = 0;
public function __construct(Block $block, Block $newState){ public function __construct(Block $block, Block $newState){
parent::__construct($block, $newState); parent::__construct($block, $newState);

View File

@ -26,6 +26,8 @@ use pocketmine\event\Cancellable;
class BlockGrowEvent extends BlockEvent implements Cancellable{ class BlockGrowEvent extends BlockEvent implements Cancellable{
public static $handlerList = null; public static $handlerList = null;
public static $eventPool = [];
public static $nextEvent = 0;
/** @var Block */ /** @var Block */
private $newState; private $newState;

View File

@ -31,6 +31,8 @@ use pocketmine\Player;
*/ */
class BlockPlaceEvent extends BlockEvent implements Cancellable{ class BlockPlaceEvent extends BlockEvent implements Cancellable{
public static $handlerList = null; public static $handlerList = null;
public static $eventPool = [];
public static $nextEvent = 0;
/** @var \pocketmine\Player */ /** @var \pocketmine\Player */
protected $player; protected $player;

View File

@ -26,6 +26,8 @@ use pocketmine\event\Cancellable;
class BlockSpreadEvent extends BlockFormEvent implements Cancellable{ class BlockSpreadEvent extends BlockFormEvent implements Cancellable{
public static $handlerList = null; public static $handlerList = null;
public static $eventPool = [];
public static $nextEvent = 0;
/** @var Block */ /** @var Block */
private $source; private $source;

View File

@ -21,14 +21,14 @@
namespace pocketmine\event\block; namespace pocketmine\event\block;
use pocketmine\block\Block;
use pocketmine\event\Cancellable; use pocketmine\event\Cancellable;
use pocketmine\Player;
/** /**
* Called when a block tries to be updated due to a neighbor change * Called when a block tries to be updated due to a neighbor change
*/ */
class BlockUpdateEvent extends BlockEvent implements Cancellable{ class BlockUpdateEvent extends BlockEvent implements Cancellable{
public static $handlerList = null; public static $handlerList = null;
public static $eventPool = [];
public static $nextEvent = 0;
} }

View File

@ -26,6 +26,8 @@ use pocketmine\event\Cancellable;
class LeavesDecayEvent extends BlockEvent implements Cancellable{ class LeavesDecayEvent extends BlockEvent implements Cancellable{
public static $handlerList = null; public static $handlerList = null;
public static $eventPool = [];
public static $nextEvent = 0;
public function __construct(Block $block){ public function __construct(Block $block){
parent::__construct($block); parent::__construct($block);

View File

@ -30,6 +30,8 @@ use pocketmine\Player;
*/ */
class SignChangeEvent extends BlockEvent implements Cancellable{ class SignChangeEvent extends BlockEvent implements Cancellable{
public static $handlerList = null; public static $handlerList = null;
public static $eventPool = [];
public static $nextEvent = 0;
/** @var \pocketmine\Player */ /** @var \pocketmine\Player */
private $player; private $player;

View File

@ -28,6 +28,8 @@ use pocketmine\item\Item;
class EntityArmorChangeEvent extends EntityEvent implements Cancellable{ class EntityArmorChangeEvent extends EntityEvent implements Cancellable{
public static $handlerList = null; public static $handlerList = null;
public static $eventPool = [];
public static $nextEvent = 0;
private $oldItem; private $oldItem;
private $newItem; private $newItem;

View File

@ -30,6 +30,8 @@ use pocketmine\event\Cancellable;
*/ */
class EntityBlockChangeEvent extends EntityEvent implements Cancellable{ class EntityBlockChangeEvent extends EntityEvent implements Cancellable{
public static $handlerList = null; public static $handlerList = null;
public static $eventPool = [];
public static $nextEvent = 0;
private $from; private $from;
private $to; private $to;

View File

@ -25,6 +25,8 @@ use pocketmine\block\Block;
use pocketmine\entity\Entity; use pocketmine\entity\Entity;
class EntityCombustByBlockEvent extends EntityCombustEvent{ class EntityCombustByBlockEvent extends EntityCombustEvent{
public static $eventPool = [];
public static $nextEvent = 0;
protected $combuster; protected $combuster;

View File

@ -24,6 +24,8 @@ namespace pocketmine\event\entity;
use pocketmine\entity\Entity; use pocketmine\entity\Entity;
class EntityCombustByEntityEvent extends EntityCombustEvent{ class EntityCombustByEntityEvent extends EntityCombustEvent{
public static $eventPool = [];
public static $nextEvent = 0;
protected $combuster; protected $combuster;

View File

@ -26,6 +26,8 @@ use pocketmine\event\Cancellable;
class EntityCombustEvent extends EntityEvent implements Cancellable{ class EntityCombustEvent extends EntityEvent implements Cancellable{
public static $handlerList = null; public static $handlerList = null;
public static $eventPool = [];
public static $nextEvent = 0;
protected $duration; protected $duration;

View File

@ -25,6 +25,8 @@ use pocketmine\block\Block;
use pocketmine\entity\Entity; use pocketmine\entity\Entity;
class EntityDamageByBlockEvent extends EntityDamageEvent{ class EntityDamageByBlockEvent extends EntityDamageEvent{
public static $eventPool = [];
public static $nextEvent = 0;
/** @var Block */ /** @var Block */
private $damager; private $damager;

View File

@ -24,6 +24,8 @@ namespace pocketmine\event\entity;
use pocketmine\entity\Entity; use pocketmine\entity\Entity;
class EntityDamageByEntityEvent extends EntityDamageEvent{ class EntityDamageByEntityEvent extends EntityDamageEvent{
public static $eventPool = [];
public static $nextEvent = 0;
/** @var Entity */ /** @var Entity */
private $damager; private $damager;

View File

@ -26,6 +26,8 @@ use pocketmine\event\Cancellable;
class EntityDamageEvent extends EntityEvent implements Cancellable{ class EntityDamageEvent extends EntityEvent implements Cancellable{
public static $handlerList = null; public static $handlerList = null;
public static $eventPool = [];
public static $nextEvent = 0;
const MODIFIER_BASE = 0; const MODIFIER_BASE = 0;
const MODIFIER_ARMOR = 1; const MODIFIER_ARMOR = 1;
@ -74,7 +76,7 @@ class EntityDamageEvent extends EntityEvent implements Cancellable{
$this->originals = $this->modifiers; $this->originals = $this->modifiers;
if(!isset($this->modifiers[self::MODIFIER_BASE])){ if(!isset($this->modifiers[self::MODIFIER_BASE])){
throw new \Exception("BASE Damage modifier missing"); throw new \InvalidArgumentException("BASE Damage modifier missing");
} }
} }

View File

@ -26,6 +26,8 @@ use pocketmine\item\Item;
class EntityDeathEvent extends EntityEvent{ class EntityDeathEvent extends EntityEvent{
public static $handlerList = null; public static $handlerList = null;
public static $eventPool = [];
public static $nextEvent = 0;
/** @var Item[] */ /** @var Item[] */
private $drops = []; private $drops = [];

View File

@ -22,9 +22,9 @@
namespace pocketmine\event\entity; namespace pocketmine\event\entity;
use pocketmine\entity\Creature; use pocketmine\entity\Creature;
use pocketmine\entity\DroppedItem;
use pocketmine\entity\Entity; use pocketmine\entity\Entity;
use pocketmine\entity\Human; use pocketmine\entity\Human;
use pocketmine\entity\Item;
use pocketmine\entity\Projectile; use pocketmine\entity\Projectile;
use pocketmine\entity\Vehicle; use pocketmine\entity\Vehicle;
@ -33,6 +33,8 @@ use pocketmine\entity\Vehicle;
*/ */
class EntityDespawnEvent extends EntityEvent{ class EntityDespawnEvent extends EntityEvent{
public static $handlerList = null; public static $handlerList = null;
public static $eventPool = [];
public static $nextEvent = 0;
private $entityType; private $entityType;
@ -83,7 +85,7 @@ class EntityDespawnEvent extends EntityEvent{
* @return bool * @return bool
*/ */
public function isItem(){ public function isItem(){
return $this->entity instanceof DroppedItem; return $this->entity instanceof Item;
} }
} }

View File

@ -31,6 +31,8 @@ use pocketmine\level\Position;
*/ */
class EntityExplodeEvent extends EntityEvent implements Cancellable{ class EntityExplodeEvent extends EntityEvent implements Cancellable{
public static $handlerList = null; public static $handlerList = null;
public static $eventPool = [];
public static $nextEvent = 0;
/** @var Position */ /** @var Position */
protected $position; protected $position;

View File

@ -28,6 +28,8 @@ use pocketmine\item\Item;
class EntityInventoryChangeEvent extends EntityEvent implements Cancellable{ class EntityInventoryChangeEvent extends EntityEvent implements Cancellable{
public static $handlerList = null; public static $handlerList = null;
public static $eventPool = [];
public static $nextEvent = 0;
private $oldItem; private $oldItem;
private $newItem; private $newItem;

View File

@ -28,6 +28,8 @@ use pocketmine\level\Level;
class EntityLevelChangeEvent extends EntityEvent implements Cancellable{ class EntityLevelChangeEvent extends EntityEvent implements Cancellable{
public static $handlerList = null; public static $handlerList = null;
public static $eventPool = [];
public static $nextEvent = 0;
private $originLevel; private $originLevel;
private $targetLevel; private $targetLevel;

View File

@ -24,10 +24,12 @@ namespace pocketmine\event\entity;
use pocketmine\entity\Entity; use pocketmine\entity\Entity;
use pocketmine\Event; use pocketmine\Event;
use pocketmine\event\Cancellable; use pocketmine\event\Cancellable;
use pocketmine\math\Vector3 as Vector3; use pocketmine\math\Vector3;
class EntityMotionEvent extends EntityEvent implements Cancellable{ class EntityMotionEvent extends EntityEvent implements Cancellable{
public static $handlerList = null; public static $handlerList = null;
public static $eventPool = [];
public static $nextEvent = 0;
private $mot; private $mot;
@ -36,6 +38,9 @@ class EntityMotionEvent extends EntityEvent implements Cancellable{
$this->mot = $mot; $this->mot = $mot;
} }
/**
* @return Vector3
*/
public function getVector(){ public function getVector(){
return $this->mot; return $this->mot;
} }

View File

@ -24,13 +24,15 @@ namespace pocketmine\event\entity;
use pocketmine\entity\Entity; use pocketmine\entity\Entity;
use pocketmine\Event; use pocketmine\Event;
use pocketmine\event\Cancellable; use pocketmine\event\Cancellable;
use pocketmine\math\Vector3 as Vector3; use pocketmine\math\Vector3;
/** /**
* @deprecated * @deprecated
*/ */
class EntityMoveEvent extends EntityEvent implements Cancellable{ class EntityMoveEvent extends EntityEvent implements Cancellable{
public static $handlerList = null; public static $handlerList = null;
public static $eventPool = [];
public static $nextEvent = 0;
/** @var \pocketmine\math\Vector3 */ /** @var \pocketmine\math\Vector3 */
private $pos; private $pos;

View File

@ -26,6 +26,8 @@ use pocketmine\event\Cancellable;
class EntityRegainHealthEvent extends EntityEvent implements Cancellable{ class EntityRegainHealthEvent extends EntityEvent implements Cancellable{
public static $handlerList = null; public static $handlerList = null;
public static $eventPool = [];
public static $nextEvent = 0;
const CAUSE_REGEN = 0; const CAUSE_REGEN = 0;
const CAUSE_EATING = 1; const CAUSE_EATING = 1;

View File

@ -29,6 +29,8 @@ use pocketmine\item\Item;
class EntityShootBowEvent extends EntityEvent implements Cancellable{ class EntityShootBowEvent extends EntityEvent implements Cancellable{
public static $handlerList = null; public static $handlerList = null;
public static $eventPool = [];
public static $nextEvent = 0;
/** @var Item */ /** @var Item */
private $bow; private $bow;

View File

@ -22,9 +22,9 @@
namespace pocketmine\event\entity; namespace pocketmine\event\entity;
use pocketmine\entity\Creature; use pocketmine\entity\Creature;
use pocketmine\entity\DroppedItem;
use pocketmine\entity\Entity; use pocketmine\entity\Entity;
use pocketmine\entity\Human; use pocketmine\entity\Human;
use pocketmine\entity\Item;
use pocketmine\entity\Projectile; use pocketmine\entity\Projectile;
use pocketmine\entity\Vehicle; use pocketmine\entity\Vehicle;
@ -33,6 +33,8 @@ use pocketmine\entity\Vehicle;
*/ */
class EntitySpawnEvent extends EntityEvent{ class EntitySpawnEvent extends EntityEvent{
public static $handlerList = null; public static $handlerList = null;
public static $eventPool = [];
public static $nextEvent = 0;
private $entityType; private $entityType;
@ -90,7 +92,7 @@ class EntitySpawnEvent extends EntityEvent{
* @return bool * @return bool
*/ */
public function isItem(){ public function isItem(){
return $this->entity instanceof DroppedItem; return $this->entity instanceof Item;
} }
} }

View File

@ -28,6 +28,8 @@ use pocketmine\level\Position;
class EntityTeleportEvent extends EntityEvent implements Cancellable{ class EntityTeleportEvent extends EntityEvent implements Cancellable{
public static $handlerList = null; public static $handlerList = null;
public static $eventPool = [];
public static $nextEvent = 0;
/** @var Position */ /** @var Position */
private $from; private $from;

View File

@ -29,6 +29,8 @@ use pocketmine\event\Cancellable;
*/ */
class ExplosionPrimeEvent extends EntityEvent implements Cancellable{ class ExplosionPrimeEvent extends EntityEvent implements Cancellable{
public static $handlerList = null; public static $handlerList = null;
public static $eventPool = [];
public static $nextEvent = 0;
protected $force; protected $force;
private $blockBreaking; private $blockBreaking;

View File

@ -21,22 +21,24 @@
namespace pocketmine\event\entity; namespace pocketmine\event\entity;
use pocketmine\entity\DroppedItem; use pocketmine\entity\Item;
use pocketmine\event\Cancellable; use pocketmine\event\Cancellable;
class ItemDespawnEvent extends EntityEvent implements Cancellable{ class ItemDespawnEvent extends EntityEvent implements Cancellable{
public static $handlerList = null; public static $handlerList = null;
public static $eventPool = [];
public static $nextEvent = 0;
/** /**
* @param DroppedItem $item * @param Item $item
*/ */
public function __construct(DroppedItem $item){ public function __construct(Item $item){
$this->entity = $item; $this->entity = $item;
} }
/** /**
* @return DroppedItem * @return Item
*/ */
public function getEntity(){ public function getEntity(){
return $this->entity; return $this->entity;

View File

@ -21,21 +21,23 @@
namespace pocketmine\event\entity; namespace pocketmine\event\entity;
use pocketmine\entity\DroppedItem; use pocketmine\entity\Item;
class ItemSpawnEvent extends EntityEvent{ class ItemSpawnEvent extends EntityEvent{
public static $handlerList = null; public static $handlerList = null;
public static $eventPool = [];
public static $nextEvent = 0;
/** /**
* @param DroppedItem $item * @param Item $item
*/ */
public function __construct(DroppedItem $item){ public function __construct(Item $item){
$this->entity = $item; $this->entity = $item;
} }
/** /**
* @return DroppedItem * @return Item
*/ */
public function getEntity(){ public function getEntity(){
return $this->entity; return $this->entity;

View File

@ -25,6 +25,8 @@ use pocketmine\entity\Projectile;
class ProjectileHitEvent extends EntityEvent{ class ProjectileHitEvent extends EntityEvent{
public static $handlerList = null; public static $handlerList = null;
public static $eventPool = [];
public static $nextEvent = 0;
/** /**
* @param Projectile $entity * @param Projectile $entity

View File

@ -26,6 +26,8 @@ use pocketmine\event\Cancellable;
class ProjectileLaunchEvent extends EntityEvent implements Cancellable{ class ProjectileLaunchEvent extends EntityEvent implements Cancellable{
public static $handlerList = null; public static $handlerList = null;
public static $eventPool = [];
public static $nextEvent = 0;
/** /**
* @param Projectile $entity * @param Projectile $entity

View File

@ -28,6 +28,8 @@ use pocketmine\inventory\Recipe;
class CraftItemEvent extends Event implements Cancellable{ class CraftItemEvent extends Event implements Cancellable{
public static $handlerList = null; public static $handlerList = null;
public static $eventPool = [];
public static $nextEvent = 0;
/** @var CraftingTransactionGroup */ /** @var CraftingTransactionGroup */
private $ts; private $ts;

View File

@ -28,6 +28,8 @@ use pocketmine\tile\Furnace;
class FurnaceBurnEvent extends BlockEvent implements Cancellable{ class FurnaceBurnEvent extends BlockEvent implements Cancellable{
public static $handlerList = null; public static $handlerList = null;
public static $eventPool = [];
public static $nextEvent = 0;
private $furnace; private $furnace;
private $fuel; private $fuel;

View File

@ -28,6 +28,8 @@ use pocketmine\tile\Furnace;
class FurnaceSmeltEvent extends BlockEvent implements Cancellable{ class FurnaceSmeltEvent extends BlockEvent implements Cancellable{
public static $handlerList = null; public static $handlerList = null;
public static $eventPool = [];
public static $nextEvent = 0;
private $furnace; private $furnace;
private $source; private $source;

View File

@ -26,6 +26,8 @@ use pocketmine\Player;
class InventoryCloseEvent extends InventoryEvent{ class InventoryCloseEvent extends InventoryEvent{
public static $handlerList = null; public static $handlerList = null;
public static $eventPool = [];
public static $nextEvent = 0;
/** @var Player */ /** @var Player */
private $who; private $who;

View File

@ -27,6 +27,8 @@ use pocketmine\Player;
class InventoryOpenEvent extends InventoryEvent implements Cancellable{ class InventoryOpenEvent extends InventoryEvent implements Cancellable{
public static $handlerList = null; public static $handlerList = null;
public static $eventPool = [];
public static $nextEvent = 0;
/** @var Player */ /** @var Player */
private $who; private $who;

View File

@ -0,0 +1,52 @@
<?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/
*
*
*/
namespace pocketmine\event\inventory;
use pocketmine\entity\Arrow;
use pocketmine\event\Cancellable;
use pocketmine\inventory\Inventory;
class InventoryPickupArrowEvent extends InventoryEvent implements Cancellable{
public static $handlerList = null;
public static $eventPool = [];
public static $nextEvent = 0;
/** @var Arrow */
private $arrow;
/**
* @param Inventory $inventory
* @param Arrow $arrow
*/
public function __construct(Inventory $inventory, Arrow $arrow){
$this->arrow = $arrow;
parent::__construct($inventory);
}
/**
* @return Arrow
*/
public function getArrow(){
return $this->arrow;
}
}

View File

@ -21,12 +21,14 @@
namespace pocketmine\event\inventory; namespace pocketmine\event\inventory;
use pocketmine\entity\Item;
use pocketmine\event\Cancellable; use pocketmine\event\Cancellable;
use pocketmine\inventory\Inventory; use pocketmine\inventory\Inventory;
use pocketmine\item\Item;
class InventoryPickupItemEvent extends InventoryEvent implements Cancellable{ class InventoryPickupItemEvent extends InventoryEvent implements Cancellable{
public static $handlerList = null; public static $handlerList = null;
public static $eventPool = [];
public static $nextEvent = 0;
/** @var Item */ /** @var Item */
private $item; private $item;

View File

@ -31,6 +31,8 @@ use pocketmine\inventory\TransactionGroup;
*/ */
class InventoryTransactionEvent extends Event implements Cancellable{ class InventoryTransactionEvent extends Event implements Cancellable{
public static $handlerList = null; public static $handlerList = null;
public static $eventPool = [];
public static $nextEvent = 0;
/** @var TransactionGroup */ /** @var TransactionGroup */
private $ts; private $ts;
@ -42,6 +44,9 @@ class InventoryTransactionEvent extends Event implements Cancellable{
$this->ts = $ts; $this->ts = $ts;
} }
/**
* @return TransactionGroup
*/
public function getTransaction(){ public function getTransaction(){
return $this->ts; return $this->ts;
} }

View File

@ -28,6 +28,8 @@ use pocketmine\level\format\FullChunk;
*/ */
class ChunkLoadEvent extends ChunkEvent{ class ChunkLoadEvent extends ChunkEvent{
public static $handlerList = null; public static $handlerList = null;
public static $eventPool = [];
public static $nextEvent = 0;
private $newChunk; private $newChunk;

View File

@ -26,4 +26,6 @@ namespace pocketmine\event\level;
*/ */
class ChunkPopulateEvent extends ChunkEvent{ class ChunkPopulateEvent extends ChunkEvent{
public static $handlerList = null; public static $handlerList = null;
public static $eventPool = [];
public static $nextEvent = 0;
} }

View File

@ -28,4 +28,6 @@ use pocketmine\event\Cancellable;
*/ */
class ChunkUnloadEvent extends ChunkEvent implements Cancellable{ class ChunkUnloadEvent extends ChunkEvent implements Cancellable{
public static $handlerList = null; public static $handlerList = null;
public static $eventPool = [];
public static $nextEvent = 0;
} }

Some files were not shown because too many files have changed in this diff Show More