Entity: replaced motion and lastMotion fields with vectors

This commit is contained in:
Dylan K. Taylor 2018-05-24 12:11:41 +01:00
parent 595f1f58da
commit 9dd0ee7f05
6 changed files with 61 additions and 73 deletions

View File

@ -1646,8 +1646,8 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{
if(parent::setMotion($motion)){ if(parent::setMotion($motion)){
$this->broadcastMotion(); $this->broadcastMotion();
if($this->motionY > 0){ if($this->motion->y > 0){
$this->startAirTicks = (-log($this->gravity / ($this->gravity + $this->drag * $this->motionY)) / $this->drag) * 2 + 5; $this->startAirTicks = (-log($this->gravity / ($this->gravity + $this->drag * $this->motion->y)) / $this->drag) * 2 + 5;
} }
return true; return true;
@ -1702,7 +1702,7 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{
if($this->spawned){ if($this->spawned){
$this->processMovement($tickDiff); $this->processMovement($tickDiff);
$this->motionX = $this->motionY = $this->motionZ = 0; //TODO: HACK! (Fixes player knockback being messed up) $this->motion->x = $this->motion->y = $this->motion->z = 0; //TODO: HACK! (Fixes player knockback being messed up)
Timings::$timerEntityBaseTick->startTiming(); Timings::$timerEntityBaseTick->startTiming();
$this->entityBaseTick($tickDiff); $this->entityBaseTick($tickDiff);

View File

@ -388,23 +388,17 @@ abstract class Entity extends Location implements Metadatable, EntityIds{
/** @var float|null */ /** @var float|null */
public $lastZ = null; public $lastZ = null;
/** @var float */
public $motionX = 0.0;
/** @var float */
public $motionY = 0.0;
/** @var float */
public $motionZ = 0.0;
/** @var Vector3 */ /** @var Vector3 */
public $temporalVector; protected $motion;
/** @var float */ /** @var Vector3 */
public $lastMotionX; protected $lastMotion;
/** @var float */
public $lastMotionY;
/** @var float */
public $lastMotionZ;
/** @var bool */ /** @var bool */
protected $forceMovementUpdate = false; protected $forceMovementUpdate = false;
/** @var Vector3 */
public $temporalVector;
/** @var float */ /** @var float */
public $lastYaw; public $lastYaw;
/** @var float */ /** @var float */
@ -851,9 +845,9 @@ abstract class Entity extends Location implements Metadatable, EntityIds{
])); ]));
$this->namedtag->setTag(new ListTag("Motion", [ $this->namedtag->setTag(new ListTag("Motion", [
new DoubleTag("", $this->motionX), new DoubleTag("", $this->motion->x),
new DoubleTag("", $this->motionY), new DoubleTag("", $this->motion->y),
new DoubleTag("", $this->motionZ) new DoubleTag("", $this->motion->z)
])); ]));
$this->namedtag->setTag(new ListTag("Rotation", [ $this->namedtag->setTag(new ListTag("Rotation", [
@ -1114,7 +1108,7 @@ abstract class Entity extends Location implements Metadatable, EntityIds{
$diffPosition = ($this->x - $this->lastX) ** 2 + ($this->y - $this->lastY) ** 2 + ($this->z - $this->lastZ) ** 2; $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; $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; $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->lastX = $this->x; $this->lastX = $this->x;
@ -1128,9 +1122,7 @@ abstract class Entity extends Location implements Metadatable, EntityIds{
} }
if($diffMotion > 0.0025 or ($diffMotion > 0.0001 and $this->getMotion()->lengthSquared() <= 0.0001)){ //0.05 ** 2 if($diffMotion > 0.0025 or ($diffMotion > 0.0001 and $this->getMotion()->lengthSquared() <= 0.0001)){ //0.05 ** 2
$this->lastMotionX = $this->motionX; $this->lastMotion = clone $this->motion;
$this->lastMotionY = $this->motionY;
$this->lastMotionZ = $this->motionZ;
$this->broadcastMotion(); $this->broadcastMotion();
} }
@ -1169,28 +1161,28 @@ abstract class Entity extends Location implements Metadatable, EntityIds{
} }
protected function applyGravity() : void{ protected function applyGravity() : void{
$this->motionY -= $this->gravity; $this->motion->y -= $this->gravity;
} }
protected function tryChangeMovement() : void{ protected function tryChangeMovement() : void{
$friction = 1 - $this->drag; $friction = 1 - $this->drag;
if($this->applyDragBeforeGravity()){ if($this->applyDragBeforeGravity()){
$this->motionY *= $friction; $this->motion->y *= $friction;
} }
$this->applyGravity(); $this->applyGravity();
if(!$this->applyDragBeforeGravity()){ if(!$this->applyDragBeforeGravity()){
$this->motionY *= $friction; $this->motion->y *= $friction;
} }
if($this->onGround){ if($this->onGround){
$friction *= $this->level->getBlockAt(Math::floorFloat($this->x), Math::floorFloat($this->y) - 1, Math::floorFloat($this->z))->getFrictionFactor(); $friction *= $this->level->getBlockAt(Math::floorFloat($this->x), Math::floorFloat($this->y) - 1, Math::floorFloat($this->z))->getFrictionFactor();
} }
$this->motionX *= $friction; $this->motion->x *= $friction;
$this->motionZ *= $friction; $this->motion->z *= $friction;
} }
protected function checkObstruction(float $x, float $y, float $z) : bool{ protected function checkObstruction(float $x, float $y, float $z) : bool{
@ -1249,37 +1241,37 @@ abstract class Entity extends Location implements Metadatable, EntityIds{
$force = lcg_value() * 0.2 + 0.1; $force = lcg_value() * 0.2 + 0.1;
if($direction === Vector3::SIDE_WEST){ if($direction === Vector3::SIDE_WEST){
$this->motionX = -$force; $this->motion->x = -$force;
return true; return true;
} }
if($direction === Vector3::SIDE_EAST){ if($direction === Vector3::SIDE_EAST){
$this->motionX = $force; $this->motion->x = $force;
return true; return true;
} }
if($direction === Vector3::SIDE_DOWN){ if($direction === Vector3::SIDE_DOWN){
$this->motionY = -$force; $this->motion->y = -$force;
return true; return true;
} }
if($direction === Vector3::SIDE_UP){ if($direction === Vector3::SIDE_UP){
$this->motionY = $force; $this->motion->y = $force;
return true; return true;
} }
if($direction === Vector3::SIDE_NORTH){ if($direction === Vector3::SIDE_NORTH){
$this->motionZ = -$force; $this->motion->z = -$force;
return true; return true;
} }
if($direction === Vector3::SIDE_SOUTH){ if($direction === Vector3::SIDE_SOUTH){
$this->motionZ = $force; $this->motion->z = $force;
return true; return true;
} }
@ -1359,16 +1351,16 @@ abstract class Entity extends Location implements Metadatable, EntityIds{
if($this->hasMovementUpdate()){ if($this->hasMovementUpdate()){
$this->tryChangeMovement(); $this->tryChangeMovement();
$this->move($this->motionX, $this->motionY, $this->motionZ); $this->move($this->motion->x, $this->motion->y, $this->motion->z);
if(abs($this->motionX) <= self::MOTION_THRESHOLD){ if(abs($this->motion->x) <= self::MOTION_THRESHOLD){
$this->motionX = 0; $this->motion->x = 0;
} }
if(abs($this->motionY) <= self::MOTION_THRESHOLD){ if(abs($this->motion->y) <= self::MOTION_THRESHOLD){
$this->motionY = 0; $this->motion->y = 0;
} }
if(abs($this->motionZ) <= self::MOTION_THRESHOLD){ if(abs($this->motion->z) <= self::MOTION_THRESHOLD){
$this->motionZ = 0; $this->motion->z = 0;
} }
$this->forceMovementUpdate = false; $this->forceMovementUpdate = false;
@ -1417,9 +1409,9 @@ abstract class Entity extends Location implements Metadatable, EntityIds{
public function hasMovementUpdate() : bool{ public function hasMovementUpdate() : bool{
return ( return (
$this->forceMovementUpdate or $this->forceMovementUpdate or
$this->motionX != 0 or $this->motion->x != 0 or
$this->motionY != 0 or $this->motion->y != 0 or
$this->motionZ != 0 or $this->motion->z != 0 or
!$this->onGround !$this->onGround
); );
} }
@ -1654,15 +1646,15 @@ abstract class Entity extends Location implements Metadatable, EntityIds{
$this->updateFallState($dy, $this->onGround); $this->updateFallState($dy, $this->onGround);
if($movX != $dx){ if($movX != $dx){
$this->motionX = 0; $this->motion->x = 0;
} }
if($movY != $dy){ if($movY != $dy){
$this->motionY = 0; $this->motion->y = 0;
} }
if($movZ != $dz){ if($movZ != $dz){
$this->motionZ = 0; $this->motion->z = 0;
} }
//TODO: vehicle collision events (first we need to spawn them!) //TODO: vehicle collision events (first we need to spawn them!)
@ -1728,9 +1720,9 @@ abstract class Entity extends Location implements Metadatable, EntityIds{
if($vector->lengthSquared() > 0){ if($vector->lengthSquared() > 0){
$vector = $vector->normalize(); $vector = $vector->normalize();
$d = 0.014; $d = 0.014;
$this->motionX += $vector->x * $d; $this->motion->x += $vector->x * $d;
$this->motionY += $vector->y * $d; $this->motion->y += $vector->y * $d;
$this->motionZ += $vector->z * $d; $this->motion->z += $vector->z * $d;
} }
} }
@ -1816,11 +1808,11 @@ abstract class Entity extends Location implements Metadatable, EntityIds{
protected function resetLastMovements() : void{ protected function resetLastMovements() : void{
list($this->lastX, $this->lastY, $this->lastZ) = [$this->x, $this->y, $this->z]; list($this->lastX, $this->lastY, $this->lastZ) = [$this->x, $this->y, $this->z];
list($this->lastYaw, $this->lastPitch) = [$this->yaw, $this->pitch]; list($this->lastYaw, $this->lastPitch) = [$this->yaw, $this->pitch];
list($this->lastMotionX, $this->lastMotionY, $this->lastMotionZ) = [$this->motionX, $this->motionY, $this->motionZ]; $this->lastMotion = clone $this->motion;
} }
public function getMotion() : Vector3{ public function getMotion() : Vector3{
return new Vector3($this->motionX, $this->motionY, $this->motionZ); return $this->motion;
} }
public function setMotion(Vector3 $motion) : bool{ public function setMotion(Vector3 $motion) : bool{
@ -1831,9 +1823,7 @@ abstract class Entity extends Location implements Metadatable, EntityIds{
} }
} }
$this->motionX = $motion->x; $this->motion = clone $motion;
$this->motionY = $motion->y;
$this->motionZ = $motion->z;
if(!$this->justCreated){ if(!$this->justCreated){
$this->updateMovement(); $this->updateMovement();

View File

@ -376,7 +376,7 @@ abstract class Living extends Entity implements Damageable{
*/ */
public function jump() : void{ public function jump() : void{
if($this->onGround){ if($this->onGround){
$this->motionY = $this->getJumpVelocity(); //Y motion should already be 0 if we're jumping from the ground. $this->motion->y = $this->getJumpVelocity(); //Y motion should already be 0 if we're jumping from the ground.
} }
} }
@ -567,7 +567,7 @@ abstract class Living extends Entity implements Damageable{
if(mt_rand() / mt_getrandmax() > $this->getAttributeMap()->getAttribute(Attribute::KNOCKBACK_RESISTANCE)->getValue()){ if(mt_rand() / mt_getrandmax() > $this->getAttributeMap()->getAttribute(Attribute::KNOCKBACK_RESISTANCE)->getValue()){
$f = 1 / $f; $f = 1 / $f;
$motion = new Vector3($this->motionX, $this->motionY, $this->motionZ); $motion = clone $this->motion;
$motion->x /= 2; $motion->x /= 2;
$motion->y /= 2; $motion->y /= 2;

View File

@ -97,19 +97,17 @@ class Squid extends WaterAnimal{
if(!$inWater){ if(!$inWater){
$this->swimDirection = null; $this->swimDirection = null;
}elseif($this->swimDirection !== null){ }elseif($this->swimDirection !== null){
if($this->motionX ** 2 + $this->motionY ** 2 + $this->motionZ ** 2 <= $this->swimDirection->lengthSquared()){ if($this->motion->lengthSquared() <= $this->swimDirection->lengthSquared()){
$this->motionX = $this->swimDirection->x * $this->swimSpeed; $this->motion = $this->swimDirection->multiply($this->swimSpeed);
$this->motionY = $this->swimDirection->y * $this->swimSpeed;
$this->motionZ = $this->swimDirection->z * $this->swimSpeed;
} }
}else{ }else{
$this->swimDirection = $this->generateRandomDirection(); $this->swimDirection = $this->generateRandomDirection();
$this->swimSpeed = mt_rand(50, 100) / 2000; $this->swimSpeed = mt_rand(50, 100) / 2000;
} }
$f = sqrt(($this->motionX ** 2) + ($this->motionZ ** 2)); $f = sqrt(($this->motion->x ** 2) + ($this->motion->z ** 2));
$this->yaw = (-atan2($this->motionX, $this->motionZ) * 180 / M_PI); $this->yaw = (-atan2($this->motion->x, $this->motion->z) * 180 / M_PI);
$this->pitch = (-atan2($f, $this->motionY) * 180 / M_PI); $this->pitch = (-atan2($f, $this->motion->y) * 180 / M_PI);
} }
return $hasUpdate; return $hasUpdate;

View File

@ -192,9 +192,9 @@ class ExperienceOrb extends Entity{
$oneMinusDistance = (1 - $distance) ** 2; $oneMinusDistance = (1 - $distance) ** 2;
if($oneMinusDistance > 0){ if($oneMinusDistance > 0){
$this->motionX += $vector->x / $distance * $oneMinusDistance * 0.2; $this->motion->x += $vector->x / $distance * $oneMinusDistance * 0.2;
$this->motionY += $vector->y / $distance * $oneMinusDistance * 0.2; $this->motion->y += $vector->y / $distance * $oneMinusDistance * 0.2;
$this->motionZ += $vector->z / $distance * $oneMinusDistance * 0.2; $this->motion->z += $vector->z / $distance * $oneMinusDistance * 0.2;
} }
if($currentTarget->canPickupXp() and $this->boundingBox->intersectsWith($currentTarget->getBoundingBox())){ if($currentTarget->canPickupXp() and $this->boundingBox->intersectsWith($currentTarget->getBoundingBox())){

View File

@ -117,7 +117,7 @@ abstract class Projectile extends Entity{
* @return int * @return int
*/ */
public function getResultDamage() : int{ public function getResultDamage() : int{
return (int) ceil(sqrt($this->motionX ** 2 + $this->motionY ** 2 + $this->motionZ ** 2) * $this->damage); return (int) ceil($this->motion->length() * $this->damage);
} }
public function saveNBT() : void{ public function saveNBT() : void{
@ -159,7 +159,7 @@ abstract class Projectile extends Entity{
Timings::$entityMoveTimer->startTiming(); Timings::$entityMoveTimer->startTiming();
$start = $this->asVector3(); $start = $this->asVector3();
$end = $start->add($this->motionX, $this->motionY, $this->motionZ); $end = $start->add($this->motion);
$blockHit = null; $blockHit = null;
$entityHit = null; $entityHit = null;
@ -230,15 +230,15 @@ abstract class Projectile extends Entity{
} }
$this->isCollided = $this->onGround = true; $this->isCollided = $this->onGround = true;
$this->motionX = $this->motionY = $this->motionZ = 0; $this->motion->x = $this->motion->y = $this->motion->z = 0;
}else{ }else{
$this->isCollided = $this->onGround = false; $this->isCollided = $this->onGround = false;
$this->blockHit = $this->blockHitId = $this->blockHitData = null; $this->blockHit = $this->blockHitId = $this->blockHitData = null;
//recompute angles... //recompute angles...
$f = sqrt(($this->motionX ** 2) + ($this->motionZ ** 2)); $f = sqrt(($this->motion->x ** 2) + ($this->motion->z ** 2));
$this->yaw = (atan2($this->motionX, $this->motionZ) * 180 / M_PI); $this->yaw = (atan2($this->motion->x, $this->motion->z) * 180 / M_PI);
$this->pitch = (atan2($this->motionY, $f) * 180 / M_PI); $this->pitch = (atan2($this->motion->y, $f) * 180 / M_PI);
} }
$this->checkChunks(); $this->checkChunks();