diff --git a/src/entity/object/PrimedTNT.php b/src/entity/object/PrimedTNT.php index ec621adfb80..8355a9404c2 100644 --- a/src/entity/object/PrimedTNT.php +++ b/src/entity/object/PrimedTNT.php @@ -118,7 +118,6 @@ public function explode() : void{ $ev = new EntityPreExplodeEvent($this, 4); $ev->call(); if(!$ev->isCancelled()){ - //TODO: deal with underwater TNT (underwater TNT treats water as if it has a blast resistance of 0) $explosion = new Explosion(Position::fromObject($this->location->add(0, $this->size->getHeight() / 2, 0), $this->getWorld()), $ev->getRadius(), $this); if($ev->isBlockBreaking()){ $explosion->explodeA(); diff --git a/src/world/Explosion.php b/src/world/Explosion.php index 601f9109e27..401089aff7f 100644 --- a/src/world/Explosion.php +++ b/src/world/Explosion.php @@ -27,7 +27,9 @@ use pocketmine\block\RuntimeBlockStateRegistry; use pocketmine\block\TNT; use pocketmine\block\VanillaBlocks; +use pocketmine\block\Water; use pocketmine\entity\Entity; +use pocketmine\entity\object\PrimedTNT; use pocketmine\event\entity\EntityDamageByBlockEvent; use pocketmine\event\entity\EntityDamageByEntityEvent; use pocketmine\event\entity\EntityDamageEvent; @@ -82,6 +84,11 @@ public function explodeA() : bool{ return false; } + $worksUnderwater = false; + if($this->what instanceof PrimedTNT || $this->what instanceof TNT){ + $worksUnderwater = $this->what->worksUnderwater(); + } + $blockFactory = RuntimeBlockStateRegistry::getInstance(); $mRays = $this->rays - 1; @@ -120,12 +127,18 @@ public function explodeA() : bool{ $state = $subChunk->getBlockStateId($vBlockX & SubChunk::COORD_MASK, $vBlockY & SubChunk::COORD_MASK, $vBlockZ & SubChunk::COORD_MASK); $blastResistance = $blockFactory->blastResistance[$state] ?? 0; + if($worksUnderwater && $blockFactory->fromStateId($state) instanceof Water){ + $blastResistance = 0; + } if($blastResistance >= 0){ $blastForce -= ($blastResistance / 5 + 0.3) * $this->stepLen; if($blastForce > 0){ if(!isset($this->affectedBlocks[World::blockHash($vBlockX, $vBlockY, $vBlockZ)])){ $_block = $this->world->getBlockAt($vBlockX, $vBlockY, $vBlockZ, true, false); foreach($_block->getAffectedBlocks() as $_affectedBlock){ + if($_affectedBlock instanceof Water){ + continue; + } $_affectedBlockPos = $_affectedBlock->getPosition(); $this->affectedBlocks[World::blockHash($_affectedBlockPos->x, $_affectedBlockPos->y, $_affectedBlockPos->z)] = $_affectedBlock; }