Implemented scheduled and partial entity updates

This commit is contained in:
Shoghi Cervantes 2014-10-14 22:49:35 +02:00
parent fbe548c611
commit 18f6bad48d
8 changed files with 81 additions and 44 deletions

View File

@ -1192,16 +1192,18 @@ class Player extends Human implements CommandSender, InventoryHolder, IPlayer{
}
public function onUpdate(){
public function onUpdate($currentTick){
if($this->spawned === false or $this->dead === true){
return true;
}
$this->timings->startTiming();
$this->lastUpdate = $currentTick;
$this->processMovement();
$this->entityBaseTick();
$this->entityBaseTick(1);
if($this->onGround){
$this->inAirTicks = 0;
@ -1215,6 +1217,10 @@ class Player extends Human implements CommandSender, InventoryHolder, IPlayer{
}
foreach($this->level->getNearbyEntities($this->boundingBox->grow(1, 1, 1), $this) as $entity){
if(($currentTick - $entity->lastUpdate) > 1){
$entity->scheduleUpdate();
}
if($entity instanceof Arrow and $entity->onGround and $this->motionX == 0 and $this->motionY == 0 and $this->motionZ == 0){
if($entity->dead !== true){
$item = Item::get(Item::ARROW, 0, 1);

View File

@ -67,14 +67,17 @@ class Arrow extends Projectile{
}
public function onUpdate(){
public function onUpdate($currentTick){
if($this->closed){
return false;
}
$this->timings->startTiming();
$this->entityBaseTick();
$tickDiff = max(1, $currentTick - $this->lastUpdate);
$this->lastUpdate = $currentTick;
$hasUpdate = $this->entityBaseTick($tickDiff);
if(!$this->dead){
@ -143,6 +146,7 @@ class Arrow extends Projectile{
}
$this->kill();
return true;
}
}
@ -156,14 +160,16 @@ class Arrow extends Projectile{
$this->server->getPluginManager()->callEvent(new ProjectileHitEvent($this));
}
if($this->motionX != 0 or $this->motionY != 0 or $this->motionZ != 0){
if(!$this->onGround or $this->motionX != 0 or $this->motionY != 0 or $this->motionZ != 0){
$f = sqrt(($this->motionX ** 2) + ($this->motionZ ** 2));
$this->yaw = (atan2($this->motionX, $this->motionZ) * 180 / M_PI);
$this->pitch = (atan2($this->motionY, $f) * 180 / M_PI);
$hasUpdate = true;
}
if($this->age > 1200){
$this->kill();
$hasUpdate = true;
}
$this->updateMovement();
@ -171,7 +177,7 @@ class Arrow extends Projectile{
$this->timings->stopTiming();
return !$this->onGround or ($this->motionX == 0 and $this->motionY == 0 and $this->motionZ == 0);
return $hasUpdate;
}
public function attack($damage, $source = EntityDamageEvent::CAUSE_MAGIC){

View File

@ -73,19 +73,22 @@ class DroppedItem extends Entity{
$this->server->getPluginManager()->callEvent(new ItemSpawnEvent($this));
}
public function onUpdate(){
public function onUpdate($currentTick){
if($this->closed !== false){
return false;
}
$tickDiff = max(1, $currentTick - $this->lastUpdate);
$this->lastUpdate = $currentTick;
$this->timings->startTiming();
$this->entityBaseTick();
$hasUpdate = $this->entityBaseTick($tickDiff);
if(!$this->dead){
if($this->pickupDelay > 0 and $this->pickupDelay < 32767){ //Infinite delay
--$this->pickupDelay;
$this->pickupDelay -= $tickDiff;
}
$this->motionY -= $this->gravity;
@ -115,6 +118,7 @@ class DroppedItem extends Entity{
$this->age = 0;
}else{
$this->kill();
$hasUpdate = true;
}
}
@ -122,7 +126,7 @@ class DroppedItem extends Entity{
$this->timings->stopTiming();
return !$this->onGround or ($this->motionX == 0 and $this->motionY == 0 and $this->motionZ == 0);
return $hasUpdate or !$this->onGround or ($this->motionX == 0 and $this->motionY == 0 and $this->motionZ == 0);
}
public function attack($damage, $source = EntityDamageEvent::CAUSE_MAGIC){

View File

@ -142,8 +142,6 @@ abstract class Entity extends Location implements Metadatable{
protected $fireProof;
private $invulnerable;
protected $spawnTime;
protected $gravity;
protected $drag;
@ -215,7 +213,7 @@ abstract class Entity extends Location implements Metadatable{
$this->chunk->addEntity($this);
$this->getLevel()->addEntity($this);
$this->initEntity();
$this->lastUpdate = $this->spawnTime = microtime(true);
$this->lastUpdate = $this->server->getTick();
$this->server->getPluginManager()->callEvent(new EntitySpawnEvent($this));
$this->scheduleUpdate();
@ -462,7 +460,7 @@ abstract class Entity extends Location implements Metadatable{
}
}
public function entityBaseTick(){
public function entityBaseTick($tickDiff = 1){
Timings::$tickEntityTimer->startTiming();
//TODO: check vehicles
@ -476,7 +474,7 @@ abstract class Entity extends Location implements Metadatable{
$this->close();
}
Timings::$tickEntityTimer->stopTiming();
return false;
return $isPlayer;
}
$hasUpdate = false;
@ -488,36 +486,39 @@ abstract class Entity extends Location implements Metadatable{
if(!$ev->isCancelled()){
$this->attack($ev->getFinalDamage(), $ev);
}
$hasUpdate = true;
}
if($this->fireTicks > 0){
if($this->fireProof){
$this->fireTicks -= 4;
$this->fireTicks -= 4 * $tickDiff;
if($this->fireTicks < 0){
$this->fireTicks = 0;
}
}else{
if(($this->fireTicks % 20) === 0){
if(($this->fireTicks % 20) === 0 or $tickDiff > 20){
$ev = new EntityDamageEvent($this, EntityDamageEvent::CAUSE_FIRE_TICK, 1);
$this->server->getPluginManager()->callEvent($ev);
if(!$ev->isCancelled()){
$this->attack($ev->getFinalDamage(), $ev);
}
}
--$this->fireTicks;
$this->fireTicks -= $tickDiff;
}
if($this->fireTicks <= 0){
$this->extinguish();
}else{
$hasUpdate = true;
}
$hasUpdate = true;
}
++$this->age;
++$this->ticksLived;
$this->age += $tickDiff;
$this->ticksLived += $tickDiff;
Timings::$tickEntityTimer->stopTiming();
return $hasUpdate;
}
public function updateMovement(){
@ -587,20 +588,24 @@ abstract class Entity extends Location implements Metadatable{
return new Vector3($x, $y, $z);
}
public function onUpdate(){
public function onUpdate($currentTick){
if($this->closed){
return false;
}
$tickDiff = max(1, $currentTick - $this->lastUpdate);
$this->lastUpdate = $currentTick;
$this->timings->startTiming();
$hasUpdate = $this->entityBaseTick();
$hasUpdate = $this->entityBaseTick($tickDiff);
$this->updateMovement();
$this->timings->stopTiming();
//if($this->isStatic())
return true;
return $hasUpdate;
//return !($this instanceof Player);
}

View File

@ -66,7 +66,7 @@ class FallingBlock extends Entity{
return [];
}
public function onUpdate(){
public function onUpdate($currentTick){
if($this->closed){
return false;
@ -74,7 +74,10 @@ class FallingBlock extends Entity{
$this->timings->startTiming();
$this->entityBaseTick();
$tickDiff = max(1, $currentTick - $this->lastUpdate);
$this->lastUpdate = $currentTick;
$hasUpdate = $this->entityBaseTick($tickDiff);
if(!$this->dead){
if($this->ticksLived === 1){
@ -110,13 +113,13 @@ class FallingBlock extends Entity{
$this->getLevel()->setBlock($pos, $ev->getTo(), true);
}
}
$hasUpdate = true;
}
$this->updateMovement();
}
return !$this->onGround or ($this->motionX == 0 and $this->motionY == 0 and $this->motionZ == 0);
return $hasUpdate or !$this->onGround or ($this->motionX == 0 and $this->motionY == 0 and $this->motionZ == 0);
}
public function getBlock(){

View File

@ -130,7 +130,7 @@ abstract class Living extends Entity implements Damageable{
}
}
public function entityBaseTick(){
public function entityBaseTick($tickDiff = 1){
Timings::$timerEntityBaseTick->startTiming();
parent::entityBaseTick();
@ -142,7 +142,7 @@ abstract class Living extends Entity implements Damageable{
}
if($this->dead !== true and $this->isInsideOfWater()){
--$this->airTicks;
$this->airTicks -= $tickDiff;
if($this->airTicks <= -20){
$this->airTicks = 0;
@ -156,7 +156,7 @@ abstract class Living extends Entity implements Damageable{
}
if($this->attackTime > 0){
--$this->attackTime;
$this->attackTime -= $tickDiff;
}
Timings::$timerEntityBaseTick->stopTiming();

View File

@ -71,7 +71,7 @@ class PrimedTNT extends Entity implements Explosive{
$this->namedtag->Fuse = new Byte("Fuse", $this->fuse);
}
public function onUpdate(){
public function onUpdate($currentTick){
if($this->closed){
return false;
@ -79,7 +79,10 @@ class PrimedTNT extends Entity implements Explosive{
$this->timings->startTiming();
$this->entityBaseTick();
$tickDiff = max(1, $currentTick - $this->lastUpdate);
$this->lastUpdate = $currentTick;
$hasUpdate = $this->entityBaseTick($tickDiff);
if(!$this->dead){
@ -101,7 +104,9 @@ class PrimedTNT extends Entity implements Explosive{
$this->motionZ *= 0.7;
}
if($this->fuse-- <= 0){
$this->fuse -= $tickDiff;
if($this->fuse <= 0){
$this->kill();
$this->explode();
}else{
@ -111,7 +116,7 @@ class PrimedTNT extends Entity implements Explosive{
}
return !$this->onGround or ($this->motionX == 0 and $this->motionY == 0 and $this->motionZ == 0);
return $hasUpdate or $this->fuse > 0 or ($this->motionX == 0 and $this->motionY == 0 and $this->motionZ == 0);
}
public function attack($damage, $source = EntityDamageEvent::CAUSE_MAGIC){

View File

@ -264,6 +264,7 @@ class Level implements ChunkManager, Metadatable{
$this->chunksPerTick = (int) $this->server->getProperty("chunk-ticking.per-tick", 80);
$this->chunkTickList = [];
$this->clearChunksOnTick = (bool) $this->server->getProperty("chunk-ticking.clear-tick-list", false);
$this->timings = new LevelTimings($this);
}
@ -472,15 +473,13 @@ class Level implements ChunkManager, Metadatable{
$this->timings->entityTick->startTiming();
//Update entities that need update
//if(count($this->updateEntities) > 0){
Timings::$tickEntityTimer->startTiming();
foreach($this->entities as $id => $entity){
if(!$entity->closed){
$entity->onUpdate();
}
Timings::$tickEntityTimer->startTiming();
foreach($this->updateEntities as $id => $entity){
if(!$entity->closed or !$entity->onUpdate($currentTick)){
unset($this->updateEntities[$id]);
}
Timings::$tickEntityTimer->stopTiming();
//}
}
Timings::$tickEntityTimer->stopTiming();
$this->timings->entityTick->stopTiming();
$this->timings->tileEntityTick->startTiming();
@ -593,6 +592,10 @@ class Level implements ChunkManager, Metadatable{
}
$chunk = $this->getChunk($chunkX, $chunkZ, true);
foreach($chunk->getEntities() as $entity){
$entity->scheduleUpdate();
}
if($this->useSections){
foreach($chunk->getSections() as $section){
@ -965,6 +968,9 @@ class Level implements ChunkManager, Metadatable{
if($update === true){
$this->updateAround($pos, self::BLOCK_UPDATE_NORMAL);
$block->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){
$entity->scheduleUpdate();
}
}
}
}
@ -1730,6 +1736,7 @@ class Level implements ChunkManager, Metadatable{
}
unset($this->entities[$entity->getID()]);
unset($this->updateEntities[$entity->getID()]);
}
/**
@ -1770,6 +1777,7 @@ class Level implements ChunkManager, Metadatable{
}
unset($this->tiles[$tile->getID()]);
unset($this->updateTiles[$tile->getID()]);
}
/**