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;
protected $inAirTicks = 0;
protected $startAirTicks = 5;
protected $autoJump = true;
@ -376,6 +377,9 @@ class Player extends Human implements CommandSender, InventoryHolder, IPlayer{
public function resetFallDistance(){
parent::resetFallDistance();
if($this->inAirTicks !== 0){
$this->startAirTicks = 5;
}
$this->inAirTicks = 0;
}
@ -1333,7 +1337,19 @@ class Player extends Human implements CommandSender, InventoryHolder, IPlayer{
$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->onGround){
if($this->inAirTicks !== 0){
$this->startAirTicks = 5;
}
$this->inAirTicks = 0;
}else{
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));
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("", [
"Pos" => new Enum("Pos", [
new Double("", $this->x + 0.5),
new Double("", $this->y),
new Double("", $this->y + 0.5),
new Double("", $this->z + 0.5)
]),
"Motion" => new Enum("Motion", [

View File

@ -161,11 +161,11 @@ abstract class Entity extends Location implements Metadatable{
protected $stepHeight = 0;
public $keepMovement = false;
public $fallDistance;
public $ticksLived;
public $fallDistance = 0;
public $ticksLived = 0;
public $lastUpdate;
public $maxFireTicks;
public $fireTicks;
public $fireTicks = 0;
public $namedtag;
public $canCollide = true;
@ -784,8 +784,13 @@ abstract class Entity extends Location implements Metadatable{
return $hasUpdate;
}
public 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){
protected function updateMovement(){
$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->lastY = $this->y;
$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->lastMotionY = $this->motionY;
$this->lastMotionZ = $this->motionZ;
@ -1361,9 +1366,6 @@ abstract class Entity extends Location implements Metadatable{
$this->motionZ = $motion->z;
if(!$this->justCreated){
if($this instanceof Player){
$this->addEntityMotion($this->getId(), $this->motionX, $this->motionY, $this->motionZ);
}
$this->updateMovement();
}

View File

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

View File

@ -130,7 +130,7 @@ class Explosion{
public function explodeB(){
$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;
if($this->what instanceof Entity){

View File

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

View File

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