mirror of
https://github.com/pmmp/PocketMine-MP.git
synced 2025-05-13 09:19:42 +00:00
first look at separating Entity and Location
This commit is contained in:
parent
591d35889e
commit
2d4a32fc77
@ -156,7 +156,7 @@ class Banner extends Transparent{
|
|||||||
if($face !== Facing::DOWN){
|
if($face !== Facing::DOWN){
|
||||||
$this->facing = $face;
|
$this->facing = $face;
|
||||||
if($face === Facing::UP){
|
if($face === Facing::UP){
|
||||||
$this->rotation = $player !== null ? ((int) floor((($player->yaw + 180) * 16 / 360) + 0.5)) & 0x0f : 0;
|
$this->rotation = $player !== null ? ((int) floor((($player->getLocation()->getYaw() + 180) * 16 / 360) + 0.5)) & 0x0f : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
return parent::place($tx, $item, $blockReplace, $blockClicked, $face, $clickVector, $player);
|
return parent::place($tx, $item, $blockReplace, $blockClicked, $face, $clickVector, $player);
|
||||||
|
@ -138,11 +138,12 @@ class Bed extends Transparent{
|
|||||||
public function onInteract(Item $item, int $face, Vector3 $clickVector, ?Player $player = null) : bool{
|
public function onInteract(Item $item, int $face, Vector3 $clickVector, ?Player $player = null) : bool{
|
||||||
if($player !== null){
|
if($player !== null){
|
||||||
$other = $this->getOtherHalf();
|
$other = $this->getOtherHalf();
|
||||||
|
$playerPos = $player->getPosition();
|
||||||
if($other === null){
|
if($other === null){
|
||||||
$player->sendMessage(TextFormat::GRAY . "This bed is incomplete");
|
$player->sendMessage(TextFormat::GRAY . "This bed is incomplete");
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}elseif($player->distanceSquared($this->pos) > 4 and $player->distanceSquared($other->pos) > 4){
|
}elseif($playerPos->distanceSquared($this->pos) > 4 and $playerPos->distanceSquared($other->pos) > 4){
|
||||||
$player->sendMessage(new TranslationContainer(TextFormat::GRAY . "%tile.bed.tooFar"));
|
$player->sendMessage(new TranslationContainer(TextFormat::GRAY . "%tile.bed.tooFar"));
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -66,7 +66,7 @@ class Ladder extends Transparent{
|
|||||||
}
|
}
|
||||||
|
|
||||||
public function onEntityInside(Entity $entity) : void{
|
public function onEntityInside(Entity $entity) : void{
|
||||||
if($entity->asVector3()->floor()->distanceSquared($this->pos) < 1){ //entity coordinates must be inside block
|
if($entity->getPosition()->floor()->distanceSquared($this->pos) < 1){ //entity coordinates must be inside block
|
||||||
$entity->resetFallDistance();
|
$entity->resetFallDistance();
|
||||||
$entity->onGround = true;
|
$entity->onGround = true;
|
||||||
}
|
}
|
||||||
|
@ -118,7 +118,7 @@ class Sign extends Transparent{
|
|||||||
if($face !== Facing::DOWN){
|
if($face !== Facing::DOWN){
|
||||||
$this->facing = $face;
|
$this->facing = $face;
|
||||||
if($face === Facing::UP){
|
if($face === Facing::UP){
|
||||||
$this->rotation = $player !== null ? ((int) floor((($player->yaw + 180) * 16 / 360) + 0.5)) & 0x0f : 0;
|
$this->rotation = $player !== null ? ((int) floor((($player->getLocation()->getYaw() + 180) * 16 / 360) + 0.5)) & 0x0f : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
return parent::place($tx, $item, $blockReplace, $blockClicked, $face, $clickVector, $player);
|
return parent::place($tx, $item, $blockReplace, $blockClicked, $face, $clickVector, $player);
|
||||||
|
@ -108,7 +108,7 @@ class Skull extends Flowable{
|
|||||||
$this->skullType = $item->getSkullType(); //TODO: the item should handle this, but this hack is currently needed because of tile mess
|
$this->skullType = $item->getSkullType(); //TODO: the item should handle this, but this hack is currently needed because of tile mess
|
||||||
}
|
}
|
||||||
if($player !== null and $face === Facing::UP){
|
if($player !== null and $face === Facing::UP){
|
||||||
$this->rotation = ((int) floor(($player->yaw * 16 / 360) + 0.5)) & 0xf;
|
$this->rotation = ((int) floor(($player->getLocation()->getYaw() * 16 / 360) + 0.5)) & 0xf;
|
||||||
}
|
}
|
||||||
return parent::place($tx, $item, $blockReplace, $blockClicked, $face, $clickVector, $player);
|
return parent::place($tx, $item, $blockReplace, $blockClicked, $face, $clickVector, $player);
|
||||||
}
|
}
|
||||||
|
@ -91,11 +91,12 @@ class ParticleCommand extends VanillaCommand{
|
|||||||
}
|
}
|
||||||
|
|
||||||
if($sender instanceof Player){
|
if($sender instanceof Player){
|
||||||
$world = $sender->getWorld();
|
$senderPos = $sender->getPosition();
|
||||||
|
$world = $senderPos->getWorld();
|
||||||
$pos = new Vector3(
|
$pos = new Vector3(
|
||||||
$this->getRelativeDouble($sender->getX(), $sender, $args[1]),
|
$this->getRelativeDouble($senderPos->getX(), $sender, $args[1]),
|
||||||
$this->getRelativeDouble($sender->getY(), $sender, $args[2], 0, World::Y_MAX),
|
$this->getRelativeDouble($senderPos->getY(), $sender, $args[2], 0, World::Y_MAX),
|
||||||
$this->getRelativeDouble($sender->getZ(), $sender, $args[3])
|
$this->getRelativeDouble($senderPos->getZ(), $sender, $args[3])
|
||||||
);
|
);
|
||||||
}else{
|
}else{
|
||||||
$world = $sender->getServer()->getWorldManager()->getDefaultWorld();
|
$world = $sender->getServer()->getWorldManager()->getDefaultWorld();
|
||||||
|
@ -44,7 +44,7 @@ class SeedCommand extends VanillaCommand{
|
|||||||
}
|
}
|
||||||
|
|
||||||
if($sender instanceof Player){
|
if($sender instanceof Player){
|
||||||
$seed = $sender->getWorld()->getSeed();
|
$seed = $sender->getPosition()->getWorld()->getSeed();
|
||||||
}else{
|
}else{
|
||||||
$seed = $sender->getServer()->getWorldManager()->getDefaultWorld()->getSeed();
|
$seed = $sender->getServer()->getWorldManager()->getDefaultWorld()->getSeed();
|
||||||
}
|
}
|
||||||
|
@ -51,8 +51,9 @@ class SetWorldSpawnCommand extends VanillaCommand{
|
|||||||
|
|
||||||
if(count($args) === 0){
|
if(count($args) === 0){
|
||||||
if($sender instanceof Player){
|
if($sender instanceof Player){
|
||||||
$world = $sender->getWorld();
|
$location = $sender->getPosition();
|
||||||
$pos = (new Vector3($sender->x, $sender->y, $sender->z))->round();
|
$world = $location->getWorld();
|
||||||
|
$pos = $location->asVector3()->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");
|
||||||
|
|
||||||
|
@ -82,7 +82,8 @@ class SpawnpointCommand extends VanillaCommand{
|
|||||||
return true;
|
return true;
|
||||||
}elseif(count($args) <= 1){
|
}elseif(count($args) <= 1){
|
||||||
if($sender instanceof Player){
|
if($sender instanceof Player){
|
||||||
$pos = new Position($sender->getFloorX(), $sender->getFloorY(), $sender->getFloorZ(), $sender->getWorld());
|
$cpos = $sender->getPosition();
|
||||||
|
$pos = Position::fromObject($cpos->floor(), $cpos->getWorld());
|
||||||
$target->setSpawn($pos);
|
$target->setSpawn($pos);
|
||||||
|
|
||||||
Command::broadcastCommandMessage($sender, new TranslationContainer("commands.spawnpoint.success", [$target->getName(), round($pos->x, 2), round($pos->y, 2), round($pos->z, 2)]));
|
Command::broadcastCommandMessage($sender, new TranslationContainer("commands.spawnpoint.success", [$target->getName(), round($pos->x, 2), round($pos->y, 2), round($pos->z, 2)]));
|
||||||
|
@ -96,8 +96,10 @@ class TeleportCommand extends VanillaCommand{
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$targetLocation = $target->getLocation();
|
||||||
|
|
||||||
if(count($args) < 3){
|
if(count($args) < 3){
|
||||||
$origin->teleport($target);
|
$origin->teleport($targetLocation);
|
||||||
Command::broadcastCommandMessage($sender, new TranslationContainer("commands.tp.success", [$origin->getName(), $target->getName()]));
|
Command::broadcastCommandMessage($sender, new TranslationContainer("commands.tp.success", [$origin->getName(), $target->getName()]));
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
@ -108,11 +110,11 @@ class TeleportCommand extends VanillaCommand{
|
|||||||
$pos = 0;
|
$pos = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
$x = $this->getRelativeDouble($target->x, $sender, $args[$pos++]);
|
$x = $this->getRelativeDouble($targetLocation->x, $sender, $args[$pos++]);
|
||||||
$y = $this->getRelativeDouble($target->y, $sender, $args[$pos++], 0, 256);
|
$y = $this->getRelativeDouble($targetLocation->y, $sender, $args[$pos++], 0, 256);
|
||||||
$z = $this->getRelativeDouble($target->z, $sender, $args[$pos++]);
|
$z = $this->getRelativeDouble($targetLocation->z, $sender, $args[$pos++]);
|
||||||
$yaw = $target->getYaw();
|
$yaw = $targetLocation->getYaw();
|
||||||
$pitch = $target->getPitch();
|
$pitch = $targetLocation->getPitch();
|
||||||
|
|
||||||
if(count($args) === 6 or (count($args) === 5 and $pos === 3)){
|
if(count($args) === 6 or (count($args) === 5 and $pos === 3)){
|
||||||
$yaw = (float) $args[$pos++];
|
$yaw = (float) $args[$pos++];
|
||||||
|
@ -59,7 +59,6 @@ use pocketmine\Server;
|
|||||||
use pocketmine\timings\Timings;
|
use pocketmine\timings\Timings;
|
||||||
use pocketmine\timings\TimingsHandler;
|
use pocketmine\timings\TimingsHandler;
|
||||||
use pocketmine\world\format\Chunk;
|
use pocketmine\world\format\Chunk;
|
||||||
use pocketmine\entity\Location;
|
|
||||||
use pocketmine\world\Position;
|
use pocketmine\world\Position;
|
||||||
use pocketmine\world\World;
|
use pocketmine\world\World;
|
||||||
use function abs;
|
use function abs;
|
||||||
@ -77,7 +76,7 @@ use function sin;
|
|||||||
use function spl_object_id;
|
use function spl_object_id;
|
||||||
use const M_PI_2;
|
use const M_PI_2;
|
||||||
|
|
||||||
abstract class Entity extends Location{
|
abstract class Entity{
|
||||||
|
|
||||||
public const MOTION_THRESHOLD = 0.00001;
|
public const MOTION_THRESHOLD = 0.00001;
|
||||||
|
|
||||||
@ -103,6 +102,8 @@ abstract class Entity extends Location{
|
|||||||
/** @var Block[] */
|
/** @var Block[] */
|
||||||
protected $blocksAround = [];
|
protected $blocksAround = [];
|
||||||
|
|
||||||
|
/** @var Location */
|
||||||
|
protected $location;
|
||||||
/** @var Location */
|
/** @var Location */
|
||||||
protected $lastLocation;
|
protected $lastLocation;
|
||||||
/** @var Vector3 */
|
/** @var Vector3 */
|
||||||
@ -240,13 +241,17 @@ abstract class Entity extends Location{
|
|||||||
/** @var float[] $rotation */
|
/** @var float[] $rotation */
|
||||||
$rotation = $nbt->getListTag("Rotation")->getAllValues();
|
$rotation = $nbt->getListTag("Rotation")->getAllValues();
|
||||||
|
|
||||||
parent::__construct($pos[0], $pos[1], $pos[2], $rotation[0], $rotation[1], $world);
|
$this->location = new Location($pos[0], $pos[1], $pos[2], $rotation[0], $rotation[1], $world);
|
||||||
assert(!is_nan($this->x) and !is_infinite($this->x) and !is_nan($this->y) and !is_infinite($this->y) and !is_nan($this->z) and !is_infinite($this->z));
|
assert(
|
||||||
|
!is_nan($this->location->x) and !is_infinite($this->location->x) and
|
||||||
|
!is_nan($this->location->y) and !is_infinite($this->location->y) and
|
||||||
|
!is_nan($this->location->z) and !is_infinite($this->location->z)
|
||||||
|
);
|
||||||
|
|
||||||
$this->boundingBox = new AxisAlignedBB(0, 0, 0, 0, 0, 0);
|
$this->boundingBox = new AxisAlignedBB(0, 0, 0, 0, 0, 0);
|
||||||
$this->recalculateBoundingBox();
|
$this->recalculateBoundingBox();
|
||||||
|
|
||||||
$this->chunk = $this->world->getChunkAtPosition($this, false);
|
$this->chunk = $this->getWorld()->getChunkAtPosition($this->location, false);
|
||||||
if($this->chunk === null){
|
if($this->chunk === null){
|
||||||
throw new \InvalidStateException("Cannot create entities in unloaded chunks");
|
throw new \InvalidStateException("Cannot create entities in unloaded chunks");
|
||||||
}
|
}
|
||||||
@ -268,7 +273,7 @@ abstract class Entity extends Location{
|
|||||||
$this->initEntity($nbt);
|
$this->initEntity($nbt);
|
||||||
|
|
||||||
$this->chunk->addEntity($this);
|
$this->chunk->addEntity($this);
|
||||||
$this->world->addEntity($this);
|
$this->getWorld()->addEntity($this);
|
||||||
|
|
||||||
$this->lastUpdate = $this->server->getTick();
|
$this->lastUpdate = $this->server->getTick();
|
||||||
(new EntitySpawnEvent($this))->call();
|
(new EntitySpawnEvent($this))->call();
|
||||||
@ -366,12 +371,12 @@ abstract class Entity extends Location{
|
|||||||
$halfWidth = $this->width / 2;
|
$halfWidth = $this->width / 2;
|
||||||
|
|
||||||
$this->boundingBox = new AxisAlignedBB(
|
$this->boundingBox = new AxisAlignedBB(
|
||||||
$this->x - $halfWidth,
|
$this->location->x - $halfWidth,
|
||||||
$this->y,
|
$this->location->y,
|
||||||
$this->z - $halfWidth,
|
$this->location->z - $halfWidth,
|
||||||
$this->x + $halfWidth,
|
$this->location->x + $halfWidth,
|
||||||
$this->y + $this->height,
|
$this->location->y + $this->height,
|
||||||
$this->z + $halfWidth
|
$this->location->z + $halfWidth
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -544,9 +549,9 @@ abstract class Entity extends Location{
|
|||||||
}
|
}
|
||||||
|
|
||||||
$nbt->setTag("Pos", new ListTag([
|
$nbt->setTag("Pos", new ListTag([
|
||||||
new DoubleTag($this->x),
|
new DoubleTag($this->location->x),
|
||||||
new DoubleTag($this->y),
|
new DoubleTag($this->location->y),
|
||||||
new DoubleTag($this->z)
|
new DoubleTag($this->location->z)
|
||||||
]));
|
]));
|
||||||
|
|
||||||
$nbt->setTag("Motion", new ListTag([
|
$nbt->setTag("Motion", new ListTag([
|
||||||
@ -556,8 +561,8 @@ abstract class Entity extends Location{
|
|||||||
]));
|
]));
|
||||||
|
|
||||||
$nbt->setTag("Rotation", new ListTag([
|
$nbt->setTag("Rotation", new ListTag([
|
||||||
new FloatTag($this->yaw),
|
new FloatTag($this->location->yaw),
|
||||||
new FloatTag($this->pitch)
|
new FloatTag($this->location->pitch)
|
||||||
]));
|
]));
|
||||||
|
|
||||||
$nbt->setFloat("FallDistance", $this->fallDistance);
|
$nbt->setFloat("FallDistance", $this->fallDistance);
|
||||||
@ -727,7 +732,7 @@ abstract class Entity extends Location{
|
|||||||
|
|
||||||
$this->checkBlockCollision();
|
$this->checkBlockCollision();
|
||||||
|
|
||||||
if($this->y <= -16 and $this->isAlive()){
|
if($this->location->y <= -16 and $this->isAlive()){
|
||||||
$ev = new EntityDamageEvent($this, EntityDamageEvent::CAUSE_VOID, 10);
|
$ev = new EntityDamageEvent($this, EntityDamageEvent::CAUSE_VOID, 10);
|
||||||
$this->attack($ev);
|
$this->attack($ev);
|
||||||
$hasUpdate = true;
|
$hasUpdate = true;
|
||||||
@ -826,13 +831,13 @@ abstract class Entity extends Location{
|
|||||||
//TODO: hack for client-side AI interference: prevent client sided movement when motion is 0
|
//TODO: hack for client-side AI interference: prevent client sided movement when motion is 0
|
||||||
$this->setImmobile($this->motion->x == 0 and $this->motion->y == 0 and $this->motion->z == 0);
|
$this->setImmobile($this->motion->x == 0 and $this->motion->y == 0 and $this->motion->z == 0);
|
||||||
|
|
||||||
$diffPosition = $this->distanceSquared($this->lastLocation);
|
$diffPosition = $this->location->distanceSquared($this->lastLocation);
|
||||||
$diffRotation = ($this->yaw - $this->lastLocation->yaw) ** 2 + ($this->pitch - $this->lastLocation->pitch) ** 2;
|
$diffRotation = ($this->location->yaw - $this->lastLocation->yaw) ** 2 + ($this->location->pitch - $this->lastLocation->pitch) ** 2;
|
||||||
|
|
||||||
$diffMotion = $this->motion->subtract($this->lastMotion)->lengthSquared();
|
$diffMotion = $this->motion->subtract($this->lastMotion)->lengthSquared();
|
||||||
|
|
||||||
if($teleport or $diffPosition > 0.0001 or $diffRotation > 1.0){
|
if($teleport or $diffPosition > 0.0001 or $diffRotation > 1.0){
|
||||||
$this->lastLocation = $this->asLocation();
|
$this->lastLocation = $this->location->asLocation();
|
||||||
|
|
||||||
$this->broadcastMovement($teleport);
|
$this->broadcastMovement($teleport);
|
||||||
}
|
}
|
||||||
@ -851,24 +856,24 @@ abstract class Entity extends Location{
|
|||||||
protected function broadcastMovement(bool $teleport = false) : void{
|
protected function broadcastMovement(bool $teleport = false) : void{
|
||||||
$pk = new MoveActorAbsolutePacket();
|
$pk = new MoveActorAbsolutePacket();
|
||||||
$pk->entityRuntimeId = $this->id;
|
$pk->entityRuntimeId = $this->id;
|
||||||
$pk->position = $this->getOffsetPosition($this);
|
$pk->position = $this->getOffsetPosition($this->location);
|
||||||
|
|
||||||
//this looks very odd but is correct as of 1.5.0.7
|
//this looks very odd but is correct as of 1.5.0.7
|
||||||
//for arrows this is actually x/y/z rotation
|
//for arrows this is actually x/y/z rotation
|
||||||
//for mobs x and z are used for pitch and yaw, and y is used for headyaw
|
//for mobs x and z are used for pitch and yaw, and y is used for headyaw
|
||||||
$pk->xRot = $this->pitch;
|
$pk->xRot = $this->location->pitch;
|
||||||
$pk->yRot = $this->yaw; //TODO: head yaw
|
$pk->yRot = $this->location->yaw; //TODO: head yaw
|
||||||
$pk->zRot = $this->yaw;
|
$pk->zRot = $this->location->yaw;
|
||||||
|
|
||||||
if($teleport){
|
if($teleport){
|
||||||
$pk->flags |= MoveActorAbsolutePacket::FLAG_TELEPORT;
|
$pk->flags |= MoveActorAbsolutePacket::FLAG_TELEPORT;
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->world->broadcastPacketToViewers($this, $pk);
|
$this->getWorld()->broadcastPacketToViewers($this->location, $pk);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function broadcastMotion() : void{
|
protected function broadcastMotion() : void{
|
||||||
$this->world->broadcastPacketToViewers($this, SetActorMotionPacket::create($this->id, $this->getMotion()));
|
$this->getWorld()->broadcastPacketToViewers($this->location, SetActorMotionPacket::create($this->id, $this->getMotion()));
|
||||||
}
|
}
|
||||||
|
|
||||||
public function hasGravity() : bool{
|
public function hasGravity() : bool{
|
||||||
@ -903,7 +908,7 @@ abstract class Entity extends Location{
|
|||||||
}
|
}
|
||||||
|
|
||||||
if($this->onGround){
|
if($this->onGround){
|
||||||
$friction *= $this->world->getBlockAt((int) floor($this->x), (int) floor($this->y - 1), (int) floor($this->z))->getFrictionFactor();
|
$friction *= $this->getWorld()->getBlockAt((int) floor($this->location->x), (int) floor($this->location->y - 1), (int) floor($this->location->z))->getFrictionFactor();
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->motion->x *= $friction;
|
$this->motion->x *= $friction;
|
||||||
@ -911,7 +916,8 @@ abstract class Entity extends Location{
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected function checkObstruction(float $x, float $y, float $z) : bool{
|
protected function checkObstruction(float $x, float $y, float $z) : bool{
|
||||||
if(count($this->world->getCollisionBoxes($this, $this->getBoundingBox(), false)) === 0){
|
$world = $this->getWorld();
|
||||||
|
if(count($world->getCollisionBoxes($this, $this->getBoundingBox(), false)) === 0){
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -923,13 +929,13 @@ abstract class Entity extends Location{
|
|||||||
$diffY = $y - $floorY;
|
$diffY = $y - $floorY;
|
||||||
$diffZ = $z - $floorZ;
|
$diffZ = $z - $floorZ;
|
||||||
|
|
||||||
if($this->world->getBlockAt($floorX, $floorY, $floorZ)->isSolid()){
|
if($world->getBlockAt($floorX, $floorY, $floorZ)->isSolid()){
|
||||||
$westNonSolid = !$this->world->getBlockAt($floorX - 1, $floorY, $floorZ)->isSolid();
|
$westNonSolid = !$world->getBlockAt($floorX - 1, $floorY, $floorZ)->isSolid();
|
||||||
$eastNonSolid = !$this->world->getBlockAt($floorX + 1, $floorY, $floorZ)->isSolid();
|
$eastNonSolid = !$world->getBlockAt($floorX + 1, $floorY, $floorZ)->isSolid();
|
||||||
$downNonSolid = !$this->world->getBlockAt($floorX, $floorY - 1, $floorZ)->isSolid();
|
$downNonSolid = !$world->getBlockAt($floorX, $floorY - 1, $floorZ)->isSolid();
|
||||||
$upNonSolid = !$this->world->getBlockAt($floorX, $floorY + 1, $floorZ)->isSolid();
|
$upNonSolid = !$world->getBlockAt($floorX, $floorY + 1, $floorZ)->isSolid();
|
||||||
$northNonSolid = !$this->world->getBlockAt($floorX, $floorY, $floorZ - 1)->isSolid();
|
$northNonSolid = !$world->getBlockAt($floorX, $floorY, $floorZ - 1)->isSolid();
|
||||||
$southNonSolid = !$this->world->getBlockAt($floorX, $floorY, $floorZ + 1)->isSolid();
|
$southNonSolid = !$world->getBlockAt($floorX, $floorY, $floorZ + 1)->isSolid();
|
||||||
|
|
||||||
$direction = -1;
|
$direction = -1;
|
||||||
$limit = 9999;
|
$limit = 9999;
|
||||||
@ -1006,7 +1012,7 @@ abstract class Entity extends Location{
|
|||||||
}
|
}
|
||||||
|
|
||||||
public function getHorizontalFacing() : int{
|
public function getHorizontalFacing() : int{
|
||||||
$angle = $this->yaw % 360;
|
$angle = $this->location->yaw % 360;
|
||||||
if($angle < 0){
|
if($angle < 0){
|
||||||
$angle += 360.0;
|
$angle += 360.0;
|
||||||
}
|
}
|
||||||
@ -1028,16 +1034,16 @@ abstract class Entity extends Location{
|
|||||||
* @return Vector3
|
* @return Vector3
|
||||||
*/
|
*/
|
||||||
public function getDirectionVector() : Vector3{
|
public function getDirectionVector() : Vector3{
|
||||||
$y = -sin(deg2rad($this->pitch));
|
$y = -sin(deg2rad($this->location->pitch));
|
||||||
$xz = cos(deg2rad($this->pitch));
|
$xz = cos(deg2rad($this->location->pitch));
|
||||||
$x = -$xz * sin(deg2rad($this->yaw));
|
$x = -$xz * sin(deg2rad($this->location->yaw));
|
||||||
$z = $xz * cos(deg2rad($this->yaw));
|
$z = $xz * cos(deg2rad($this->location->yaw));
|
||||||
|
|
||||||
return $this->temporalVector->setComponents($x, $y, $z)->normalize();
|
return $this->temporalVector->setComponents($x, $y, $z)->normalize();
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getDirectionPlane() : Vector2{
|
public function getDirectionPlane() : Vector2{
|
||||||
return (new Vector2(-cos(deg2rad($this->yaw) - M_PI_2), -sin(deg2rad($this->yaw) - M_PI_2)))->normalize();
|
return (new Vector2(-cos(deg2rad($this->location->yaw) - M_PI_2), -sin(deg2rad($this->location->yaw) - M_PI_2)))->normalize();
|
||||||
}
|
}
|
||||||
|
|
||||||
public function onUpdate(int $currentTick) : bool{
|
public function onUpdate(int $currentTick) : bool{
|
||||||
@ -1105,7 +1111,7 @@ abstract class Entity extends Location{
|
|||||||
if($this->closed){
|
if($this->closed){
|
||||||
throw new \InvalidStateException("Cannot schedule update on garbage entity " . get_class($this));
|
throw new \InvalidStateException("Cannot schedule update on garbage entity " . get_class($this));
|
||||||
}
|
}
|
||||||
$this->world->updateEntities[$this->id] = $this;
|
$this->getWorld()->updateEntities[$this->id] = $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function onNearbyBlockChange() : void{
|
public function onNearbyBlockChange() : void{
|
||||||
@ -1172,7 +1178,7 @@ abstract class Entity extends Location{
|
|||||||
}
|
}
|
||||||
|
|
||||||
public function getEyePos() : Vector3{
|
public function getEyePos() : Vector3{
|
||||||
return new Vector3($this->x, $this->y + $this->getEyeHeight(), $this->z);
|
return new Vector3($this->location->x, $this->location->y + $this->getEyeHeight(), $this->location->z);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function onCollideWithPlayer(Player $player) : void{
|
public function onCollideWithPlayer(Player $player) : void{
|
||||||
@ -1180,7 +1186,7 @@ abstract class Entity extends Location{
|
|||||||
}
|
}
|
||||||
|
|
||||||
public function isUnderwater() : bool{
|
public function isUnderwater() : bool{
|
||||||
$block = $this->world->getBlockAt((int) floor($this->x), $blockY = (int) floor($y = ($this->y + $this->getEyeHeight())), (int) floor($this->z));
|
$block = $this->getWorld()->getBlockAt((int) floor($this->location->x), $blockY = (int) floor($y = ($this->location->y + $this->getEyeHeight())), (int) floor($this->location->z));
|
||||||
|
|
||||||
if($block instanceof Water){
|
if($block instanceof Water){
|
||||||
$f = ($blockY + 1) - ($block->getFluidHeightPercent() - 0.1111111);
|
$f = ($blockY + 1) - ($block->getFluidHeightPercent() - 0.1111111);
|
||||||
@ -1191,7 +1197,7 @@ abstract class Entity extends Location{
|
|||||||
}
|
}
|
||||||
|
|
||||||
public function isInsideOfSolid() : bool{
|
public function isInsideOfSolid() : bool{
|
||||||
$block = $this->world->getBlockAt((int) floor($this->x), (int) floor($y = ($this->y + $this->getEyeHeight())), (int) floor($this->z));
|
$block = $this->getWorld()->getBlockAt((int) floor($this->location->x), (int) floor($y = ($this->location->y + $this->getEyeHeight())), (int) floor($this->location->z));
|
||||||
|
|
||||||
return $block->isSolid() and !$block->isTransparent() and $block->collidesWithBB($this->getBoundingBox());
|
return $block->isSolid() and !$block->isTransparent() and $block->collidesWithBB($this->getBoundingBox());
|
||||||
}
|
}
|
||||||
@ -1252,7 +1258,7 @@ abstract class Entity extends Location{
|
|||||||
|
|
||||||
assert(abs($dx) <= 20 and abs($dy) <= 20 and abs($dz) <= 20, "Movement distance is excessive: dx=$dx, dy=$dy, dz=$dz");
|
assert(abs($dx) <= 20 and abs($dy) <= 20 and abs($dz) <= 20, "Movement distance is excessive: dx=$dx, dy=$dy, dz=$dz");
|
||||||
|
|
||||||
$list = $this->world->getCollisionBoxes($this, $moveBB->addCoord($dx, $dy, $dz), false);
|
$list = $this->getWorld()->getCollisionBoxes($this, $moveBB->addCoord($dx, $dy, $dz), false);
|
||||||
|
|
||||||
foreach($list as $bb){
|
foreach($list as $bb){
|
||||||
$dy = $bb->calculateYOffset($moveBB, $dy);
|
$dy = $bb->calculateYOffset($moveBB, $dy);
|
||||||
@ -1285,8 +1291,7 @@ abstract class Entity extends Location{
|
|||||||
|
|
||||||
$stepBB = clone $this->boundingBox;
|
$stepBB = clone $this->boundingBox;
|
||||||
|
|
||||||
$list = $this->world->getCollisionBoxes($this, $stepBB->addCoord($dx, $dy, $dz), false);
|
$list = $this->getWorld()->getCollisionBoxes($this, $stepBB->addCoord($dx, $dy, $dz), false);
|
||||||
|
|
||||||
foreach($list as $bb){
|
foreach($list as $bb){
|
||||||
$dy = $bb->calculateYOffset($stepBB, $dy);
|
$dy = $bb->calculateYOffset($stepBB, $dy);
|
||||||
}
|
}
|
||||||
@ -1318,9 +1323,9 @@ abstract class Entity extends Location{
|
|||||||
$this->boundingBox = $moveBB;
|
$this->boundingBox = $moveBB;
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->x = ($this->boundingBox->minX + $this->boundingBox->maxX) / 2;
|
$this->location->x = ($this->boundingBox->minX + $this->boundingBox->maxX) / 2;
|
||||||
$this->y = $this->boundingBox->minY - $this->ySize;
|
$this->location->y = $this->boundingBox->minY - $this->ySize;
|
||||||
$this->z = ($this->boundingBox->minZ + $this->boundingBox->maxZ) / 2;
|
$this->location->z = ($this->boundingBox->minZ + $this->boundingBox->maxZ) / 2;
|
||||||
|
|
||||||
$this->checkChunks();
|
$this->checkChunks();
|
||||||
$this->checkBlockCollision();
|
$this->checkBlockCollision();
|
||||||
@ -1370,10 +1375,12 @@ abstract class Entity extends Location{
|
|||||||
|
|
||||||
$this->blocksAround = [];
|
$this->blocksAround = [];
|
||||||
|
|
||||||
|
$world = $this->getWorld();
|
||||||
|
|
||||||
for($z = $minZ; $z <= $maxZ; ++$z){
|
for($z = $minZ; $z <= $maxZ; ++$z){
|
||||||
for($x = $minX; $x <= $maxX; ++$x){
|
for($x = $minX; $x <= $maxX; ++$x){
|
||||||
for($y = $minY; $y <= $maxY; ++$y){
|
for($y = $minY; $y <= $maxY; ++$y){
|
||||||
$block = $this->world->getBlockAt($x, $y, $z);
|
$block = $world->getBlockAt($x, $y, $z);
|
||||||
if($block->hasEntityCollision()){
|
if($block->hasEntityCollision()){
|
||||||
$this->blocksAround[] = $block;
|
$this->blocksAround[] = $block;
|
||||||
}
|
}
|
||||||
@ -1412,11 +1419,15 @@ abstract class Entity extends Location{
|
|||||||
}
|
}
|
||||||
|
|
||||||
public function getPosition() : Position{
|
public function getPosition() : Position{
|
||||||
return $this->asPosition();
|
return $this->location->asPosition();
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getLocation() : Location{
|
public function getLocation() : Location{
|
||||||
return $this->asLocation();
|
return $this->location->asLocation();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getWorld() : World{
|
||||||
|
return $this->location->getWorld();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function setPosition(Vector3 $pos) : bool{
|
protected function setPosition(Vector3 $pos) : bool{
|
||||||
@ -1424,15 +1435,15 @@ abstract class Entity extends Location{
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if($pos instanceof Position and $pos->world !== null and $pos->world !== $this->world){
|
if($pos instanceof Position and $pos->world !== null and $pos->world !== $this->getWorld()){
|
||||||
if(!$this->switchWorld($pos->getWorld())){
|
if(!$this->switchWorld($pos->getWorld())){
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->x = $pos->x;
|
$this->location->x = $pos->x;
|
||||||
$this->y = $pos->y;
|
$this->location->y = $pos->y;
|
||||||
$this->z = $pos->z;
|
$this->location->z = $pos->z;
|
||||||
|
|
||||||
$this->recalculateBoundingBox();
|
$this->recalculateBoundingBox();
|
||||||
|
|
||||||
@ -1444,8 +1455,8 @@ abstract class Entity extends Location{
|
|||||||
}
|
}
|
||||||
|
|
||||||
public function setRotation(float $yaw, float $pitch) : void{
|
public function setRotation(float $yaw, float $pitch) : void{
|
||||||
$this->yaw = $yaw;
|
$this->location->yaw = $yaw;
|
||||||
$this->pitch = $pitch;
|
$this->location->pitch = $pitch;
|
||||||
$this->scheduleUpdate();
|
$this->scheduleUpdate();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1460,16 +1471,16 @@ abstract class Entity extends Location{
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected function checkChunks() : void{
|
protected function checkChunks() : void{
|
||||||
$chunkX = $this->getFloorX() >> 4;
|
$chunkX = $this->location->getFloorX() >> 4;
|
||||||
$chunkZ = $this->getFloorZ() >> 4;
|
$chunkZ = $this->location->getFloorZ() >> 4;
|
||||||
if($this->chunk === null or ($this->chunk->getX() !== $chunkX or $this->chunk->getZ() !== $chunkZ)){
|
if($this->chunk === null or ($this->chunk->getX() !== $chunkX or $this->chunk->getZ() !== $chunkZ)){
|
||||||
if($this->chunk !== null){
|
if($this->chunk !== null){
|
||||||
$this->chunk->removeEntity($this);
|
$this->chunk->removeEntity($this);
|
||||||
}
|
}
|
||||||
$this->chunk = $this->world->getChunk($chunkX, $chunkZ, true);
|
$this->chunk = $this->getWorld()->getChunk($chunkX, $chunkZ, true);
|
||||||
|
|
||||||
if(!$this->justCreated){
|
if(!$this->justCreated){
|
||||||
$newChunk = $this->world->getViewersForPosition($this);
|
$newChunk = $this->getWorld()->getViewersForPosition($this->location);
|
||||||
foreach($this->hasSpawned as $player){
|
foreach($this->hasSpawned as $player){
|
||||||
if(!isset($newChunk[spl_object_id($player)])){
|
if(!isset($newChunk[spl_object_id($player)])){
|
||||||
$this->despawnFrom($player);
|
$this->despawnFrom($player);
|
||||||
@ -1491,7 +1502,7 @@ abstract class Entity extends Location{
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected function resetLastMovements() : void{
|
protected function resetLastMovements() : void{
|
||||||
$this->lastLocation = $this->asLocation();
|
$this->lastLocation = $this->location->asLocation();
|
||||||
$this->lastMotion = clone $this->motion;
|
$this->lastMotion = clone $this->motion;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1546,8 +1557,8 @@ abstract class Entity extends Location{
|
|||||||
$yaw = $yaw ?? $pos->yaw;
|
$yaw = $yaw ?? $pos->yaw;
|
||||||
$pitch = $pitch ?? $pos->pitch;
|
$pitch = $pitch ?? $pos->pitch;
|
||||||
}
|
}
|
||||||
$from = Position::fromObject($this, $this->world);
|
$from = $this->location->asPosition();
|
||||||
$to = Position::fromObject($pos, $pos instanceof Position ? $pos->getWorld() : $this->world);
|
$to = Position::fromObject($pos, $pos instanceof Position ? $pos->getWorld() : $this->getWorld());
|
||||||
$ev = new EntityTeleportEvent($this, $from, $to);
|
$ev = new EntityTeleportEvent($this, $from, $to);
|
||||||
$ev->call();
|
$ev->call();
|
||||||
if($ev->isCancelled()){
|
if($ev->isCancelled()){
|
||||||
@ -1557,7 +1568,7 @@ abstract class Entity extends Location{
|
|||||||
$pos = $ev->getTo();
|
$pos = $ev->getTo();
|
||||||
|
|
||||||
$this->setMotion($this->temporalVector->setComponents(0, 0, 0));
|
$this->setMotion($this->temporalVector->setComponents(0, 0, 0));
|
||||||
if($this->setPositionAndRotation($pos, $yaw ?? $this->yaw, $pitch ?? $this->pitch)){
|
if($this->setPositionAndRotation($pos, $yaw ?? $this->location->yaw, $pitch ?? $this->location->pitch)){
|
||||||
$this->resetFallDistance();
|
$this->resetFallDistance();
|
||||||
$this->onGround = true;
|
$this->onGround = true;
|
||||||
|
|
||||||
@ -1574,16 +1585,16 @@ abstract class Entity extends Location{
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if($this->isValid()){
|
if($this->location->isValid()){
|
||||||
$this->world->removeEntity($this);
|
$this->getWorld()->removeEntity($this);
|
||||||
if($this->chunk !== null){
|
if($this->chunk !== null){
|
||||||
$this->chunk->removeEntity($this);
|
$this->chunk->removeEntity($this);
|
||||||
}
|
}
|
||||||
$this->despawnFromAll();
|
$this->despawnFromAll();
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->setWorld($targetWorld);
|
$this->location->setWorld($targetWorld);
|
||||||
$this->world->addEntity($this);
|
$this->getWorld()->addEntity($this);
|
||||||
$this->chunk = null;
|
$this->chunk = null;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
@ -1609,11 +1620,11 @@ abstract class Entity extends Location{
|
|||||||
$pk = new AddActorPacket();
|
$pk = new AddActorPacket();
|
||||||
$pk->entityRuntimeId = $this->getId();
|
$pk->entityRuntimeId = $this->getId();
|
||||||
$pk->type = static::NETWORK_ID;
|
$pk->type = static::NETWORK_ID;
|
||||||
$pk->position = $this->asVector3();
|
$pk->position = $this->location->asVector3();
|
||||||
$pk->motion = $this->getMotion();
|
$pk->motion = $this->getMotion();
|
||||||
$pk->yaw = $this->yaw;
|
$pk->yaw = $this->location->yaw;
|
||||||
$pk->headYaw = $this->yaw; //TODO
|
$pk->headYaw = $this->location->yaw; //TODO
|
||||||
$pk->pitch = $this->pitch;
|
$pk->pitch = $this->location->pitch;
|
||||||
$pk->attributes = $this->attributeMap->getAll();
|
$pk->attributes = $this->attributeMap->getAll();
|
||||||
$pk->metadata = $this->getSyncedNetworkData(false);
|
$pk->metadata = $this->getSyncedNetworkData(false);
|
||||||
|
|
||||||
@ -1636,7 +1647,7 @@ abstract class Entity extends Location{
|
|||||||
if($this->closed){
|
if($this->closed){
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
foreach($this->world->getViewersForPosition($this) as $player){
|
foreach($this->getWorld()->getViewersForPosition($this->location) as $player){
|
||||||
$this->spawnTo($player);
|
$this->spawnTo($player);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1719,8 +1730,8 @@ abstract class Entity extends Location{
|
|||||||
if($this->chunk !== null){
|
if($this->chunk !== null){
|
||||||
$this->chunk->removeEntity($this);
|
$this->chunk->removeEntity($this);
|
||||||
}
|
}
|
||||||
if($this->isValid()){
|
if($this->location->isValid()){
|
||||||
$this->world->removeEntity($this);
|
$this->getWorld()->removeEntity($this);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1732,7 +1743,7 @@ abstract class Entity extends Location{
|
|||||||
*/
|
*/
|
||||||
protected function destroyCycles() : void{
|
protected function destroyCycles() : void{
|
||||||
$this->chunk = null;
|
$this->chunk = null;
|
||||||
$this->setWorld(null);
|
$this->location->setWorld(null);
|
||||||
$this->lastDamageCause = null;
|
$this->lastDamageCause = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -95,7 +95,7 @@ class ExperienceManager{
|
|||||||
if($playSound){
|
if($playSound){
|
||||||
$newLevel = $this->getXpLevel();
|
$newLevel = $this->getXpLevel();
|
||||||
if((int) ($newLevel / 5) > (int) ($oldLevel / 5)){
|
if((int) ($newLevel / 5) > (int) ($oldLevel / 5)){
|
||||||
$this->entity->getWorld()->addSound($this->entity->asVector3(), new XpLevelUpSound($newLevel));
|
$this->entity->getWorld()->addSound($this->entity->getPosition(), new XpLevelUpSound($newLevel));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -187,9 +187,9 @@ class ExperienceManager{
|
|||||||
if($playSound){
|
if($playSound){
|
||||||
$newLevel = $this->getXpLevel();
|
$newLevel = $this->getXpLevel();
|
||||||
if((int) ($newLevel / 5) > (int) ($oldLevel / 5)){
|
if((int) ($newLevel / 5) > (int) ($oldLevel / 5)){
|
||||||
$this->entity->getWorld()->addSound($this->entity->asVector3(), new XpLevelUpSound($newLevel));
|
$this->entity->getWorld()->addSound($this->entity->getPosition(), new XpLevelUpSound($newLevel));
|
||||||
}elseif($this->getCurrentTotalXp() > $oldTotal){
|
}elseif($this->getCurrentTotalXp() > $oldTotal){
|
||||||
$this->entity->getWorld()->addSound($this->entity->asVector3(), new XpCollectSound());
|
$this->entity->getWorld()->addSound($this->entity->getPosition(), new XpCollectSound());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -316,7 +316,7 @@ class Human extends Living implements ProjectileSource, InventoryHolder{
|
|||||||
$this->effectManager->add(new EffectInstance(VanillaEffects::ABSORPTION(), 5 * 20, 1));
|
$this->effectManager->add(new EffectInstance(VanillaEffects::ABSORPTION(), 5 * 20, 1));
|
||||||
|
|
||||||
$this->broadcastEntityEvent(ActorEventPacket::CONSUME_TOTEM);
|
$this->broadcastEntityEvent(ActorEventPacket::CONSUME_TOTEM);
|
||||||
$this->world->addSound($this->add(0, $this->eyeHeight, 0), new TotemUseSound());
|
$this->getWorld()->addSound($this->location->add(0, $this->eyeHeight, 0), new TotemUseSound());
|
||||||
|
|
||||||
$hand = $this->inventory->getItemInHand();
|
$hand = $this->inventory->getItemInHand();
|
||||||
if($hand instanceof Totem){
|
if($hand instanceof Totem){
|
||||||
@ -412,10 +412,10 @@ class Human extends Living implements ProjectileSource, InventoryHolder{
|
|||||||
$pk->uuid = $this->getUniqueId();
|
$pk->uuid = $this->getUniqueId();
|
||||||
$pk->username = $this->getName();
|
$pk->username = $this->getName();
|
||||||
$pk->entityRuntimeId = $this->getId();
|
$pk->entityRuntimeId = $this->getId();
|
||||||
$pk->position = $this->asVector3();
|
$pk->position = $this->location->asVector3();
|
||||||
$pk->motion = $this->getMotion();
|
$pk->motion = $this->getMotion();
|
||||||
$pk->yaw = $this->yaw;
|
$pk->yaw = $this->location->yaw;
|
||||||
$pk->pitch = $this->pitch;
|
$pk->pitch = $this->location->pitch;
|
||||||
$pk->item = $this->getInventory()->getItemInHand();
|
$pk->item = $this->getInventory()->getItemInHand();
|
||||||
$pk->metadata = $this->getSyncedNetworkData(false);
|
$pk->metadata = $this->getSyncedNetworkData(false);
|
||||||
$player->sendDataPacket($pk);
|
$player->sendDataPacket($pk);
|
||||||
|
@ -380,7 +380,7 @@ abstract class Living extends Entity{
|
|||||||
private function damageItem(Durable $item, int $durabilityRemoved) : void{
|
private function damageItem(Durable $item, int $durabilityRemoved) : void{
|
||||||
$item->applyDamage($durabilityRemoved);
|
$item->applyDamage($durabilityRemoved);
|
||||||
if($item->isBroken()){
|
if($item->isBroken()){
|
||||||
$this->world->addSound($this, new ItemBreakSound());
|
$this->getWorld()->addSound($this->location, new ItemBreakSound());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -434,11 +434,11 @@ abstract class Living extends Entity{
|
|||||||
$source->getCause() === EntityDamageEvent::CAUSE_PROJECTILE or
|
$source->getCause() === EntityDamageEvent::CAUSE_PROJECTILE or
|
||||||
$source->getCause() === EntityDamageEvent::CAUSE_ENTITY_ATTACK
|
$source->getCause() === EntityDamageEvent::CAUSE_ENTITY_ATTACK
|
||||||
) and $e->isOnFire()){
|
) and $e->isOnFire()){
|
||||||
$this->setOnFire(2 * $this->world->getDifficulty());
|
$this->setOnFire(2 * $this->getWorld()->getDifficulty());
|
||||||
}
|
}
|
||||||
|
|
||||||
$deltaX = $this->x - $e->x;
|
$deltaX = $this->location->x - $e->location->x;
|
||||||
$deltaZ = $this->z - $e->z;
|
$deltaZ = $this->location->z - $e->location->z;
|
||||||
$this->knockBack($deltaX, $deltaZ, $source->getKnockBack());
|
$this->knockBack($deltaX, $deltaZ, $source->getKnockBack());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -482,11 +482,11 @@ abstract class Living extends Entity{
|
|||||||
$ev = new EntityDeathEvent($this, $this->getDrops(), $this->getXpDropAmount());
|
$ev = new EntityDeathEvent($this, $this->getDrops(), $this->getXpDropAmount());
|
||||||
$ev->call();
|
$ev->call();
|
||||||
foreach($ev->getDrops() as $item){
|
foreach($ev->getDrops() as $item){
|
||||||
$this->getWorld()->dropItem($this, $item);
|
$this->getWorld()->dropItem($this->location, $item);
|
||||||
}
|
}
|
||||||
|
|
||||||
//TODO: check death conditions (must have been damaged by player < 5 seconds from death)
|
//TODO: check death conditions (must have been damaged by player < 5 seconds from death)
|
||||||
$this->world->dropExperience($this, $ev->getXpDropAmount());
|
$this->getWorld()->dropExperience($this->location, $ev->getXpDropAmount());
|
||||||
|
|
||||||
$this->startDeathAnimation();
|
$this->startDeathAnimation();
|
||||||
}
|
}
|
||||||
@ -684,8 +684,8 @@ abstract class Living extends Entity{
|
|||||||
$blocks = [];
|
$blocks = [];
|
||||||
$nextIndex = 0;
|
$nextIndex = 0;
|
||||||
|
|
||||||
foreach(VoxelRayTrace::inDirection($this->add(0, $this->eyeHeight, 0), $this->getDirectionVector(), $maxDistance) as $vector3){
|
foreach(VoxelRayTrace::inDirection($this->location->add(0, $this->eyeHeight, 0), $this->getDirectionVector(), $maxDistance) as $vector3){
|
||||||
$block = $this->world->getBlockAt($vector3->x, $vector3->y, $vector3->z);
|
$block = $this->getWorld()->getBlockAt($vector3->x, $vector3->y, $vector3->z);
|
||||||
$blocks[$nextIndex++] = $block;
|
$blocks[$nextIndex++] = $block;
|
||||||
|
|
||||||
if($maxLength !== 0 and count($blocks) > $maxLength){
|
if($maxLength !== 0 and count($blocks) > $maxLength){
|
||||||
@ -731,15 +731,15 @@ abstract class Living extends Entity{
|
|||||||
* @param Vector3 $target
|
* @param Vector3 $target
|
||||||
*/
|
*/
|
||||||
public function lookAt(Vector3 $target) : void{
|
public function lookAt(Vector3 $target) : void{
|
||||||
$horizontal = sqrt(($target->x - $this->x) ** 2 + ($target->z - $this->z) ** 2);
|
$horizontal = sqrt(($target->x - $this->location->x) ** 2 + ($target->z - $this->location->z) ** 2);
|
||||||
$vertical = $target->y - $this->y;
|
$vertical = $target->y - $this->location->y;
|
||||||
$this->pitch = -atan2($vertical, $horizontal) / M_PI * 180; //negative is up, positive is down
|
$this->location->pitch = -atan2($vertical, $horizontal) / M_PI * 180; //negative is up, positive is down
|
||||||
|
|
||||||
$xDist = $target->x - $this->x;
|
$xDist = $target->x - $this->location->x;
|
||||||
$zDist = $target->z - $this->z;
|
$zDist = $target->z - $this->location->z;
|
||||||
$this->yaw = atan2($zDist, $xDist) / M_PI * 180 - 90;
|
$this->location->yaw = atan2($zDist, $xDist) / M_PI * 180 - 90;
|
||||||
if($this->yaw < 0){
|
if($this->location->yaw < 0){
|
||||||
$this->yaw += 360.0;
|
$this->location->yaw += 360.0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -66,7 +66,7 @@ class Squid extends WaterAnimal{
|
|||||||
$this->swimSpeed = mt_rand(150, 350) / 2000;
|
$this->swimSpeed = mt_rand(150, 350) / 2000;
|
||||||
$e = $source->getDamager();
|
$e = $source->getDamager();
|
||||||
if($e !== null){
|
if($e !== null){
|
||||||
$this->swimDirection = (new Vector3($this->x - $e->x, $this->y - $e->y, $this->z - $e->z))->normalize();
|
$this->swimDirection = $this->location->subtract($e->location)->normalize();
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->broadcastEntityEvent(ActorEventPacket::SQUID_INK_CLOUD);
|
$this->broadcastEntityEvent(ActorEventPacket::SQUID_INK_CLOUD);
|
||||||
@ -94,7 +94,7 @@ class Squid extends WaterAnimal{
|
|||||||
|
|
||||||
if($this->isAlive()){
|
if($this->isAlive()){
|
||||||
|
|
||||||
if($this->y > 62 and $this->swimDirection !== null){
|
if($this->location->y > 62 and $this->swimDirection !== null){
|
||||||
$this->swimDirection->y = -0.5;
|
$this->swimDirection->y = -0.5;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -112,8 +112,8 @@ class Squid extends WaterAnimal{
|
|||||||
}
|
}
|
||||||
|
|
||||||
$f = sqrt(($this->motion->x ** 2) + ($this->motion->z ** 2));
|
$f = sqrt(($this->motion->x ** 2) + ($this->motion->z ** 2));
|
||||||
$this->yaw = (-atan2($this->motion->x, $this->motion->z) * 180 / M_PI);
|
$this->location->yaw = (-atan2($this->motion->x, $this->motion->z) * 180 / M_PI);
|
||||||
$this->pitch = (-atan2($f, $this->motion->y) * 180 / M_PI);
|
$this->location->pitch = (-atan2($f, $this->motion->y) * 180 / M_PI);
|
||||||
}
|
}
|
||||||
|
|
||||||
return $hasUpdate;
|
return $hasUpdate;
|
||||||
|
@ -156,7 +156,7 @@ class ExperienceOrb extends Entity{
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
$entity = $this->world->getEntity($this->targetPlayerRuntimeId);
|
$entity = $this->getWorld()->getEntity($this->targetPlayerRuntimeId);
|
||||||
if($entity instanceof Human){
|
if($entity instanceof Human){
|
||||||
return $entity;
|
return $entity;
|
||||||
}
|
}
|
||||||
@ -178,13 +178,13 @@ class ExperienceOrb extends Entity{
|
|||||||
}
|
}
|
||||||
|
|
||||||
$currentTarget = $this->getTargetPlayer();
|
$currentTarget = $this->getTargetPlayer();
|
||||||
if($currentTarget !== null and (!$currentTarget->isAlive() or $currentTarget->distanceSquared($this) > self::MAX_TARGET_DISTANCE ** 2)){
|
if($currentTarget !== null and (!$currentTarget->isAlive() or $currentTarget->location->distanceSquared($this->location) > self::MAX_TARGET_DISTANCE ** 2)){
|
||||||
$currentTarget = null;
|
$currentTarget = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
if($this->lookForTargetTime >= 20){
|
if($this->lookForTargetTime >= 20){
|
||||||
if($currentTarget === null){
|
if($currentTarget === null){
|
||||||
$newTarget = $this->world->getNearestEntity($this, self::MAX_TARGET_DISTANCE, Human::class);
|
$newTarget = $this->getWorld()->getNearestEntity($this->location, self::MAX_TARGET_DISTANCE, Human::class);
|
||||||
|
|
||||||
if($newTarget instanceof Human and !($newTarget instanceof Player and $newTarget->isSpectator())){
|
if($newTarget instanceof Human and !($newTarget instanceof Player and $newTarget->isSpectator())){
|
||||||
$currentTarget = $newTarget;
|
$currentTarget = $newTarget;
|
||||||
@ -199,7 +199,7 @@ class ExperienceOrb extends Entity{
|
|||||||
$this->setTargetPlayer($currentTarget);
|
$this->setTargetPlayer($currentTarget);
|
||||||
|
|
||||||
if($currentTarget !== null){
|
if($currentTarget !== null){
|
||||||
$vector = $currentTarget->add(0, $currentTarget->getEyeHeight() / 2, 0)->subtract($this)->divide(self::MAX_TARGET_DISTANCE);
|
$vector = $currentTarget->getPosition()->add(0, $currentTarget->getEyeHeight() / 2, 0)->subtract($this)->divide(self::MAX_TARGET_DISTANCE);
|
||||||
|
|
||||||
$distance = $vector->lengthSquared();
|
$distance = $vector->lengthSquared();
|
||||||
if($distance < 1){
|
if($distance < 1){
|
||||||
@ -221,7 +221,7 @@ class ExperienceOrb extends Entity{
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected function tryChangeMovement() : void{
|
protected function tryChangeMovement() : void{
|
||||||
$this->checkObstruction($this->x, $this->y, $this->z);
|
$this->checkObstruction($this->location->x, $this->location->y, $this->location->z);
|
||||||
parent::tryChangeMovement();
|
parent::tryChangeMovement();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -96,9 +96,10 @@ class FallingBlock extends Entity{
|
|||||||
$hasUpdate = parent::entityBaseTick($tickDiff);
|
$hasUpdate = parent::entityBaseTick($tickDiff);
|
||||||
|
|
||||||
if(!$this->isFlaggedForDespawn()){
|
if(!$this->isFlaggedForDespawn()){
|
||||||
$pos = $this->add(-$this->width / 2, $this->height, -$this->width / 2)->floor();
|
$world = $this->getWorld();
|
||||||
|
$pos = $this->location->add(-$this->width / 2, $this->height, -$this->width / 2)->floor();
|
||||||
|
|
||||||
$this->block->position($this->world, $pos->x, $pos->y, $pos->z);
|
$this->block->position($world, $pos->x, $pos->y, $pos->z);
|
||||||
|
|
||||||
$blockTarget = null;
|
$blockTarget = null;
|
||||||
if($this->block instanceof Fallable){
|
if($this->block instanceof Fallable){
|
||||||
@ -108,15 +109,15 @@ class FallingBlock extends Entity{
|
|||||||
if($this->onGround or $blockTarget !== null){
|
if($this->onGround or $blockTarget !== null){
|
||||||
$this->flagForDespawn();
|
$this->flagForDespawn();
|
||||||
|
|
||||||
$block = $this->world->getBlock($pos);
|
$block = $world->getBlock($pos);
|
||||||
if(($block->isTransparent() and !$block->canBeReplaced()) or !$this->world->isInWorld($pos->getFloorX(), $pos->getFloorY(), $pos->getFloorZ()) or ($this->onGround and abs($this->y - $this->getFloorY()) > 0.001)){
|
if(($block->isTransparent() and !$block->canBeReplaced()) or !$world->isInWorld($pos->getFloorX(), $pos->getFloorY(), $pos->getFloorZ()) or ($this->onGround and abs($this->location->y - $this->location->getFloorY()) > 0.001)){
|
||||||
//FIXME: anvils are supposed to destroy torches
|
//FIXME: anvils are supposed to destroy torches
|
||||||
$this->getWorld()->dropItem($this, $this->block->asItem());
|
$world->dropItem($this->location, $this->block->asItem());
|
||||||
}else{
|
}else{
|
||||||
$ev = new EntityBlockChangeEvent($this, $block, $blockTarget ?? $this->block);
|
$ev = new EntityBlockChangeEvent($this, $block, $blockTarget ?? $this->block);
|
||||||
$ev->call();
|
$ev->call();
|
||||||
if(!$ev->isCancelled()){
|
if(!$ev->isCancelled()){
|
||||||
$this->getWorld()->setBlock($pos, $ev->getTo());
|
$world->setBlock($pos, $ev->getTo());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
$hasUpdate = true;
|
$hasUpdate = true;
|
||||||
|
@ -125,7 +125,7 @@ class ItemEntity extends Entity{
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected function tryChangeMovement() : void{
|
protected function tryChangeMovement() : void{
|
||||||
$this->checkObstruction($this->x, $this->y, $this->z);
|
$this->checkObstruction($this->location->x, $this->location->y, $this->location->z);
|
||||||
parent::tryChangeMovement();
|
parent::tryChangeMovement();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -235,7 +235,7 @@ class ItemEntity extends Entity{
|
|||||||
protected function sendSpawnPacket(Player $player) : void{
|
protected function sendSpawnPacket(Player $player) : void{
|
||||||
$pk = new AddItemActorPacket();
|
$pk = new AddItemActorPacket();
|
||||||
$pk->entityRuntimeId = $this->getId();
|
$pk->entityRuntimeId = $this->getId();
|
||||||
$pk->position = $this->asVector3();
|
$pk->position = $this->location->asVector3();
|
||||||
$pk->motion = $this->getMotion();
|
$pk->motion = $this->getMotion();
|
||||||
$pk->item = $this->getItem();
|
$pk->item = $this->getItem();
|
||||||
$pk->metadata = $this->getSyncedNetworkData(false);
|
$pk->metadata = $this->getSyncedNetworkData(false);
|
||||||
|
@ -118,9 +118,9 @@ class Painting extends Entity{
|
|||||||
|
|
||||||
if($drops){
|
if($drops){
|
||||||
//non-living entities don't have a way to create drops generically yet
|
//non-living entities don't have a way to create drops generically yet
|
||||||
$this->world->dropItem($this, VanillaItems::PAINTING());
|
$this->getWorld()->dropItem($this->location, VanillaItems::PAINTING());
|
||||||
}
|
}
|
||||||
$this->world->addParticle($this->add(0.5, 0.5, 0.5), new DestroyBlockParticle(VanillaBlocks::OAK_PLANKS()));
|
$this->getWorld()->addParticle($this->location->add(0.5, 0.5, 0.5), new DestroyBlockParticle(VanillaBlocks::OAK_PLANKS()));
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function recalculateBoundingBox() : void{
|
protected function recalculateBoundingBox() : void{
|
||||||
@ -131,7 +131,7 @@ class Painting extends Entity{
|
|||||||
public function onNearbyBlockChange() : void{
|
public function onNearbyBlockChange() : void{
|
||||||
parent::onNearbyBlockChange();
|
parent::onNearbyBlockChange();
|
||||||
|
|
||||||
if(!self::canFit($this->world, $this->blockIn->getSide($this->facing), $this->facing, false, $this->getMotive())){
|
if(!self::canFit($this->getWorld(), $this->blockIn->getSide($this->facing), $this->facing, false, $this->getMotive())){
|
||||||
$this->kill();
|
$this->kill();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -62,7 +62,7 @@ class PrimedTNT extends Entity implements Explosive{
|
|||||||
|
|
||||||
$this->fuse = $nbt->getShort("Fuse", 80, true);
|
$this->fuse = $nbt->getShort("Fuse", 80, true);
|
||||||
|
|
||||||
$this->world->addSound($this, new IgniteSound());
|
$this->getWorld()->addSound($this->location, new IgniteSound());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -100,7 +100,7 @@ class PrimedTNT extends Entity implements Explosive{
|
|||||||
$ev = new ExplosionPrimeEvent($this, 4);
|
$ev = new ExplosionPrimeEvent($this, 4);
|
||||||
$ev->call();
|
$ev->call();
|
||||||
if(!$ev->isCancelled()){
|
if(!$ev->isCancelled()){
|
||||||
$explosion = new Explosion(Position::fromObject($this->add(0, $this->height / 2, 0), $this->world), $ev->getForce(), $this);
|
$explosion = new Explosion(Position::fromObject($this->location->add(0, $this->height / 2, 0), $this->getWorld()), $ev->getForce(), $this);
|
||||||
if($ev->isBlockBreaking()){
|
if($ev->isBlockBreaking()){
|
||||||
$explosion->explodeA();
|
$explosion->explodeA();
|
||||||
}
|
}
|
||||||
|
@ -142,7 +142,7 @@ class Arrow extends Projectile{
|
|||||||
|
|
||||||
protected function onHit(ProjectileHitEvent $event) : void{
|
protected function onHit(ProjectileHitEvent $event) : void{
|
||||||
$this->setCritical(false);
|
$this->setCritical(false);
|
||||||
$this->world->addSound($this, new ArrowHitSound());
|
$this->getWorld()->addSound($this->location, new ArrowHitSound());
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function onHitBlock(Block $blockHit, RayTraceResult $hitResult) : void{
|
protected function onHitBlock(Block $blockHit, RayTraceResult $hitResult) : void{
|
||||||
|
@ -35,7 +35,7 @@ class Egg extends Throwable{
|
|||||||
|
|
||||||
protected function onHit(ProjectileHitEvent $event) : void{
|
protected function onHit(ProjectileHitEvent $event) : void{
|
||||||
for($i = 0; $i < 6; ++$i){
|
for($i = 0; $i < 6; ++$i){
|
||||||
$this->world->addParticle($this, new ItemBreakParticle(VanillaItems::EGG()));
|
$this->getWorld()->addParticle($this->location, new ItemBreakParticle(VanillaItems::EGG()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -33,6 +33,7 @@ use pocketmine\math\Vector3;
|
|||||||
use pocketmine\network\mcpe\protocol\types\entity\EntityLegacyIds;
|
use pocketmine\network\mcpe\protocol\types\entity\EntityLegacyIds;
|
||||||
use pocketmine\world\particle\EndermanTeleportParticle;
|
use pocketmine\world\particle\EndermanTeleportParticle;
|
||||||
use pocketmine\world\sound\EndermanTeleportSound;
|
use pocketmine\world\sound\EndermanTeleportSound;
|
||||||
|
use function get_class;
|
||||||
|
|
||||||
class EnderPearl extends Throwable{
|
class EnderPearl extends Throwable{
|
||||||
public const NETWORK_ID = EntityLegacyIds::ENDER_PEARL;
|
public const NETWORK_ID = EntityLegacyIds::ENDER_PEARL;
|
||||||
@ -53,10 +54,10 @@ class EnderPearl extends Throwable{
|
|||||||
//TODO: check end gateways (when they are added)
|
//TODO: check end gateways (when they are added)
|
||||||
//TODO: spawn endermites at origin
|
//TODO: spawn endermites at origin
|
||||||
|
|
||||||
$this->world->addParticle($owner, new EndermanTeleportParticle());
|
$this->getWorld()->addParticle($origin = $owner->getPosition(), new EndermanTeleportParticle());
|
||||||
$this->world->addSound($owner, new EndermanTeleportSound());
|
$this->getWorld()->addSound($origin, new EndermanTeleportSound());
|
||||||
$owner->teleport($target = $event->getRayTraceResult()->getHitVector());
|
$owner->teleport($target = $event->getRayTraceResult()->getHitVector());
|
||||||
$this->world->addSound($target, new EndermanTeleportSound());
|
$this->getWorld()->addSound($target, new EndermanTeleportSound());
|
||||||
|
|
||||||
$owner->attack(new EntityDamageEvent($owner, EntityDamageEvent::CAUSE_FALL, 5));
|
$owner->attack(new EntityDamageEvent($owner, EntityDamageEvent::CAUSE_FALL, 5));
|
||||||
}
|
}
|
||||||
|
@ -39,9 +39,9 @@ class ExperienceBottle extends Throwable{
|
|||||||
}
|
}
|
||||||
|
|
||||||
public function onHit(ProjectileHitEvent $event) : void{
|
public function onHit(ProjectileHitEvent $event) : void{
|
||||||
$this->world->addParticle($this, new PotionSplashParticle(PotionSplashParticle::DEFAULT_COLOR()));
|
$this->getWorld()->addParticle($this->location, new PotionSplashParticle(PotionSplashParticle::DEFAULT_COLOR()));
|
||||||
$this->world->addSound($this, new PotionSplashSound());
|
$this->getWorld()->addSound($this->location, new PotionSplashSound());
|
||||||
|
|
||||||
$this->world->dropExperience($this, mt_rand(3, 11));
|
$this->getWorld()->dropExperience($this->location, mt_rand(3, 11));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -84,7 +84,7 @@ abstract class Projectile extends Entity{
|
|||||||
$blockData = null;
|
$blockData = null;
|
||||||
|
|
||||||
if($nbt->hasTag("tileX", IntTag::class) and $nbt->hasTag("tileY", IntTag::class) and $nbt->hasTag("tileZ", IntTag::class)){
|
if($nbt->hasTag("tileX", IntTag::class) and $nbt->hasTag("tileY", IntTag::class) and $nbt->hasTag("tileZ", IntTag::class)){
|
||||||
$blockPos = new Position($nbt->getInt("tileX"), $nbt->getInt("tileY"), $nbt->getInt("tileZ"), $this->world);
|
$blockPos = new Position($nbt->getInt("tileX"), $nbt->getInt("tileY"), $nbt->getInt("tileZ"), $this->getWorld());
|
||||||
}else{
|
}else{
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -164,7 +164,7 @@ abstract class Projectile extends Entity{
|
|||||||
}
|
}
|
||||||
|
|
||||||
public function onNearbyBlockChange() : void{
|
public function onNearbyBlockChange() : void{
|
||||||
if($this->blockHit !== null and $this->world->isInLoadedTerrain($this->blockHit->getPos()) and !$this->blockHit->isSameState($this->world->getBlock($this->blockHit->getPos()))){
|
if($this->blockHit !== null and $this->getWorld()->isInLoadedTerrain($this->blockHit->getPos()) and !$this->blockHit->isSameState($this->getWorld()->getBlock($this->blockHit->getPos()))){
|
||||||
$this->blockHit = null;
|
$this->blockHit = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -180,7 +180,7 @@ abstract class Projectile extends Entity{
|
|||||||
|
|
||||||
Timings::$entityMoveTimer->startTiming();
|
Timings::$entityMoveTimer->startTiming();
|
||||||
|
|
||||||
$start = $this->asVector3();
|
$start = $this->location->asVector3();
|
||||||
$end = $start->add($this->motion);
|
$end = $start->add($this->motion);
|
||||||
|
|
||||||
$blockHit = null;
|
$blockHit = null;
|
||||||
@ -188,7 +188,7 @@ abstract class Projectile extends Entity{
|
|||||||
$hitResult = null;
|
$hitResult = null;
|
||||||
|
|
||||||
foreach(VoxelRayTrace::betweenPoints($start, $end) as $vector3){
|
foreach(VoxelRayTrace::betweenPoints($start, $end) as $vector3){
|
||||||
$block = $this->world->getBlockAt($vector3->x, $vector3->y, $vector3->z);
|
$block = $this->getWorld()->getBlockAt($vector3->x, $vector3->y, $vector3->z);
|
||||||
|
|
||||||
$blockHitResult = $this->calculateInterceptWithBlock($block, $start, $end);
|
$blockHitResult = $this->calculateInterceptWithBlock($block, $start, $end);
|
||||||
if($blockHitResult !== null){
|
if($blockHitResult !== null){
|
||||||
@ -202,7 +202,7 @@ abstract class Projectile extends Entity{
|
|||||||
$entityDistance = PHP_INT_MAX;
|
$entityDistance = PHP_INT_MAX;
|
||||||
|
|
||||||
$newDiff = $end->subtract($start);
|
$newDiff = $end->subtract($start);
|
||||||
foreach($this->world->getCollidingEntities($this->boundingBox->addCoord($newDiff->x, $newDiff->y, $newDiff->z)->expand(1, 1, 1), $this) as $entity){
|
foreach($this->getWorld()->getCollidingEntities($this->boundingBox->addCoord($newDiff->x, $newDiff->y, $newDiff->z)->expand(1, 1, 1), $this) as $entity){
|
||||||
if($entity->getId() === $this->getOwningEntityId() and $this->ticksLived < 5){
|
if($entity->getId() === $this->getOwningEntityId() and $this->ticksLived < 5){
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@ -214,7 +214,7 @@ abstract class Projectile extends Entity{
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
$distance = $this->distanceSquared($entityHitResult->hitVector);
|
$distance = $this->location->distanceSquared($entityHitResult->hitVector);
|
||||||
|
|
||||||
if($distance < $entityDistance){
|
if($distance < $entityDistance){
|
||||||
$entityDistance = $distance;
|
$entityDistance = $distance;
|
||||||
@ -224,9 +224,9 @@ abstract class Projectile extends Entity{
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->x = $end->x;
|
$this->location->x = $end->x;
|
||||||
$this->y = $end->y;
|
$this->location->y = $end->y;
|
||||||
$this->z = $end->z;
|
$this->location->z = $end->z;
|
||||||
$this->recalculateBoundingBox();
|
$this->recalculateBoundingBox();
|
||||||
|
|
||||||
if($hitResult !== null){
|
if($hitResult !== null){
|
||||||
@ -259,8 +259,8 @@ abstract class Projectile extends Entity{
|
|||||||
|
|
||||||
//recompute angles...
|
//recompute angles...
|
||||||
$f = sqrt(($this->motion->x ** 2) + ($this->motion->z ** 2));
|
$f = sqrt(($this->motion->x ** 2) + ($this->motion->z ** 2));
|
||||||
$this->yaw = (atan2($this->motion->x, $this->motion->z) * 180 / M_PI);
|
$this->location->yaw = (atan2($this->motion->x, $this->motion->z) * 180 / M_PI);
|
||||||
$this->pitch = (atan2($this->motion->y, $f) * 180 / M_PI);
|
$this->location->pitch = (atan2($this->motion->y, $f) * 180 / M_PI);
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->checkChunks();
|
$this->checkChunks();
|
||||||
|
@ -32,7 +32,7 @@ class Snowball extends Throwable{
|
|||||||
|
|
||||||
protected function onHit(ProjectileHitEvent $event) : void{
|
protected function onHit(ProjectileHitEvent $event) : void{
|
||||||
for($i = 0; $i < 6; ++$i){
|
for($i = 0; $i < 6; ++$i){
|
||||||
$this->world->addParticle($this, new SnowballPoofParticle());
|
$this->getWorld()->addParticle($this->location, new SnowballPoofParticle());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -89,14 +89,14 @@ class SplashPotion extends Throwable{
|
|||||||
$particle = new PotionSplashParticle(Color::mix(...$colors));
|
$particle = new PotionSplashParticle(Color::mix(...$colors));
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->world->addParticle($this, $particle);
|
$this->getWorld()->addParticle($this->location, $particle);
|
||||||
$this->world->addSound($this, new PotionSplashSound());
|
$this->getWorld()->addSound($this->location, new PotionSplashSound());
|
||||||
|
|
||||||
if($hasEffects){
|
if($hasEffects){
|
||||||
if(!$this->willLinger()){
|
if(!$this->willLinger()){
|
||||||
foreach($this->world->getNearbyEntities($this->boundingBox->expandedCopy(4.125, 2.125, 4.125), $this) as $entity){
|
foreach($this->getWorld()->getNearbyEntities($this->boundingBox->expandedCopy(4.125, 2.125, 4.125), $this) as $entity){
|
||||||
if($entity instanceof Living and $entity->isAlive()){
|
if($entity instanceof Living and $entity->isAlive()){
|
||||||
$distanceSquared = $entity->getEyePos()->distanceSquared($this);
|
$distanceSquared = $entity->getEyePos()->distanceSquared($this->location);
|
||||||
if($distanceSquared > 16){ //4 blocks
|
if($distanceSquared > 16){ //4 blocks
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@ -129,11 +129,11 @@ class SplashPotion extends Throwable{
|
|||||||
$blockIn = $event->getBlockHit()->getSide($event->getRayTraceResult()->getHitFace());
|
$blockIn = $event->getBlockHit()->getSide($event->getRayTraceResult()->getHitFace());
|
||||||
|
|
||||||
if($blockIn->getId() === BlockLegacyIds::FIRE){
|
if($blockIn->getId() === BlockLegacyIds::FIRE){
|
||||||
$this->world->setBlock($blockIn->getPos(), VanillaBlocks::AIR());
|
$this->getWorld()->setBlock($blockIn->getPos(), VanillaBlocks::AIR());
|
||||||
}
|
}
|
||||||
foreach($blockIn->getHorizontalSides() as $horizontalSide){
|
foreach($blockIn->getHorizontalSides() as $horizontalSide){
|
||||||
if($horizontalSide->getId() === BlockLegacyIds::FIRE){
|
if($horizontalSide->getId() === BlockLegacyIds::FIRE){
|
||||||
$this->world->setBlock($horizontalSide->getPos(), VanillaBlocks::AIR());
|
$this->getWorld()->setBlock($horizontalSide->getPos(), VanillaBlocks::AIR());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -50,11 +50,12 @@ class Bow extends Tool{
|
|||||||
return ItemUseResult::FAIL();
|
return ItemUseResult::FAIL();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$location = $player->getLocation();
|
||||||
$nbt = EntityFactory::createBaseNBT(
|
$nbt = EntityFactory::createBaseNBT(
|
||||||
$player->getEyePos(),
|
$player->getEyePos(),
|
||||||
$player->getDirectionVector(),
|
$player->getDirectionVector(),
|
||||||
($player->yaw > 180 ? 360 : 0) - $player->yaw,
|
($location->yaw > 180 ? 360 : 0) - $location->yaw,
|
||||||
-$player->pitch
|
-$location->pitch
|
||||||
);
|
);
|
||||||
$nbt->setShort("Fire", $player->isOnFire() ? 45 * 60 : 0);
|
$nbt->setShort("Fire", $player->isOnFire() ? 45 * 60 : 0);
|
||||||
|
|
||||||
@ -63,7 +64,7 @@ class Bow extends Tool{
|
|||||||
$baseForce = min((($p ** 2) + $p * 2) / 3, 1);
|
$baseForce = min((($p ** 2) + $p * 2) / 3, 1);
|
||||||
|
|
||||||
/** @var ArrowEntity $entity */
|
/** @var ArrowEntity $entity */
|
||||||
$entity = EntityFactory::create(ArrowEntity::class, $player->getWorld(), $nbt, $player, $baseForce >= 1);
|
$entity = EntityFactory::create(ArrowEntity::class, $location->getWorld(), $nbt, $player, $baseForce >= 1);
|
||||||
|
|
||||||
$infinity = $this->hasEnchantment(Enchantment::INFINITY());
|
$infinity = $this->hasEnchantment(Enchantment::INFINITY());
|
||||||
if($infinity){
|
if($infinity){
|
||||||
@ -104,7 +105,7 @@ class Bow extends Tool{
|
|||||||
}
|
}
|
||||||
|
|
||||||
$ev->getProjectile()->spawnToAll();
|
$ev->getProjectile()->spawnToAll();
|
||||||
$player->getWorld()->addSound($player, new BowShootSound());
|
$location->getWorld()->addSound($location, new BowShootSound());
|
||||||
}else{
|
}else{
|
||||||
$entity->spawnToAll();
|
$entity->spawnToAll();
|
||||||
}
|
}
|
||||||
|
@ -49,9 +49,10 @@ class ChorusFruit extends Food{
|
|||||||
$world = $consumer->getWorld();
|
$world = $consumer->getWorld();
|
||||||
assert($world !== null);
|
assert($world !== null);
|
||||||
|
|
||||||
$minX = $consumer->getFloorX() - 8;
|
$origin = $consumer->getPosition();
|
||||||
$minY = min($consumer->getFloorY(), $consumer->getWorld()->getWorldHeight()) - 8;
|
$minX = $origin->getFloorX() - 8;
|
||||||
$minZ = $consumer->getFloorZ() - 8;
|
$minY = min($origin->getFloorY(), $consumer->getWorld()->getWorldHeight()) - 8;
|
||||||
|
$minZ = $origin->getFloorZ() - 8;
|
||||||
|
|
||||||
$maxX = $minX + 16;
|
$maxX = $minX + 16;
|
||||||
$maxY = $minY + 16;
|
$maxY = $minY + 16;
|
||||||
@ -76,7 +77,7 @@ class ChorusFruit extends Food{
|
|||||||
}
|
}
|
||||||
|
|
||||||
//Sounds are broadcasted at both source and destination
|
//Sounds are broadcasted at both source and destination
|
||||||
$world->addSound($consumer->asVector3(), new EndermanTeleportSound());
|
$world->addSound($origin, new EndermanTeleportSound());
|
||||||
$consumer->teleport($target = new Vector3($x + 0.5, $y + 1, $z + 0.5));
|
$consumer->teleport($target = new Vector3($x + 0.5, $y + 1, $z + 0.5));
|
||||||
$world->addSound($target, new EndermanTeleportSound());
|
$world->addSound($target, new EndermanTeleportSound());
|
||||||
|
|
||||||
|
@ -53,14 +53,15 @@ abstract class ProjectileItem extends Item{
|
|||||||
}
|
}
|
||||||
|
|
||||||
public function onClickAir(Player $player, Vector3 $directionVector) : ItemUseResult{
|
public function onClickAir(Player $player, Vector3 $directionVector) : ItemUseResult{
|
||||||
$nbt = EntityFactory::createBaseNBT($player->getEyePos(), $directionVector, $player->yaw, $player->pitch);
|
$location = $player->getLocation();
|
||||||
|
$nbt = EntityFactory::createBaseNBT($player->getEyePos(), $directionVector, $location->yaw, $location->pitch);
|
||||||
$this->addExtraTags($nbt);
|
$this->addExtraTags($nbt);
|
||||||
|
|
||||||
$class = $this->getProjectileEntityClass();
|
$class = $this->getProjectileEntityClass();
|
||||||
Utils::testValidInstance($class, Throwable::class);
|
Utils::testValidInstance($class, Throwable::class);
|
||||||
|
|
||||||
/** @var Throwable $projectile */
|
/** @var Throwable $projectile */
|
||||||
$projectile = EntityFactory::create($class, $player->getWorld(), $nbt, $player);
|
$projectile = EntityFactory::create($class, $location->getWorld(), $nbt, $player);
|
||||||
$projectile->setMotion($projectile->getMotion()->multiply($this->getThrowForce()));
|
$projectile->setMotion($projectile->getMotion()->multiply($this->getThrowForce()));
|
||||||
|
|
||||||
$projectileEv = new ProjectileLaunchEvent($projectile);
|
$projectileEv = new ProjectileLaunchEvent($projectile);
|
||||||
@ -72,7 +73,7 @@ abstract class ProjectileItem extends Item{
|
|||||||
|
|
||||||
$projectile->spawnToAll();
|
$projectile->spawnToAll();
|
||||||
|
|
||||||
$player->getWorld()->addSound($player, new ThrowSound());
|
$location->getWorld()->addSound($location, new ThrowSound());
|
||||||
|
|
||||||
$this->pop();
|
$this->pop();
|
||||||
|
|
||||||
|
@ -38,7 +38,8 @@ class KnockbackEnchantment extends MeleeWeaponEnchantment{
|
|||||||
|
|
||||||
public function onPostAttack(Entity $attacker, Entity $victim, int $enchantmentLevel) : void{
|
public function onPostAttack(Entity $attacker, Entity $victim, int $enchantmentLevel) : void{
|
||||||
if($victim instanceof Living){
|
if($victim instanceof Living){
|
||||||
$victim->knockBack($victim->x - $attacker->x, $victim->z - $attacker->z, $enchantmentLevel * 0.5);
|
$diff = $victim->getPosition()->subtract($attacker->getPosition());
|
||||||
|
$victim->knockBack($diff->x, $diff->z, $enchantmentLevel * 0.5);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -623,8 +623,9 @@ class NetworkSession{
|
|||||||
}
|
}
|
||||||
|
|
||||||
public function syncMovement(Vector3 $pos, ?float $yaw = null, ?float $pitch = null, int $mode = MovePlayerPacket::MODE_NORMAL) : void{
|
public function syncMovement(Vector3 $pos, ?float $yaw = null, ?float $pitch = null, int $mode = MovePlayerPacket::MODE_NORMAL) : void{
|
||||||
$yaw = $yaw ?? $this->player->getYaw();
|
$location = $this->player->getLocation();
|
||||||
$pitch = $pitch ?? $this->player->getPitch();
|
$yaw = $yaw ?? $location->getYaw();
|
||||||
|
$pitch = $pitch ?? $location->getPitch();
|
||||||
|
|
||||||
$pk = new MovePlayerPacket();
|
$pk = new MovePlayerPacket();
|
||||||
$pk->entityRuntimeId = $this->player->getId();
|
$pk->entityRuntimeId = $this->player->getId();
|
||||||
@ -767,7 +768,7 @@ class NetworkSession{
|
|||||||
public function startUsingChunk(int $chunkX, int $chunkZ, \Closure $onCompletion) : void{
|
public function startUsingChunk(int $chunkX, int $chunkZ, \Closure $onCompletion) : void{
|
||||||
Utils::validateCallableSignature(function(int $chunkX, int $chunkZ){}, $onCompletion);
|
Utils::validateCallableSignature(function(int $chunkX, int $chunkZ){}, $onCompletion);
|
||||||
|
|
||||||
$world = $this->player->getWorld();
|
$world = $this->player->getLocation()->getWorld();
|
||||||
assert($world !== null);
|
assert($world !== null);
|
||||||
ChunkCache::getInstance($world)->request($chunkX, $chunkZ)->onResolve(
|
ChunkCache::getInstance($world)->request($chunkX, $chunkZ)->onResolve(
|
||||||
|
|
||||||
@ -776,16 +777,17 @@ class NetworkSession{
|
|||||||
if(!$this->isConnected()){
|
if(!$this->isConnected()){
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if($world !== $this->player->getWorld() or !$this->player->isUsingChunk($chunkX, $chunkZ)){
|
$currentWorld = $this->player->getLocation()->getWorld();
|
||||||
|
if($world !== $currentWorld or !$this->player->isUsingChunk($chunkX, $chunkZ)){
|
||||||
$this->logger->debug("Tried to send no-longer-active chunk $chunkX $chunkZ in world " . $world->getFolderName());
|
$this->logger->debug("Tried to send no-longer-active chunk $chunkX $chunkZ in world " . $world->getFolderName());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
$this->player->world->timings->syncChunkSendTimer->startTiming();
|
$currentWorld->timings->syncChunkSendTimer->startTiming();
|
||||||
try{
|
try{
|
||||||
$this->queueCompressed($promise);
|
$this->queueCompressed($promise);
|
||||||
$onCompletion($chunkX, $chunkZ);
|
$onCompletion($chunkX, $chunkZ);
|
||||||
}finally{
|
}finally{
|
||||||
$this->player->world->timings->syncChunkSendTimer->stopTiming();
|
$currentWorld->timings->syncChunkSendTimer->stopTiming();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
@ -301,7 +301,7 @@ class InGamePacketHandler extends PacketHandler{
|
|||||||
*/
|
*/
|
||||||
private function onFailedBlockAction(Vector3 $blockPos, ?int $face) : void{
|
private function onFailedBlockAction(Vector3 $blockPos, ?int $face) : void{
|
||||||
$this->session->getInvManager()->syncSlot($this->player->getInventory(), $this->player->getInventory()->getHeldItemIndex());
|
$this->session->getInvManager()->syncSlot($this->player->getInventory(), $this->player->getInventory()->getHeldItemIndex());
|
||||||
if($blockPos->distanceSquared($this->player) < 10000){
|
if($blockPos->distanceSquared($this->player->getLocation()) < 10000){
|
||||||
$blocks = $blockPos->sidesArray();
|
$blocks = $blockPos->sidesArray();
|
||||||
if($face !== null){
|
if($face !== null){
|
||||||
$sidePos = $blockPos->getSide($face);
|
$sidePos = $blockPos->getSide($face);
|
||||||
@ -311,7 +311,7 @@ class InGamePacketHandler extends PacketHandler{
|
|||||||
}else{
|
}else{
|
||||||
$blocks[] = $blockPos;
|
$blocks[] = $blockPos;
|
||||||
}
|
}
|
||||||
$this->player->getWorld()->sendBlocks([$this->player], $blocks);
|
$this->player->getLocation()->getWorld()->sendBlocks([$this->player], $blocks);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -510,11 +510,11 @@ class InGamePacketHandler extends PacketHandler{
|
|||||||
|
|
||||||
public function handleBlockActorData(BlockActorDataPacket $packet) : bool{
|
public function handleBlockActorData(BlockActorDataPacket $packet) : bool{
|
||||||
$pos = new Vector3($packet->x, $packet->y, $packet->z);
|
$pos = new Vector3($packet->x, $packet->y, $packet->z);
|
||||||
if($pos->distanceSquared($this->player) > 10000){
|
if($pos->distanceSquared($this->player->getLocation()) > 10000){
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
$block = $this->player->getWorld()->getBlock($pos);
|
$block = $this->player->getLocation()->getWorld()->getBlock($pos);
|
||||||
try{
|
try{
|
||||||
$offset = 0;
|
$offset = 0;
|
||||||
$nbt = (new NetworkNbtSerializer())->read($packet->namedtag, $offset, 512)->getTag();
|
$nbt = (new NetworkNbtSerializer())->read($packet->namedtag, $offset, 512)->getTag();
|
||||||
@ -703,7 +703,7 @@ class InGamePacketHandler extends PacketHandler{
|
|||||||
}
|
}
|
||||||
|
|
||||||
public function handleLevelSoundEvent(LevelSoundEventPacket $packet) : bool{
|
public function handleLevelSoundEvent(LevelSoundEventPacket $packet) : bool{
|
||||||
$this->player->getWorld()->broadcastPacketToViewers($this->player->asVector3(), $packet);
|
$this->player->getWorld()->broadcastPacketToViewers($this->player->getPosition(), $packet);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -53,23 +53,24 @@ class PreSpawnPacketHandler extends PacketHandler{
|
|||||||
|
|
||||||
public function setUp() : void{
|
public function setUp() : void{
|
||||||
$spawnPosition = $this->player->getSpawn();
|
$spawnPosition = $this->player->getSpawn();
|
||||||
|
$location = $this->player->getLocation();
|
||||||
|
|
||||||
$pk = new StartGamePacket();
|
$pk = new StartGamePacket();
|
||||||
$pk->entityUniqueId = $this->player->getId();
|
$pk->entityUniqueId = $this->player->getId();
|
||||||
$pk->entityRuntimeId = $this->player->getId();
|
$pk->entityRuntimeId = $this->player->getId();
|
||||||
$pk->playerGamemode = NetworkSession::getClientFriendlyGamemode($this->player->getGamemode());
|
$pk->playerGamemode = NetworkSession::getClientFriendlyGamemode($this->player->getGamemode());
|
||||||
$pk->playerPosition = $this->player->getOffsetPosition($this->player);
|
$pk->playerPosition = $this->player->getOffsetPosition($location);
|
||||||
$pk->pitch = $this->player->pitch;
|
$pk->pitch = $location->pitch;
|
||||||
$pk->yaw = $this->player->yaw;
|
$pk->yaw = $location->yaw;
|
||||||
$pk->seed = -1;
|
$pk->seed = -1;
|
||||||
$pk->dimension = DimensionIds::OVERWORLD; //TODO: implement this properly
|
$pk->dimension = DimensionIds::OVERWORLD; //TODO: implement this properly
|
||||||
$pk->worldGamemode = NetworkSession::getClientFriendlyGamemode($this->server->getGamemode());
|
$pk->worldGamemode = NetworkSession::getClientFriendlyGamemode($this->server->getGamemode());
|
||||||
$pk->difficulty = $this->player->getWorld()->getDifficulty();
|
$pk->difficulty = $location->getWorld()->getDifficulty();
|
||||||
$pk->spawnX = $spawnPosition->getFloorX();
|
$pk->spawnX = $spawnPosition->getFloorX();
|
||||||
$pk->spawnY = $spawnPosition->getFloorY();
|
$pk->spawnY = $spawnPosition->getFloorY();
|
||||||
$pk->spawnZ = $spawnPosition->getFloorZ();
|
$pk->spawnZ = $spawnPosition->getFloorZ();
|
||||||
$pk->hasAchievementsDisabled = true;
|
$pk->hasAchievementsDisabled = true;
|
||||||
$pk->time = $this->player->getWorld()->getTime();
|
$pk->time = $location->getWorld()->getTime();
|
||||||
$pk->eduMode = false;
|
$pk->eduMode = false;
|
||||||
$pk->rainLevel = 0; //TODO: implement these properly
|
$pk->rainLevel = 0; //TODO: implement these properly
|
||||||
$pk->lightningLevel = 0;
|
$pk->lightningLevel = 0;
|
||||||
|
@ -329,10 +329,10 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener,
|
|||||||
$this->networkSession->getIp(),
|
$this->networkSession->getIp(),
|
||||||
$this->networkSession->getPort(),
|
$this->networkSession->getPort(),
|
||||||
$this->id,
|
$this->id,
|
||||||
$this->world->getDisplayName(),
|
$this->getWorld()->getDisplayName(),
|
||||||
round($this->x, 4),
|
round($this->location->x, 4),
|
||||||
round($this->y, 4),
|
round($this->location->y, 4),
|
||||||
round($this->z, 4)
|
round($this->location->z, 4)
|
||||||
]));
|
]));
|
||||||
|
|
||||||
$this->server->addOnlinePlayer($this);
|
$this->server->addOnlinePlayer($this);
|
||||||
@ -368,7 +368,7 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener,
|
|||||||
if(($world = $this->server->getWorldManager()->getWorldByName($nbt->getString("SpawnLevel", ""))) instanceof World){
|
if(($world = $this->server->getWorldManager()->getWorldByName($nbt->getString("SpawnLevel", ""))) instanceof World){
|
||||||
$this->spawnPosition = new Position($nbt->getInt("SpawnX"), $nbt->getInt("SpawnY"), $nbt->getInt("SpawnZ"), $world);
|
$this->spawnPosition = new Position($nbt->getInt("SpawnX"), $nbt->getInt("SpawnY"), $nbt->getInt("SpawnZ"), $world);
|
||||||
}else{
|
}else{
|
||||||
$this->spawnPosition = $this->world->getSafeSpawn();
|
$this->spawnPosition = $this->getWorld()->getSafeSpawn();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -514,7 +514,7 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener,
|
|||||||
* @param Player $player
|
* @param Player $player
|
||||||
*/
|
*/
|
||||||
public function spawnTo(Player $player) : void{
|
public function spawnTo(Player $player) : void{
|
||||||
if($this->isAlive() and $player->isAlive() and $player->getWorld() === $this->world and $player->canSee($this) and !$this->isSpectator()){
|
if($this->isAlive() and $player->isAlive() and $player->getWorld() === $this->getWorld() and $player->canSee($this) and !$this->isSpectator()){
|
||||||
parent::spawnTo($player);
|
parent::spawnTo($player);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -802,7 +802,7 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener,
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected function switchWorld(World $targetWorld) : bool{
|
protected function switchWorld(World $targetWorld) : bool{
|
||||||
$oldWorld = $this->world;
|
$oldWorld = $this->getWorld();
|
||||||
if(parent::switchWorld($targetWorld)){
|
if(parent::switchWorld($targetWorld)){
|
||||||
if($oldWorld !== null){
|
if($oldWorld !== null){
|
||||||
foreach($this->usedChunks as $index => $d){
|
foreach($this->usedChunks as $index => $d){
|
||||||
@ -813,8 +813,8 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener,
|
|||||||
|
|
||||||
$this->usedChunks = [];
|
$this->usedChunks = [];
|
||||||
$this->loadQueue = [];
|
$this->loadQueue = [];
|
||||||
$this->world->sendTime($this);
|
$this->getWorld()->sendTime($this);
|
||||||
$this->world->sendDifficulty($this);
|
$this->getWorld()->sendDifficulty($this);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -823,7 +823,7 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener,
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected function unloadChunk(int $x, int $z, ?World $world = null){
|
protected function unloadChunk(int $x, int $z, ?World $world = null){
|
||||||
$world = $world ?? $this->world;
|
$world = $world ?? $this->getWorld();
|
||||||
$index = World::chunkHash($x, $z);
|
$index = World::chunkHash($x, $z);
|
||||||
if(isset($this->usedChunks[$index])){
|
if(isset($this->usedChunks[$index])){
|
||||||
foreach($world->getChunk($x, $z)->getEntities() as $entity){
|
foreach($world->getChunk($x, $z)->getEntities() as $entity){
|
||||||
@ -840,7 +840,7 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener,
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected function spawnEntitiesOnChunk(int $chunkX, int $chunkZ) : void{
|
protected function spawnEntitiesOnChunk(int $chunkX, int $chunkZ) : void{
|
||||||
foreach($this->world->getChunk($chunkX, $chunkZ)->getEntities() as $entity){
|
foreach($this->getWorld()->getChunk($chunkX, $chunkZ)->getEntities() as $entity){
|
||||||
if($entity !== $this and !$entity->isFlaggedForDespawn()){
|
if($entity !== $this and !$entity->isFlaggedForDespawn()){
|
||||||
$entity->spawnTo($this);
|
$entity->spawnTo($this);
|
||||||
}
|
}
|
||||||
@ -868,10 +868,10 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener,
|
|||||||
++$count;
|
++$count;
|
||||||
|
|
||||||
$this->usedChunks[$index] = false;
|
$this->usedChunks[$index] = false;
|
||||||
$this->world->registerChunkLoader($this, $X, $Z, true);
|
$this->getWorld()->registerChunkLoader($this, $X, $Z, true);
|
||||||
$this->world->registerChunkListener($this, $X, $Z);
|
$this->getWorld()->registerChunkListener($this, $X, $Z);
|
||||||
|
|
||||||
if(!$this->world->populateChunk($X, $Z)){
|
if(!$this->getWorld()->populateChunk($X, $Z)){
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -935,8 +935,8 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener,
|
|||||||
$radius = $this->server->getAllowedViewDistance($this->viewDistance);
|
$radius = $this->server->getAllowedViewDistance($this->viewDistance);
|
||||||
$radiusSquared = $radius ** 2;
|
$radiusSquared = $radius ** 2;
|
||||||
|
|
||||||
$centerX = $this->getFloorX() >> 4;
|
$centerX = $this->location->getFloorX() >> 4;
|
||||||
$centerZ = $this->getFloorZ() >> 4;
|
$centerZ = $this->location->getFloorZ() >> 4;
|
||||||
|
|
||||||
for($x = 0; $x < $radius; ++$x){
|
for($x = 0; $x < $radius; ++$x){
|
||||||
for($z = 0; $z <= $x; ++$z){
|
for($z = 0; $z <= $x; ++$z){
|
||||||
@ -993,7 +993,7 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener,
|
|||||||
|
|
||||||
$this->loadQueue = $newOrder;
|
$this->loadQueue = $newOrder;
|
||||||
if(!empty($this->loadQueue) or !empty($unloadChunks)){
|
if(!empty($this->loadQueue) or !empty($unloadChunks)){
|
||||||
$this->networkSession->syncViewAreaCenterPoint($this, $this->viewDistance);
|
$this->networkSession->syncViewAreaCenterPoint($this->location, $this->viewDistance);
|
||||||
}
|
}
|
||||||
|
|
||||||
Timings::$playerChunkOrderTimer->stopTiming();
|
Timings::$playerChunkOrderTimer->stopTiming();
|
||||||
@ -1042,7 +1042,7 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener,
|
|||||||
*/
|
*/
|
||||||
public function setSpawn(Vector3 $pos){
|
public function setSpawn(Vector3 $pos){
|
||||||
if(!($pos instanceof Position)){
|
if(!($pos instanceof Position)){
|
||||||
$world = $this->world;
|
$world = $this->getWorld();
|
||||||
}else{
|
}else{
|
||||||
$world = $pos->getWorld();
|
$world = $pos->getWorld();
|
||||||
}
|
}
|
||||||
@ -1064,7 +1064,7 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener,
|
|||||||
*/
|
*/
|
||||||
public function sleepOn(Vector3 $pos) : bool{
|
public function sleepOn(Vector3 $pos) : bool{
|
||||||
$pos = $pos->floor();
|
$pos = $pos->floor();
|
||||||
$b = $this->world->getBlock($pos);
|
$b = $this->getWorld()->getBlock($pos);
|
||||||
|
|
||||||
$ev = new PlayerBedEnterEvent($this, $b);
|
$ev = new PlayerBedEnterEvent($this, $b);
|
||||||
$ev->call();
|
$ev->call();
|
||||||
@ -1080,14 +1080,14 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener,
|
|||||||
|
|
||||||
$this->setSpawn($pos);
|
$this->setSpawn($pos);
|
||||||
|
|
||||||
$this->world->setSleepTicks(60);
|
$this->getWorld()->setSleepTicks(60);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function stopSleep(){
|
public function stopSleep(){
|
||||||
if($this->sleeping instanceof Vector3){
|
if($this->sleeping instanceof Vector3){
|
||||||
$b = $this->world->getBlock($this->sleeping);
|
$b = $this->getWorld()->getBlock($this->sleeping);
|
||||||
if($b instanceof Bed){
|
if($b instanceof Bed){
|
||||||
$b->setOccupied(false);
|
$b->setOccupied(false);
|
||||||
}
|
}
|
||||||
@ -1095,7 +1095,7 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener,
|
|||||||
|
|
||||||
$this->sleeping = null;
|
$this->sleeping = null;
|
||||||
|
|
||||||
$this->world->setSleepTicks(0);
|
$this->getWorld()->setSleepTicks(0);
|
||||||
|
|
||||||
$this->broadcastAnimation([$this], AnimatePacket::ACTION_STOP_SLEEP);
|
$this->broadcastAnimation([$this], AnimatePacket::ACTION_STOP_SLEEP);
|
||||||
}
|
}
|
||||||
@ -1225,10 +1225,10 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener,
|
|||||||
|
|
||||||
protected function checkGroundState(float $movX, float $movY, float $movZ, float $dx, float $dy, float $dz) : void{
|
protected function checkGroundState(float $movX, float $movY, float $movZ, float $dx, float $dy, float $dz) : void{
|
||||||
$bb = clone $this->boundingBox;
|
$bb = clone $this->boundingBox;
|
||||||
$bb->minY = $this->y - 0.2;
|
$bb->minY = $this->location->y - 0.2;
|
||||||
$bb->maxY = $this->y + 0.2;
|
$bb->maxY = $this->location->y + 0.2;
|
||||||
|
|
||||||
$this->onGround = $this->isCollided = count($this->world->getCollisionBlocks($bb, true)) > 0;
|
$this->onGround = $this->isCollided = count($this->getWorld()->getCollisionBlocks($bb, true)) > 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function canBeMovedByCurrents() : bool{
|
public function canBeMovedByCurrents() : bool{
|
||||||
@ -1236,7 +1236,7 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener,
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected function checkNearEntities(){
|
protected function checkNearEntities(){
|
||||||
foreach($this->world->getNearbyEntities($this->boundingBox->expandedCopy(1, 0.5, 1), $this) as $entity){
|
foreach($this->getWorld()->getNearbyEntities($this->boundingBox->expandedCopy(1, 0.5, 1), $this) as $entity){
|
||||||
$entity->scheduleUpdate();
|
$entity->scheduleUpdate();
|
||||||
|
|
||||||
if(!$entity->isAlive() or $entity->isFlaggedForDespawn()){
|
if(!$entity->isAlive() or $entity->isFlaggedForDespawn()){
|
||||||
@ -1254,7 +1254,7 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener,
|
|||||||
* @return Vector3
|
* @return Vector3
|
||||||
*/
|
*/
|
||||||
public function getNextPosition() : Vector3{
|
public function getNextPosition() : Vector3{
|
||||||
return $this->newPosition !== null ? clone $this->newPosition : $this->asVector3();
|
return $this->newPosition !== null ? clone $this->newPosition : $this->location->asVector3();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -1271,9 +1271,9 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener,
|
|||||||
//TODO: teleport acks are a network specific thing and shouldn't be here
|
//TODO: teleport acks are a network specific thing and shouldn't be here
|
||||||
|
|
||||||
$newPos = $newPos->asVector3();
|
$newPos = $newPos->asVector3();
|
||||||
if($this->isTeleporting and $newPos->distanceSquared($this) > 1){ //Tolerate up to 1 block to avoid problems with client-sided physics when spawning in blocks
|
if($this->isTeleporting and $newPos->distanceSquared($this->location) > 1){ //Tolerate up to 1 block to avoid problems with client-sided physics when spawning in blocks
|
||||||
$this->sendPosition($this, null, null, MovePlayerPacket::MODE_RESET);
|
$this->sendPosition($this->location, null, null, MovePlayerPacket::MODE_RESET);
|
||||||
$this->logger->debug("Got outdated pre-teleport movement, received " . $newPos . ", expected " . $this->asVector3());
|
$this->logger->debug("Got outdated pre-teleport movement, received " . $newPos . ", expected " . $this->location->asVector3());
|
||||||
//Still getting movements from before teleport, ignore them
|
//Still getting movements from before teleport, ignore them
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -1296,11 +1296,10 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener,
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
assert($this->x !== null and $this->y !== null and $this->z !== null);
|
|
||||||
assert($this->newPosition->x !== null and $this->newPosition->y !== null and $this->newPosition->z !== null);
|
assert($this->newPosition->x !== null and $this->newPosition->y !== null and $this->newPosition->z !== null);
|
||||||
|
|
||||||
$newPos = $this->newPosition;
|
$newPos = $this->newPosition;
|
||||||
$distanceSquared = $newPos->distanceSquared($this);
|
$distanceSquared = $newPos->distanceSquared($this->location);
|
||||||
|
|
||||||
$revert = false;
|
$revert = false;
|
||||||
|
|
||||||
@ -1316,23 +1315,23 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener,
|
|||||||
* asking for help if you suffer the consequences of messing with this.
|
* asking for help if you suffer the consequences of messing with this.
|
||||||
*/
|
*/
|
||||||
$this->logger->debug("Moved too fast, reverting movement");
|
$this->logger->debug("Moved too fast, reverting movement");
|
||||||
$this->logger->debug("Old position: " . $this->asVector3() . ", new position: " . $this->newPosition);
|
$this->logger->debug("Old position: " . $this->location->asVector3() . ", new position: " . $this->newPosition);
|
||||||
$revert = true;
|
$revert = true;
|
||||||
}elseif(!$this->world->isInLoadedTerrain($newPos) or !$this->world->isChunkGenerated($newPos->getFloorX() >> 4, $newPos->getFloorZ() >> 4)){
|
}elseif(!$this->getWorld()->isInLoadedTerrain($newPos) or !$this->getWorld()->isChunkGenerated($newPos->getFloorX() >> 4, $newPos->getFloorZ() >> 4)){
|
||||||
$revert = true;
|
$revert = true;
|
||||||
$this->nextChunkOrderRun = 0;
|
$this->nextChunkOrderRun = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!$revert and $distanceSquared != 0){
|
if(!$revert and $distanceSquared != 0){
|
||||||
$dx = $newPos->x - $this->x;
|
$dx = $newPos->x - $this->location->x;
|
||||||
$dy = $newPos->y - $this->y;
|
$dy = $newPos->y - $this->location->y;
|
||||||
$dz = $newPos->z - $this->z;
|
$dz = $newPos->z - $this->location->z;
|
||||||
|
|
||||||
$this->move($dx, $dy, $dz);
|
$this->move($dx, $dy, $dz);
|
||||||
}
|
}
|
||||||
|
|
||||||
$from = clone $this->lastLocation;
|
$from = clone $this->lastLocation;
|
||||||
$to = $this->asLocation();
|
$to = clone $this->location;
|
||||||
|
|
||||||
$delta = $to->distanceSquared($from);
|
$delta = $to->distanceSquared($from);
|
||||||
$deltaAngle = abs($this->lastLocation->yaw - $to->yaw) + abs($this->lastLocation->pitch - $to->pitch);
|
$deltaAngle = abs($this->lastLocation->yaw - $to->yaw) + abs($this->lastLocation->pitch - $to->pitch);
|
||||||
@ -1631,7 +1630,7 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener,
|
|||||||
}
|
}
|
||||||
|
|
||||||
public function pickBlock(Vector3 $pos, bool $addTileNBT) : bool{
|
public function pickBlock(Vector3 $pos, bool $addTileNBT) : bool{
|
||||||
$block = $this->world->getBlock($pos);
|
$block = $this->getWorld()->getBlock($pos);
|
||||||
if($block instanceof UnknownBlock){
|
if($block instanceof UnknownBlock){
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -1678,11 +1677,11 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener,
|
|||||||
* @return bool if an action took place successfully
|
* @return bool if an action took place successfully
|
||||||
*/
|
*/
|
||||||
public function attackBlock(Vector3 $pos, int $face) : bool{
|
public function attackBlock(Vector3 $pos, int $face) : bool{
|
||||||
if($pos->distanceSquared($this) > 10000){
|
if($pos->distanceSquared($this->location) > 10000){
|
||||||
return false; //TODO: maybe this should throw an exception instead?
|
return false; //TODO: maybe this should throw an exception instead?
|
||||||
}
|
}
|
||||||
|
|
||||||
$target = $this->world->getBlock($pos);
|
$target = $this->getWorld()->getBlock($pos);
|
||||||
|
|
||||||
$ev = new PlayerInteractEvent($this, $this->inventory->getItemInHand(), $target, null, $face, PlayerInteractEvent::LEFT_CLICK_BLOCK);
|
$ev = new PlayerInteractEvent($this, $this->inventory->getItemInHand(), $target, null, $face, PlayerInteractEvent::LEFT_CLICK_BLOCK);
|
||||||
$ev->call();
|
$ev->call();
|
||||||
@ -1696,7 +1695,7 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener,
|
|||||||
|
|
||||||
$block = $target->getSide($face);
|
$block = $target->getSide($face);
|
||||||
if($block->getId() === BlockLegacyIds::FIRE){
|
if($block->getId() === BlockLegacyIds::FIRE){
|
||||||
$this->world->setBlock($block->getPos(), VanillaBlocks::AIR());
|
$this->getWorld()->setBlock($block->getPos(), VanillaBlocks::AIR());
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1704,7 +1703,7 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener,
|
|||||||
//TODO: improve this to take stuff like swimming, ladders, enchanted tools into account, fix wrong tool break time calculations for bad tools (pmmp/PocketMine-MP#211)
|
//TODO: improve this to take stuff like swimming, ladders, enchanted tools into account, fix wrong tool break time calculations for bad tools (pmmp/PocketMine-MP#211)
|
||||||
$breakTime = ceil($target->getBreakInfo()->getBreakTime($this->inventory->getItemInHand()) * 20);
|
$breakTime = ceil($target->getBreakInfo()->getBreakTime($this->inventory->getItemInHand()) * 20);
|
||||||
if($breakTime > 0){
|
if($breakTime > 0){
|
||||||
$this->world->broadcastLevelEvent($pos, LevelEventPacket::EVENT_BLOCK_START_BREAK, (int) (65535 / $breakTime));
|
$this->getWorld()->broadcastLevelEvent($pos, LevelEventPacket::EVENT_BLOCK_START_BREAK, (int) (65535 / $breakTime));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1712,15 +1711,15 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener,
|
|||||||
}
|
}
|
||||||
|
|
||||||
public function continueBreakBlock(Vector3 $pos, int $face) : void{
|
public function continueBreakBlock(Vector3 $pos, int $face) : void{
|
||||||
$block = $this->world->getBlock($pos);
|
$block = $this->getWorld()->getBlock($pos);
|
||||||
$this->world->addParticle($pos, new PunchBlockParticle($block, $face));
|
$this->getWorld()->addParticle($pos, new PunchBlockParticle($block, $face));
|
||||||
$this->broadcastEntityEvent(ActorEventPacket::ARM_SWING, null, $this->getViewers());
|
$this->broadcastEntityEvent(ActorEventPacket::ARM_SWING, null, $this->getViewers());
|
||||||
|
|
||||||
//TODO: destroy-progress level event
|
//TODO: destroy-progress level event
|
||||||
}
|
}
|
||||||
|
|
||||||
public function stopBreakBlock(Vector3 $pos) : void{
|
public function stopBreakBlock(Vector3 $pos) : void{
|
||||||
$this->world->broadcastLevelEvent($pos, LevelEventPacket::EVENT_BLOCK_STOP_BREAK);
|
$this->getWorld()->broadcastLevelEvent($pos, LevelEventPacket::EVENT_BLOCK_STOP_BREAK);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -1737,7 +1736,7 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener,
|
|||||||
$this->broadcastEntityEvent(ActorEventPacket::ARM_SWING, null, $this->getViewers());
|
$this->broadcastEntityEvent(ActorEventPacket::ARM_SWING, null, $this->getViewers());
|
||||||
$item = $this->inventory->getItemInHand();
|
$item = $this->inventory->getItemInHand();
|
||||||
$oldItem = clone $item;
|
$oldItem = clone $item;
|
||||||
if($this->world->useBreakOn($pos, $item, $this, true)){
|
if($this->getWorld()->useBreakOn($pos, $item, $this, true)){
|
||||||
if($this->hasFiniteResources() and !$item->equalsExact($oldItem)){
|
if($this->hasFiniteResources() and !$item->equalsExact($oldItem)){
|
||||||
$this->inventory->setItemInHand($item);
|
$this->inventory->setItemInHand($item);
|
||||||
}
|
}
|
||||||
@ -1765,7 +1764,7 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener,
|
|||||||
$this->broadcastEntityEvent(ActorEventPacket::ARM_SWING, null, $this->getViewers());
|
$this->broadcastEntityEvent(ActorEventPacket::ARM_SWING, null, $this->getViewers());
|
||||||
$item = $this->inventory->getItemInHand(); //this is a copy of the real item
|
$item = $this->inventory->getItemInHand(); //this is a copy of the real item
|
||||||
$oldItem = clone $item;
|
$oldItem = clone $item;
|
||||||
if($this->world->useItemOn($pos, $item, $face, $clickOffset, $this, true)){
|
if($this->getWorld()->useItemOn($pos, $item, $face, $clickOffset, $this, true)){
|
||||||
if($this->hasFiniteResources() and !$item->equalsExact($oldItem)){
|
if($this->hasFiniteResources() and !$item->equalsExact($oldItem)){
|
||||||
$this->inventory->setItemInHand($item);
|
$this->inventory->setItemInHand($item);
|
||||||
}
|
}
|
||||||
@ -1797,7 +1796,7 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener,
|
|||||||
$heldItem = $this->inventory->getItemInHand();
|
$heldItem = $this->inventory->getItemInHand();
|
||||||
|
|
||||||
$ev = new EntityDamageByEntityEvent($this, $entity, EntityDamageEvent::CAUSE_ENTITY_ATTACK, $heldItem->getAttackPoints());
|
$ev = new EntityDamageByEntityEvent($this, $entity, EntityDamageEvent::CAUSE_ENTITY_ATTACK, $heldItem->getAttackPoints());
|
||||||
if(!$this->canInteract($entity, 8) or ($entity instanceof Player and !$this->server->getConfigBool("pvp"))){
|
if(!$this->canInteract($entity->getLocation(), 8) or ($entity instanceof Player and !$this->server->getConfigBool("pvp"))){
|
||||||
$ev->setCancelled();
|
$ev->setCancelled();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1900,7 +1899,7 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener,
|
|||||||
*/
|
*/
|
||||||
public function dropItem(Item $item) : void{
|
public function dropItem(Item $item) : void{
|
||||||
$this->broadcastEntityEvent(ActorEventPacket::ARM_SWING, null, $this->getViewers());
|
$this->broadcastEntityEvent(ActorEventPacket::ARM_SWING, null, $this->getViewers());
|
||||||
$this->world->dropItem($this->add(0, 1.3, 0), $item, $this->getDirectionVector()->multiply(0.4), 40);
|
$this->getWorld()->dropItem($this->location->add(0, 1.3, 0), $item, $this->getDirectionVector()->multiply(0.4), 40);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -2159,7 +2158,7 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener,
|
|||||||
}
|
}
|
||||||
$this->hiddenPlayers = [];
|
$this->hiddenPlayers = [];
|
||||||
|
|
||||||
if($this->isValid()){
|
if($this->location->isValid()){
|
||||||
foreach($this->usedChunks as $index => $d){
|
foreach($this->usedChunks as $index => $d){
|
||||||
World::getXZ($index, $chunkX, $chunkZ);
|
World::getXZ($index, $chunkX, $chunkZ);
|
||||||
$this->unloadChunk($chunkX, $chunkZ);
|
$this->unloadChunk($chunkX, $chunkZ);
|
||||||
@ -2221,8 +2220,8 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener,
|
|||||||
|
|
||||||
$nbt = $this->saveNBT();
|
$nbt = $this->saveNBT();
|
||||||
|
|
||||||
if($this->isValid()){
|
if($this->location->isValid()){
|
||||||
$nbt->setString("Level", $this->world->getFolderName());
|
$nbt->setString("Level", $this->getWorld()->getFolderName());
|
||||||
}
|
}
|
||||||
|
|
||||||
if($this->hasValidSpawnPosition()){
|
if($this->hasValidSpawnPosition()){
|
||||||
@ -2261,7 +2260,7 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener,
|
|||||||
|
|
||||||
if(!$ev->getKeepInventory()){
|
if(!$ev->getKeepInventory()){
|
||||||
foreach($ev->getDrops() as $item){
|
foreach($ev->getDrops() as $item){
|
||||||
$this->world->dropItem($this, $item);
|
$this->getWorld()->dropItem($this->location, $item);
|
||||||
}
|
}
|
||||||
|
|
||||||
if($this->inventory !== null){
|
if($this->inventory !== null){
|
||||||
@ -2273,7 +2272,7 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->world->dropExperience($this, $ev->getXpDropAmount());
|
$this->getWorld()->dropExperience($this->location, $ev->getXpDropAmount());
|
||||||
$this->xpManager->setXpAndProgress(0, 0.0);
|
$this->xpManager->setXpAndProgress(0, 0.0);
|
||||||
|
|
||||||
if($ev->getDeathMessage() != ""){
|
if($ev->getDeathMessage() != ""){
|
||||||
@ -2400,7 +2399,7 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener,
|
|||||||
|
|
||||||
$this->removeCurrentWindow();
|
$this->removeCurrentWindow();
|
||||||
|
|
||||||
$this->sendPosition($this, $this->yaw, $this->pitch, MovePlayerPacket::MODE_TELEPORT);
|
$this->sendPosition($this->location, $this->location->yaw, $this->location->pitch, MovePlayerPacket::MODE_TELEPORT);
|
||||||
$this->broadcastMovement(true);
|
$this->broadcastMovement(true);
|
||||||
|
|
||||||
$this->spawnToAll();
|
$this->spawnToAll();
|
||||||
@ -2543,4 +2542,22 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener,
|
|||||||
$this->nextChunkOrderRun = 0;
|
$this->nextChunkOrderRun = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see ChunkLoader::getX()
|
||||||
|
* @return float
|
||||||
|
*/
|
||||||
|
public function getX(){
|
||||||
|
return $this->location->getX();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see ChunkLoader::getZ()
|
||||||
|
* @return float
|
||||||
|
*/
|
||||||
|
public function getZ(){
|
||||||
|
return $this->location->getZ();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -174,12 +174,14 @@ class Explosion{
|
|||||||
|
|
||||||
$explosionBB = new AxisAlignedBB($minX, $minY, $minZ, $maxX, $maxY, $maxZ);
|
$explosionBB = new AxisAlignedBB($minX, $minY, $minZ, $maxX, $maxY, $maxZ);
|
||||||
|
|
||||||
|
/** @var Entity[] $list */
|
||||||
$list = $this->world->getNearbyEntities($explosionBB, $this->what instanceof Entity ? $this->what : null);
|
$list = $this->world->getNearbyEntities($explosionBB, $this->what instanceof Entity ? $this->what : null);
|
||||||
foreach($list as $entity){
|
foreach($list as $entity){
|
||||||
$distance = $entity->distance($this->source) / $explosionSize;
|
$entityPos = $entity->getPosition();
|
||||||
|
$distance = $entityPos->distance($this->source) / $explosionSize;
|
||||||
|
|
||||||
if($distance <= 1){
|
if($distance <= 1){
|
||||||
$motion = $entity->subtract($this->source)->normalize();
|
$motion = $entityPos->subtract($this->source)->normalize();
|
||||||
|
|
||||||
$impact = (1 - $distance) * ($exposure = 1);
|
$impact = (1 - $distance) * ($exposure = 1);
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user