Improved Player flight detection after setMotion(), other method improvement

This commit is contained in:
Shoghi Cervantes 2015-05-03 13:42:54 +02:00
parent 0ead3ec781
commit 9ec609d025
No known key found for this signature in database
GPG Key ID: 78464DB0A7837F89
7 changed files with 52 additions and 38 deletions

View File

@ -215,6 +215,7 @@ class Player extends Human implements CommandSender, InventoryHolder, IPlayer{
private $spawnPosition = null; private $spawnPosition = null;
protected $inAirTicks = 0; protected $inAirTicks = 0;
protected $startAirTicks = 5;
protected $autoJump = true; protected $autoJump = true;
@ -376,6 +377,9 @@ class Player extends Human implements CommandSender, InventoryHolder, IPlayer{
public function resetFallDistance(){ public function resetFallDistance(){
parent::resetFallDistance(); parent::resetFallDistance();
if($this->inAirTicks !== 0){
$this->startAirTicks = 5;
}
$this->inAirTicks = 0; $this->inAirTicks = 0;
} }
@ -1333,7 +1337,19 @@ class Player extends Human implements CommandSender, InventoryHolder, IPlayer{
$this->newPosition = null; $this->newPosition = null;
} }
public function updateMovement(){ public function setMotion(Vector3 $mot){
if(parent::setMotion($mot)){
if($this->motionY > 0){
$this->addEntityMotion($this->getId(), $this->motionX, $this->motionY, $this->motionZ);
$this->startAirTicks = (-(log($this->gravity / ($this->gravity + $this->drag * $this->motionY))) / $this->drag) * 2 + 5;
}
return true;
}
return false;
}
protected function updateMovement(){
} }
@ -1369,10 +1385,13 @@ class Player extends Human implements CommandSender, InventoryHolder, IPlayer{
if(!$this->isSpectator()){ if(!$this->isSpectator()){
if($this->onGround){ if($this->onGround){
if($this->inAirTicks !== 0){
$this->startAirTicks = 5;
}
$this->inAirTicks = 0; $this->inAirTicks = 0;
}else{ }else{
if(!$this->allowFlight and $this->inAirTicks > 10 and !$this->isSleeping() and $this->getDataProperty(self::DATA_NO_AI) !== 1){ if(!$this->allowFlight and $this->inAirTicks > 10 and !$this->isSleeping() and $this->getDataProperty(self::DATA_NO_AI) !== 1){
$expectedVelocity = (-$this->gravity) / $this->drag - ((-$this->gravity) / $this->drag) * exp(-$this->drag * ($this->inAirTicks - 5)); $expectedVelocity = (-$this->gravity) / $this->drag - ((-$this->gravity) / $this->drag) * exp(-$this->drag * ($this->inAirTicks - $this->startAirTicks));
$diff = sqrt(abs($this->speed->y - $expectedVelocity)); $diff = sqrt(abs($this->speed->y - $expectedVelocity));
if(!$this->hasEffect(Effect::JUMP) and $diff > 0.6 and $expectedVelocity < $this->speed->y and !$this->server->getAllowFlight()){ if(!$this->hasEffect(Effect::JUMP) and $diff > 0.6 and $expectedVelocity < $this->speed->y and !$this->server->getAllowFlight()){

View File

@ -47,7 +47,7 @@ abstract class Fallable extends Solid{
$fall = Entity::createEntity("FallingSand", $this->getLevel()->getChunk($this->x >> 4, $this->z >> 4), new Compound("", [ $fall = Entity::createEntity("FallingSand", $this->getLevel()->getChunk($this->x >> 4, $this->z >> 4), new Compound("", [
"Pos" => new Enum("Pos", [ "Pos" => new Enum("Pos", [
new Double("", $this->x + 0.5), new Double("", $this->x + 0.5),
new Double("", $this->y), new Double("", $this->y + 0.5),
new Double("", $this->z + 0.5) new Double("", $this->z + 0.5)
]), ]),
"Motion" => new Enum("Motion", [ "Motion" => new Enum("Motion", [

View File

@ -161,11 +161,11 @@ abstract class Entity extends Location implements Metadatable{
protected $stepHeight = 0; protected $stepHeight = 0;
public $keepMovement = false; public $keepMovement = false;
public $fallDistance; public $fallDistance = 0;
public $ticksLived; public $ticksLived = 0;
public $lastUpdate; public $lastUpdate;
public $maxFireTicks; public $maxFireTicks;
public $fireTicks; public $fireTicks = 0;
public $namedtag; public $namedtag;
public $canCollide = true; public $canCollide = true;
@ -784,8 +784,13 @@ abstract class Entity extends Location implements Metadatable{
return $hasUpdate; return $hasUpdate;
} }
public function updateMovement(){ protected function updateMovement(){
if($this->x !== $this->lastX or $this->y !== $this->lastY or $this->z !== $this->lastZ or $this->yaw !== $this->lastYaw or $this->pitch !== $this->lastPitch){ $diffPosition = ($this->x - $this->lastX) ** 2 + ($this->y - $this->lastY) ** 2 + ($this->z - $this->lastZ) ** 2;
$diffRotation = ($this->yaw - $this->lastYaw) ** 2 + ($this->pitch - $this->lastPitch) ** 2;
$diffMotion = ($this->motionX - $this->lastMotionX) ** 2 + ($this->motionY - $this->lastMotionY) ** 2 + ($this->motionZ - $this->lastMotionZ) ** 2;
if($diffPosition > 0.04 or $diffRotation > 2.25){ //0.2 ** 2, 1.5 ** 2
$this->lastX = $this->x; $this->lastX = $this->x;
$this->lastY = $this->y; $this->lastY = $this->y;
$this->lastZ = $this->z; $this->lastZ = $this->z;
@ -800,7 +805,7 @@ abstract class Entity extends Location implements Metadatable{
} }
} }
if(($this->lastMotionX != $this->motionX or $this->lastMotionY != $this->motionY or $this->lastMotionZ != $this->motionZ)){ if($diffMotion > 0.0025){ //0.05 ** 2
$this->lastMotionX = $this->motionX; $this->lastMotionX = $this->motionX;
$this->lastMotionY = $this->motionY; $this->lastMotionY = $this->motionY;
$this->lastMotionZ = $this->motionZ; $this->lastMotionZ = $this->motionZ;
@ -1361,9 +1366,6 @@ abstract class Entity extends Location implements Metadatable{
$this->motionZ = $motion->z; $this->motionZ = $motion->z;
if(!$this->justCreated){ if(!$this->justCreated){
if($this instanceof Player){
$this->addEntityMotion($this->getId(), $this->motionX, $this->motionY, $this->motionZ);
}
$this->updateMovement(); $this->updateMovement();
} }

View File

@ -96,13 +96,12 @@ class FallingSand extends Entity{
if(!$this->dead){ if(!$this->dead){
if($this->ticksLived === 1){ if($this->ticksLived === 1){
$block = $this->level->getBlock($pos = (new Vector3($this->x, $this->y, $this->z))->floor()); $block = $this->level->getBlock($pos = (new Vector3($this->x - 0.5, $this->y - 0.5, $this->z - 0.5))->floor());
if($block->getId() != $this->blockId){ if($block->getId() !== $this->blockId){
$this->kill(); $this->kill();
return true; return true;
} }
$this->level->setBlock($pos, Block::get(0), true); $this->level->setBlock($pos, Block::get(0), true);
} }
$this->motionY -= $this->gravity; $this->motionY -= $this->gravity;

View File

@ -130,7 +130,7 @@ class Explosion{
public function explodeB(){ public function explodeB(){
$send = []; $send = [];
$source = (new Vector3($this->source->x, $this->source->y, $this->source->z))->floor(); $source = (new Vector3($this->source->x, $this->source->y, $this->source->z))->round();
$yield = (1 / $this->size) * 100; $yield = (1 / $this->size) * 100;
if($this->what instanceof Entity){ if($this->what instanceof Entity){

View File

@ -847,16 +847,6 @@ class Level implements ChunkManager, Metadatable{
* @param Vector3 $pos * @param Vector3 $pos
*/ */
public function updateAround(Vector3 $pos){ public function updateAround(Vector3 $pos){
$this->server->getPluginManager()->callEvent($ev = new BlockUpdateEvent($this->getBlock($this->temporalVector->setComponents($pos->x - 1, $pos->y, $pos->z))));
if(!$ev->isCancelled()){
$ev->getBlock()->onUpdate(self::BLOCK_UPDATE_NORMAL);
}
$this->server->getPluginManager()->callEvent($ev = new BlockUpdateEvent($this->getBlock($this->temporalVector->setComponents($pos->x + 1, $pos->y, $pos->z))));
if(!$ev->isCancelled()){
$ev->getBlock()->onUpdate(self::BLOCK_UPDATE_NORMAL);
}
$this->server->getPluginManager()->callEvent($ev = new BlockUpdateEvent($this->getBlock($this->temporalVector->setComponents($pos->x, $pos->y - 1, $pos->z)))); $this->server->getPluginManager()->callEvent($ev = new BlockUpdateEvent($this->getBlock($this->temporalVector->setComponents($pos->x, $pos->y - 1, $pos->z))));
if(!$ev->isCancelled()){ if(!$ev->isCancelled()){
$ev->getBlock()->onUpdate(self::BLOCK_UPDATE_NORMAL); $ev->getBlock()->onUpdate(self::BLOCK_UPDATE_NORMAL);
@ -867,6 +857,16 @@ class Level implements ChunkManager, Metadatable{
$ev->getBlock()->onUpdate(self::BLOCK_UPDATE_NORMAL); $ev->getBlock()->onUpdate(self::BLOCK_UPDATE_NORMAL);
} }
$this->server->getPluginManager()->callEvent($ev = new BlockUpdateEvent($this->getBlock($this->temporalVector->setComponents($pos->x - 1, $pos->y, $pos->z))));
if(!$ev->isCancelled()){
$ev->getBlock()->onUpdate(self::BLOCK_UPDATE_NORMAL);
}
$this->server->getPluginManager()->callEvent($ev = new BlockUpdateEvent($this->getBlock($this->temporalVector->setComponents($pos->x + 1, $pos->y, $pos->z))));
if(!$ev->isCancelled()){
$ev->getBlock()->onUpdate(self::BLOCK_UPDATE_NORMAL);
}
$this->server->getPluginManager()->callEvent($ev = new BlockUpdateEvent($this->getBlock($this->temporalVector->setComponents($pos->x, $pos->y, $pos->z - 1)))); $this->server->getPluginManager()->callEvent($ev = new BlockUpdateEvent($this->getBlock($this->temporalVector->setComponents($pos->x, $pos->y, $pos->z - 1))));
if(!$ev->isCancelled()){ if(!$ev->isCancelled()){
$ev->getBlock()->onUpdate(self::BLOCK_UPDATE_NORMAL); $ev->getBlock()->onUpdate(self::BLOCK_UPDATE_NORMAL);
@ -1081,7 +1081,7 @@ class Level implements ChunkManager, Metadatable{
*/ */
public function getBlock(Vector3 $pos, $cached = true){ public function getBlock(Vector3 $pos, $cached = true){
$index = Level::blockHash($pos->x, $pos->y, $pos->z); $index = Level::blockHash($pos->x, $pos->y, $pos->z);
if($cached === true and isset($this->blockCache[$index])){ if($cached and isset($this->blockCache[$index])){
return $this->blockCache[$index]; return $this->blockCache[$index];
}elseif($pos->y >= 0 and $pos->y < 128 and isset($this->chunks[$chunkIndex = Level::chunkHash($pos->x >> 4, $pos->z >> 4)])){ }elseif($pos->y >= 0 and $pos->y < 128 and isset($this->chunks[$chunkIndex = Level::chunkHash($pos->x >> 4, $pos->z >> 4)])){
$fullState = $this->chunks[$chunkIndex]->getFullBlock($pos->x & 0x0f, $pos->y & 0x7f, $pos->z & 0x0f); $fullState = $this->chunks[$chunkIndex]->getFullBlock($pos->x & 0x0f, $pos->y & 0x7f, $pos->z & 0x0f);
@ -1232,10 +1232,6 @@ class Level implements ChunkManager, Metadatable{
$this->sendBlocks($this->getUsingChunk($pos->x >> 4, $pos->z >> 4), [$block], UpdateBlockPacket::FLAG_ALL_PRIORITY); $this->sendBlocks($this->getUsingChunk($pos->x >> 4, $pos->z >> 4), [$block], UpdateBlockPacket::FLAG_ALL_PRIORITY);
unset($this->chunkCache[$index]); unset($this->chunkCache[$index]);
}else{ }else{
if(!($pos instanceof Position)){
$pos = $this->temporalPosition->setComponents($pos->x, $pos->y, $pos->z);
}
$block->position($pos);
if(!isset($this->changedBlocks[$index])){ if(!isset($this->changedBlocks[$index])){
$this->changedBlocks[$index] = []; $this->changedBlocks[$index] = [];
} }
@ -1248,10 +1244,10 @@ class Level implements ChunkManager, Metadatable{
$this->server->getPluginManager()->callEvent($ev = new BlockUpdateEvent($block)); $this->server->getPluginManager()->callEvent($ev = new BlockUpdateEvent($block));
if(!$ev->isCancelled()){ if(!$ev->isCancelled()){
$ev->getBlock()->onUpdate(self::BLOCK_UPDATE_NORMAL); foreach($this->getNearbyEntities(new AxisAlignedBB($block->x - 1, $block->y - 1, $block->z - 1, $block->x + 1, $block->y + 1, $block->z + 1)) as $entity){
foreach($this->getNearbyEntities(new AxisAlignedBB($block->x - 1, $block->y - 1, $block->z - 1, $block->x + 2, $block->y + 2, $block->z + 2)) as $entity){
$entity->scheduleUpdate(); $entity->scheduleUpdate();
} }
$ev->getBlock()->onUpdate(self::BLOCK_UPDATE_NORMAL);
} }
$this->updateAround($pos); $this->updateAround($pos);
@ -2291,7 +2287,7 @@ class Level implements ChunkManager, Metadatable{
$spawn = $this->getSpawnLocation(); $spawn = $this->getSpawnLocation();
} }
if($spawn instanceof Vector3){ if($spawn instanceof Vector3){
$v = $spawn->floor(); $v = $spawn->round();
$chunk = $this->getChunk($v->x >> 4, $v->z >> 4, false); $chunk = $this->getChunk($v->x >> 4, $v->z >> 4, false);
$x = $v->x & 0x0f; $x = $v->x & 0x0f;
$z = $v->z & 0x0f; $z = $v->z & 0x0f;

View File

@ -127,13 +127,11 @@ class Vector3{
} }
public function floor(){ public function floor(){
$x = (int) $this->x; return new Vector3((int) $this->x, (int) $this->y, (int) $this->z);
$z = (int) $this->z;
return new Vector3($this->x >= $x ? $x : $x - 1, (int) round($this->y), $this->z >= $z ? $z : $z - 1);
} }
public function round(){ public function round(){
return new Vector3(round($this->x), round($this->y), round($this->z)); return new Vector3((int) round($this->x), (int) round($this->y), (int) round($this->z));
} }
public function abs(){ public function abs(){