From 8e12693494878d3725e7fd620525aa65a1278fe3 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Fri, 25 Sep 2020 16:35:59 +0100 Subject: [PATCH] Entity: Invalid blocksAround cache when something happens during onEntityInside() this fixes TNT spawning multiple entities when lit by flaming arrows. The problem here is a bit more complex (entities aren't immediately notified when local block updates happen, so they cache stuff that becomes unusable). The simplest option would be to just lose the cache, but that would have some impacts on performance. Barring a rethink of the block updating mechanism, this solution seems usable for now. --- src/block/Block.php | 7 +++++-- src/block/Cactus.php | 3 ++- src/block/Cobweb.php | 3 ++- src/block/Fire.php | 3 ++- src/block/Ladder.php | 3 ++- src/block/Lava.php | 3 ++- src/block/Magma.php | 3 ++- src/block/NetherPortal.php | 3 ++- src/block/TNT.php | 4 +++- src/block/Vine.php | 3 ++- src/block/Water.php | 3 ++- src/entity/Entity.php | 4 +++- 12 files changed, 29 insertions(+), 13 deletions(-) diff --git a/src/block/Block.php b/src/block/Block.php index 2022a55be..dae39760f 100644 --- a/src/block/Block.php +++ b/src/block/Block.php @@ -536,9 +536,12 @@ class Block{ /** * Called when an entity's bounding box clips inside this block's cell. Note that the entity may not be intersecting * with the collision box or bounding box. + * + * @return bool Whether the block is still the same after the intersection. If it changed (e.g. due to an explosive + * being ignited), this should return false. */ - public function onEntityInside(Entity $entity) : void{ - + public function onEntityInside(Entity $entity) : bool{ + return true; } /** diff --git a/src/block/Cactus.php b/src/block/Cactus.php index 951666623..6a24b8c2e 100644 --- a/src/block/Cactus.php +++ b/src/block/Cactus.php @@ -68,9 +68,10 @@ class Cactus extends Transparent{ return [AxisAlignedBB::one()->contract($shrinkSize, 0, $shrinkSize)->trim(Facing::UP, $shrinkSize)]; } - public function onEntityInside(Entity $entity) : void{ + public function onEntityInside(Entity $entity) : bool{ $ev = new EntityDamageByBlockEvent($this, $entity, EntityDamageEvent::CAUSE_CONTACT, 1); $entity->attack($ev); + return true; } public function onNearbyBlockChange() : void{ diff --git a/src/block/Cobweb.php b/src/block/Cobweb.php index e93641d7d..1f042ed29 100644 --- a/src/block/Cobweb.php +++ b/src/block/Cobweb.php @@ -37,8 +37,9 @@ class Cobweb extends Flowable{ return true; } - public function onEntityInside(Entity $entity) : void{ + public function onEntityInside(Entity $entity) : bool{ $entity->resetFallDistance(); + return true; } public function getDropsForCompatibleTool(Item $item) : array{ diff --git a/src/block/Fire.php b/src/block/Fire.php index c1b019a48..be94f8ab3 100644 --- a/src/block/Fire.php +++ b/src/block/Fire.php @@ -68,7 +68,7 @@ class Fire extends Flowable{ return true; } - public function onEntityInside(Entity $entity) : void{ + public function onEntityInside(Entity $entity) : bool{ $ev = new EntityDamageByBlockEvent($this, $entity, EntityDamageEvent::CAUSE_FIRE, 1); $entity->attack($ev); @@ -80,6 +80,7 @@ class Fire extends Flowable{ if(!$ev->isCancelled()){ $entity->setOnFire($ev->getDuration()); } + return true; } public function getDropsForCompatibleTool(Item $item) : array{ diff --git a/src/block/Ladder.php b/src/block/Ladder.php index 3ef3f073e..b696d8daa 100644 --- a/src/block/Ladder.php +++ b/src/block/Ladder.php @@ -66,11 +66,12 @@ class Ladder extends Transparent{ return true; } - public function onEntityInside(Entity $entity) : void{ + public function onEntityInside(Entity $entity) : bool{ if($entity instanceof Living && $entity->getPosition()->floor()->distanceSquared($this->pos) < 1){ //entity coordinates must be inside block $entity->resetFallDistance(); $entity->onGround = true; } + return true; } /** diff --git a/src/block/Lava.php b/src/block/Lava.php index aa1dec075..004049c00 100644 --- a/src/block/Lava.php +++ b/src/block/Lava.php @@ -87,7 +87,7 @@ class Lava extends Liquid{ } } - public function onEntityInside(Entity $entity) : void{ + public function onEntityInside(Entity $entity) : bool{ $entity->fallDistance *= 0.5; $ev = new EntityDamageByBlockEvent($this, $entity, EntityDamageEvent::CAUSE_LAVA, 4); @@ -100,5 +100,6 @@ class Lava extends Liquid{ } $entity->resetFallDistance(); + return true; } } diff --git a/src/block/Magma.php b/src/block/Magma.php index d16ae056b..2993e1e6b 100644 --- a/src/block/Magma.php +++ b/src/block/Magma.php @@ -43,11 +43,12 @@ class Magma extends Opaque{ return true; } - public function onEntityInside(Entity $entity) : void{ + public function onEntityInside(Entity $entity) : bool{ if($entity instanceof Living and !$entity->isSneaking()){ $ev = new EntityDamageByBlockEvent($this, $entity, EntityDamageEvent::CAUSE_FIRE, 1); $entity->attack($ev); } + return true; } public function burnsForever() : bool{ diff --git a/src/block/NetherPortal.php b/src/block/NetherPortal.php index c2003958f..70260994a 100644 --- a/src/block/NetherPortal.php +++ b/src/block/NetherPortal.php @@ -83,7 +83,8 @@ class NetherPortal extends Transparent{ return []; } - public function onEntityInside(Entity $entity) : void{ + public function onEntityInside(Entity $entity) : bool{ //TODO + return true; } } diff --git a/src/block/TNT.php b/src/block/TNT.php index 201b5c5dc..f9325afd1 100644 --- a/src/block/TNT.php +++ b/src/block/TNT.php @@ -83,10 +83,12 @@ class TNT extends Opaque{ return true; } - public function onEntityInside(Entity $entity) : void{ + public function onEntityInside(Entity $entity) : bool{ if($entity instanceof Arrow and $entity->isOnFire()){ $this->ignite(); + return false; } + return true; } public function ignite(int $fuse = 80) : void{ diff --git a/src/block/Vine.php b/src/block/Vine.php index ec86d57ab..ac76a81b5 100644 --- a/src/block/Vine.php +++ b/src/block/Vine.php @@ -81,8 +81,9 @@ class Vine extends Flowable{ return true; } - public function onEntityInside(Entity $entity) : void{ + public function onEntityInside(Entity $entity) : bool{ $entity->resetFallDistance(); + return true; } protected function recalculateCollisionBoxes() : array{ diff --git a/src/block/Water.php b/src/block/Water.php index d2d85baad..a516d4064 100644 --- a/src/block/Water.php +++ b/src/block/Water.php @@ -46,10 +46,11 @@ class Water extends Liquid{ return 5; } - public function onEntityInside(Entity $entity) : void{ + public function onEntityInside(Entity $entity) : bool{ $entity->resetFallDistance(); if($entity->isOnFire()){ $entity->extinguish(); } + return true; } } diff --git a/src/entity/Entity.php b/src/entity/Entity.php index 550852f40..e855c1b57 100644 --- a/src/entity/Entity.php +++ b/src/entity/Entity.php @@ -1279,7 +1279,9 @@ abstract class Entity{ $vectors = []; foreach($this->getBlocksAround() as $block){ - $block->onEntityInside($this); + if(!$block->onEntityInside($this)){ + $this->blocksAround = null; + } if(($v = $block->addVelocityToEntity($this)) !== null){ $vectors[] = $v; }