Eliminate remaining usages of legacy block ID+meta on disk

flower pots loaded from vanilla worlds should now correctly display the plant inside
This commit is contained in:
Dylan K. Taylor
2022-06-05 21:49:51 +01:00
parent 02568bb049
commit 5c85aa6e58
5 changed files with 98 additions and 69 deletions

View File

@ -24,7 +24,7 @@ declare(strict_types=1);
namespace pocketmine\entity\projectile;
use pocketmine\block\Block;
use pocketmine\block\BlockFactory;
use pocketmine\data\SavedDataLoadingException;
use pocketmine\entity\Entity;
use pocketmine\entity\Living;
use pocketmine\entity\Location;
@ -38,21 +38,24 @@ use pocketmine\event\entity\ProjectileHitEvent;
use pocketmine\math\RayTraceResult;
use pocketmine\math\Vector3;
use pocketmine\math\VoxelRayTrace;
use pocketmine\nbt\tag\ByteTag;
use pocketmine\nbt\NBT;
use pocketmine\nbt\tag\CompoundTag;
use pocketmine\nbt\tag\IntTag;
use pocketmine\nbt\tag\ListTag;
use pocketmine\timings\Timings;
use function assert;
use function atan2;
use function ceil;
use function count;
use function sqrt;
use const M_PI;
use const PHP_INT_MAX;
abstract class Projectile extends Entity{
private const TAG_STUCK_ON_BLOCK_POS = "StuckToBlockPos";
protected float $damage = 0.0;
protected ?Block $blockHit = null;
protected ?Vector3 $blockHit = null;
public function __construct(Location $location, ?Entity $shootingEntity, ?CompoundTag $nbt = null){
parent::__construct($location, $nbt);
@ -74,28 +77,18 @@ abstract class Projectile extends Entity{
$this->setHealth(1);
$this->damage = $nbt->getDouble("damage", $this->damage);
(function() use ($nbt) : void{
if(($tileXTag = $nbt->getTag("tileX")) instanceof IntTag && ($tileYTag = $nbt->getTag("tileY")) instanceof IntTag && ($tileZTag = $nbt->getTag("tileZ")) instanceof IntTag){
$blockPos = new Vector3($tileXTag->getValue(), $tileYTag->getValue(), $tileZTag->getValue());
}else{
return;
if(($stuckOnBlockPosTag = $nbt->getListTag(self::TAG_STUCK_ON_BLOCK_POS)) !== null){
if($stuckOnBlockPosTag->getTagType() !== NBT::TAG_Int || count($stuckOnBlockPosTag) !== 3){
throw new SavedDataLoadingException(self::TAG_STUCK_ON_BLOCK_POS . " tag should be a list of 3 TAG_Int");
}
if(($blockIdTag = $nbt->getTag("blockId")) instanceof IntTag){
$blockId = $blockIdTag->getValue();
}else{
return;
}
/** @var IntTag[] $values */
$values = $stuckOnBlockPosTag->getValue();
if(($blockDataTag = $nbt->getTag("blockData")) instanceof ByteTag){
$blockData = $blockDataTag->getValue();
}else{
return;
}
$this->blockHit = BlockFactory::getInstance()->get($blockId, $blockData);
$this->blockHit->position($this->getWorld(), $blockPos->getFloorX(), $blockPos->getFloorY(), $blockPos->getFloorZ());
})();
$this->blockHit = new Vector3($values[0]->getValue(), $values[1]->getValue(), $values[2]->getValue());
}elseif(($tileXTag = $nbt->getTag("tileX")) instanceof IntTag && ($tileYTag = $nbt->getTag("tileY")) instanceof IntTag && ($tileZTag = $nbt->getTag("tileZ")) instanceof IntTag){
$this->blockHit = new Vector3($tileXTag->getValue(), $tileYTag->getValue(), $tileZTag->getValue());
}
}
public function canCollideWith(Entity $entity) : bool{
@ -134,14 +127,11 @@ abstract class Projectile extends Entity{
$nbt->setDouble("damage", $this->damage);
if($this->blockHit !== null){
$pos = $this->blockHit->getPosition();
$nbt->setInt("tileX", $pos->x);
$nbt->setInt("tileY", $pos->y);
$nbt->setInt("tileZ", $pos->z);
//we intentionally use different ones to PC because we don't have stringy IDs
$nbt->setInt("blockId", $this->blockHit->getId());
$nbt->setByte("blockData", $this->blockHit->getMeta());
$nbt->setTag(self::TAG_STUCK_ON_BLOCK_POS, new ListTag([
new IntTag($this->blockHit->getFloorX()),
new IntTag($this->blockHit->getFloorY()),
new IntTag($this->blockHit->getFloorZ())
]));
}
return $nbt;
@ -152,8 +142,11 @@ abstract class Projectile extends Entity{
}
public function onNearbyBlockChange() : void{
if($this->blockHit !== null && $this->getWorld()->isInLoadedTerrain($this->blockHit->getPosition()) && !$this->blockHit->isSameState($this->getWorld()->getBlock($this->blockHit->getPosition()))){
$this->blockHit = null;
if($this->blockHit !== null && $this->getWorld()->isInLoadedTerrain($this->blockHit)){
$blockHit = $this->getWorld()->getBlock($this->blockHit);
if(!$blockHit->collidesWithBB($this->getBoundingBox()->expandedCopy(0.001, 0.001, 0.001))){
$this->blockHit = null;
}
}
parent::onNearbyBlockChange();
@ -312,6 +305,6 @@ abstract class Projectile extends Entity{
* Called when the projectile collides with a Block.
*/
protected function onHitBlock(Block $blockHit, RayTraceResult $hitResult) : void{
$this->blockHit = clone $blockHit;
$this->blockHit = $blockHit->getPosition()->asVector3();
}
}