First step towards removing Vector3 from Block

This commit is contained in:
Dylan K. Taylor 2024-12-04 15:54:31 +00:00
parent 205aabe11f
commit 224fa09327
No known key found for this signature in database
GPG Key ID: 8927471A91CAFD3D
113 changed files with 456 additions and 1001 deletions

View File

@ -116,7 +116,7 @@ class Bamboo extends Transparent{
} }
public function getModelPositionOffset() : ?Vector3{ public function getModelPositionOffset() : ?Vector3{
$seed = self::getOffsetSeed($this->position->getFloorX(), 0, $this->position->getFloorZ()); $seed = self::getOffsetSeed($this->position->x, 0, $this->position->z);
$retX = (($seed % 12) + 1) / 16; $retX = (($seed % 12) + 1) / 16;
$retZ = ((($seed >> 8) % 12) + 1) / 16; $retZ = ((($seed >> 8) % 12) + 1) / 16;
return new Vector3($retX, 0, $retZ); return new Vector3($retX, 0, $retZ);
@ -135,7 +135,7 @@ class Bamboo extends Transparent{
private function seekToTop() : Bamboo{ private function seekToTop() : Bamboo{
$world = $this->position->getWorld(); $world = $this->position->getWorld();
$top = $this; $top = $this;
while(($next = $world->getBlock($top->position->up())) instanceof Bamboo && $next->hasSameTypeId($this)){ while(($next = $world->getBlock($top->position->getSide(Facing::UP))) instanceof Bamboo && $next->hasSameTypeId($this)){
$top = $next; $top = $next;
} }
return $top; return $top;
@ -144,7 +144,7 @@ class Bamboo extends Transparent{
public function onInteract(Item $item, int $face, Vector3 $clickVector, ?Player $player = null, array &$returnedItems = []) : bool{ public function onInteract(Item $item, int $face, Vector3 $clickVector, ?Player $player = null, array &$returnedItems = []) : bool{
if($item instanceof Fertilizer){ if($item instanceof Fertilizer){
$top = $this->seekToTop(); $top = $this->seekToTop();
if($top->grow(self::getMaxHeight($top->position->getFloorX(), $top->position->getFloorZ()), mt_rand(1, 2), $player)){ if($top->grow(self::getMaxHeight($top->position->x, $top->position->z), mt_rand(1, 2), $player)){
$item->pop(); $item->pop();
return true; return true;
} }
@ -159,12 +159,12 @@ class Bamboo extends Transparent{
private function grow(int $maxHeight, int $growAmount, ?Player $player) : bool{ private function grow(int $maxHeight, int $growAmount, ?Player $player) : bool{
$world = $this->position->getWorld(); $world = $this->position->getWorld();
if(!$world->getBlock($this->position->up())->canBeReplaced()){ if(!$world->getBlock($this->position->getSide(Facing::UP))->canBeReplaced()){
return false; return false;
} }
$height = 1; $height = 1;
while($world->getBlock($this->position->subtract(0, $height, 0))->hasSameTypeId($this)){ while($world->getBlock($this->position->getSide(Facing::DOWN, $height))->hasSameTypeId($this)){
if(++$height >= $maxHeight){ if(++$height >= $maxHeight){
return false; return false;
} }
@ -201,7 +201,7 @@ class Bamboo extends Transparent{
$tx = new BlockTransaction($world); $tx = new BlockTransaction($world);
foreach($newBlocks as $idx => $newBlock){ foreach($newBlocks as $idx => $newBlock){
$tx->addBlock($this->position->subtract(0, $idx - $growAmount, 0), $newBlock); $tx->addBlock($this->position->getSide(Facing::DOWN, $idx - $growAmount), $newBlock);
} }
$ev = new StructureGrowEvent($this, $tx, $player); $ev = new StructureGrowEvent($this, $tx, $player);
@ -221,10 +221,10 @@ class Bamboo extends Transparent{
$world = $this->position->getWorld(); $world = $this->position->getWorld();
if($this->ready){ if($this->ready){
$this->ready = false; $this->ready = false;
if($world->getFullLight($this->position) < 9 || !$this->grow(self::getMaxHeight($this->position->getFloorX(), $this->position->getFloorZ()), 1, null)){ if($world->getFullLight($this->position) < 9 || !$this->grow(self::getMaxHeight($this->position->x, $this->position->z), 1, null)){
$world->setBlock($this->position, $this); $world->setBlock($this->position, $this);
} }
}elseif($world->getBlock($this->position->up())->canBeReplaced()){ }elseif($world->getBlock($this->position->getSide(Facing::UP))->canBeReplaced()){
$this->ready = true; $this->ready = true;
$world->setBlock($this->position, $this); $world->setBlock($this->position, $this);
} }

View File

@ -73,14 +73,14 @@ final class BambooSapling extends Flowable{
private function grow(?Player $player) : bool{ private function grow(?Player $player) : bool{
$world = $this->position->getWorld(); $world = $this->position->getWorld();
if(!$world->getBlock($this->position->up())->canBeReplaced()){ if(!$world->getBlock($this->position->getSide(Facing::UP))->canBeReplaced()){
return false; return false;
} }
$tx = new BlockTransaction($world); $tx = new BlockTransaction($world);
$bamboo = VanillaBlocks::BAMBOO(); $bamboo = VanillaBlocks::BAMBOO();
$tx->addBlock($this->position, $bamboo) $tx->addBlock($this->position, $bamboo)
->addBlock($this->position->up(), (clone $bamboo)->setLeafSize(Bamboo::SMALL_LEAVES)); ->addBlock($this->position->getSide(Facing::UP), (clone $bamboo)->setLeafSize(Bamboo::SMALL_LEAVES));
$ev = new StructureGrowEvent($this, $tx, $player); $ev = new StructureGrowEvent($this, $tx, $player);
$ev->call(); $ev->call();
@ -102,7 +102,7 @@ final class BambooSapling extends Flowable{
if($world->getFullLight($this->position) < 9 || !$this->grow(null)){ if($world->getFullLight($this->position) < 9 || !$this->grow(null)){
$world->setBlock($this->position, $this); $world->setBlock($this->position, $this);
} }
}elseif($world->getBlock($this->position->up())->canBeReplaced()){ }elseif($world->getBlock($this->position->getSide(Facing::UP))->canBeReplaced()){
$this->ready = true; $this->ready = true;
$world->setBlock($this->position, $this); $world->setBlock($this->position, $this);
} }

View File

@ -99,10 +99,10 @@ abstract class BaseBigDripleaf extends Transparent{
return false; return false;
} }
$pos = $head->position; $pos = $head->position;
$up = $pos->up(); $up = $pos->getSide(Facing::UP);
$world = $pos->getWorld(); $world = $pos->getWorld();
if( if(
!$world->isInWorld($up->getFloorX(), $up->getFloorY(), $up->getFloorZ()) || !$world->isInWorld($up->x, $up->y, $up->z) ||
$world->getBlock($up)->getTypeId() !== BlockTypeIds::AIR $world->getBlock($up)->getTypeId() !== BlockTypeIds::AIR
){ ){
return false; return false;

View File

@ -27,6 +27,7 @@ use pocketmine\block\utils\BlockEventHelper;
use pocketmine\block\utils\CoralTypeTrait; use pocketmine\block\utils\CoralTypeTrait;
use pocketmine\block\utils\SupportType; use pocketmine\block\utils\SupportType;
use pocketmine\item\Item; use pocketmine\item\Item;
use pocketmine\math\Facing;
use function mt_rand; use function mt_rand;
abstract class BaseCoral extends Transparent{ abstract class BaseCoral extends Transparent{
@ -55,11 +56,9 @@ abstract class BaseCoral extends Transparent{
public function isSolid() : bool{ return false; } public function isSolid() : bool{ return false; }
protected function isCoveredWithWater() : bool{ protected function isCoveredWithWater() : bool{
$world = $this->position->getWorld();
$hasWater = false; $hasWater = false;
foreach($this->position->sides() as $vector3){ foreach(Facing::ALL as $side){
if($world->getBlock($vector3) instanceof Water){ if($this->getSide($side) instanceof Water){
$hasWater = true; $hasWater = true;
break; break;
} }

View File

@ -145,7 +145,7 @@ abstract class BaseSign extends Transparent{
private function changeSignGlowingState(bool $glowing, Player $player, Item $item) : bool{ private function changeSignGlowingState(bool $glowing, Player $player, Item $item) : bool{
if($this->text->isGlowing() !== $glowing && $this->doSignChange(new SignText($this->text->getLines(), $this->text->getBaseColor(), $glowing), $player, $item)){ if($this->text->isGlowing() !== $glowing && $this->doSignChange(new SignText($this->text->getLines(), $this->text->getBaseColor(), $glowing), $player, $item)){
$this->position->getWorld()->addSound($this->position, new InkSacUseSound()); $this->position->getWorld()->addSound($this->position->asVector3(), new InkSacUseSound());
return true; return true;
} }
return false; return false;
@ -183,7 +183,7 @@ abstract class BaseSign extends Transparent{
$color->toARGB() !== $this->text->getBaseColor()->toARGB() && $color->toARGB() !== $this->text->getBaseColor()->toARGB() &&
$this->doSignChange(new SignText($this->text->getLines(), $color, $this->text->isGlowing()), $player, $item) $this->doSignChange(new SignText($this->text->getLines(), $color, $this->text->isGlowing()), $player, $item)
){ ){
$this->position->getWorld()->addSound($this->position, new DyeUseSound()); $this->position->getWorld()->addSound($this->position->asVector3(), new DyeUseSound());
return true; return true;
} }
}elseif(match($item->getTypeId()){ }elseif(match($item->getTypeId()){

View File

@ -128,7 +128,7 @@ class Bed extends Transparent{
$player->sendMessage(TextFormat::GRAY . "This bed is incomplete"); $player->sendMessage(TextFormat::GRAY . "This bed is incomplete");
return true; return true;
}elseif($playerPos->distanceSquared($this->position) > 4 && $playerPos->distanceSquared($other->position) > 4){ }elseif($playerPos->distanceSquared($this->position->asVector3()) > 4 && $playerPos->distanceSquared($other->position->asVector3()) > 4){
$player->sendMessage(KnownTranslationFactory::tile_bed_tooFar()->prefix(TextFormat::GRAY)); $player->sendMessage(KnownTranslationFactory::tile_bed_tooFar()->prefix(TextFormat::GRAY));
return true; return true;
} }

View File

@ -143,10 +143,10 @@ final class Bell extends Transparent{
public function ring(int $faceHit) : void{ public function ring(int $faceHit) : void{
$world = $this->position->getWorld(); $world = $this->position->getWorld();
$world->addSound($this->position, new BellRingSound()); $world->addSound($this->position->asVector3(), new BellRingSound());
$tile = $world->getTile($this->position); $tile = $world->getTile($this->position);
if($tile instanceof TileBell){ if($tile instanceof TileBell){
$world->broadcastPacketToViewers($this->position, $tile->createFakeUpdatePacket($faceHit)); $world->broadcastPacketToViewers($this->position->asVector3(), $tile->createFakeUpdatePacket($faceHit));
} }
} }

View File

@ -93,7 +93,7 @@ class BigDripleafHead extends BaseBigDripleaf{
public function onProjectileHit(Projectile $projectile, RayTraceResult $hitResult) : void{ public function onProjectileHit(Projectile $projectile, RayTraceResult $hitResult) : void{
if($this->leafState !== DripleafState::FULL_TILT){ if($this->leafState !== DripleafState::FULL_TILT){
$this->setTiltAndScheduleTick(DripleafState::FULL_TILT); $this->setTiltAndScheduleTick(DripleafState::FULL_TILT);
$this->position->getWorld()->addSound($this->position, new DripleafTiltDownSound()); $this->position->getWorld()->addSound($this->position->asVector3(), new DripleafTiltDownSound());
} }
} }
@ -101,13 +101,13 @@ class BigDripleafHead extends BaseBigDripleaf{
if($this->leafState !== DripleafState::STABLE){ if($this->leafState !== DripleafState::STABLE){
if($this->leafState === DripleafState::FULL_TILT){ if($this->leafState === DripleafState::FULL_TILT){
$this->position->getWorld()->setBlock($this->position, $this->setLeafState(DripleafState::STABLE)); $this->position->getWorld()->setBlock($this->position, $this->setLeafState(DripleafState::STABLE));
$this->position->getWorld()->addSound($this->position, new DripleafTiltUpSound()); $this->position->getWorld()->addSound($this->position->asVector3(), new DripleafTiltUpSound());
}else{ }else{
$this->setTiltAndScheduleTick(match($this->leafState){ $this->setTiltAndScheduleTick(match($this->leafState){
DripleafState::UNSTABLE => DripleafState::PARTIAL_TILT, DripleafState::UNSTABLE => DripleafState::PARTIAL_TILT,
DripleafState::PARTIAL_TILT => DripleafState::FULL_TILT, DripleafState::PARTIAL_TILT => DripleafState::FULL_TILT,
}); });
$this->position->getWorld()->addSound($this->position, new DripleafTiltDownSound()); $this->position->getWorld()->addSound($this->position->asVector3(), new DripleafTiltDownSound());
} }
} }
} }

View File

@ -73,7 +73,7 @@ class Block{
protected BlockIdentifier $idInfo; protected BlockIdentifier $idInfo;
protected string $fallbackName; protected string $fallbackName;
protected BlockTypeInfo $typeInfo; protected BlockTypeInfo $typeInfo;
protected Position $position; protected BlockPosition $position;
/** @var AxisAlignedBB[]|null */ /** @var AxisAlignedBB[]|null */
protected ?array $collisionBoxes = null; protected ?array $collisionBoxes = null;
@ -107,7 +107,7 @@ class Block{
$this->idInfo = $idInfo; $this->idInfo = $idInfo;
$this->fallbackName = $name; $this->fallbackName = $name;
$this->typeInfo = $typeInfo; $this->typeInfo = $typeInfo;
$this->position = new Position(0, 0, 0, null); $this->position = new BlockPosition(0, 0, 0, null);
$calculator = new RuntimeDataSizeCalculator(); $calculator = new RuntimeDataSizeCalculator();
$this->describeBlockItemState($calculator); $this->describeBlockItemState($calculator);
@ -377,7 +377,7 @@ class Block{
*/ */
public function writeStateToWorld() : void{ public function writeStateToWorld() : void{
$world = $this->position->getWorld(); $world = $this->position->getWorld();
$chunk = $world->getOrLoadChunkAtPosition($this->position); $chunk = $world->loadChunk($this->position->x >> Chunk::COORD_BIT_SIZE, $this->position->z >> Chunk::COORD_BIT_SIZE);
if($chunk === null){ if($chunk === null){
throw new AssumptionFailedError("World::setBlock() should have loaded the chunk before calling this method"); throw new AssumptionFailedError("World::setBlock() should have loaded the chunk before calling this method");
} }
@ -608,7 +608,7 @@ class Block{
return false; return false;
} }
final public function getPosition() : Position{ final public function getPosition() : BlockPosition{
return $this->position; return $this->position;
} }
@ -616,7 +616,7 @@ class Block{
* @internal * @internal
*/ */
final public function position(World $world, int $x, int $y, int $z) : void{ final public function position(World $world, int $x, int $y, int $z) : void{
$this->position = new Position($x, $y, $z, $world); $this->position = new BlockPosition($x, $y, $z, $world);
$this->collisionBoxes = null; $this->collisionBoxes = null;
} }
@ -912,9 +912,9 @@ class Block{
if($this->collisionBoxes === null){ if($this->collisionBoxes === null){
$this->collisionBoxes = $this->recalculateCollisionBoxes(); $this->collisionBoxes = $this->recalculateCollisionBoxes();
$extraOffset = $this->getModelPositionOffset(); $extraOffset = $this->getModelPositionOffset();
$offset = $extraOffset !== null ? $this->position->addVector($extraOffset) : $this->position; [$dx, $dy, $dz] = $extraOffset !== null ? [$extraOffset->x, $extraOffset->y, $extraOffset->z] : [0, 0, 0];
foreach($this->collisionBoxes as $bb){ foreach($this->collisionBoxes as $bb){
$bb->offset($offset->x, $offset->y, $offset->z); $bb->offset($this->position->x + $dx, $this->position->y + $dy, $this->position->z + $dz);
} }
} }

View File

@ -67,7 +67,7 @@ abstract class Button extends Flowable{
$world = $this->position->getWorld(); $world = $this->position->getWorld();
$world->setBlock($this->position, $this); $world->setBlock($this->position, $this);
$world->scheduleDelayedBlockUpdate($this->position, $this->getActivationTime()); $world->scheduleDelayedBlockUpdate($this->position, $this->getActivationTime());
$world->addSound($this->position->add(0.5, 0.5, 0.5), new RedstonePowerOnSound()); $world->addSound($this->position->asVector3()->add(0.5, 0.5, 0.5), new RedstonePowerOnSound());
} }
return true; return true;
@ -78,7 +78,7 @@ abstract class Button extends Flowable{
$this->pressed = false; $this->pressed = false;
$world = $this->position->getWorld(); $world = $this->position->getWorld();
$world->setBlock($this->position, $this); $world->setBlock($this->position, $this);
$world->addSound($this->position->add(0.5, 0.5, 0.5), new RedstonePowerOffSound()); $world->addSound($this->position->asVector3()->add(0.5, 0.5, 0.5), new RedstonePowerOffSound());
} }
} }

View File

@ -76,6 +76,6 @@ class CakeWithCandle extends BaseCake{
public function onConsume(Living $consumer) : void{ public function onConsume(Living $consumer) : void{
parent::onConsume($consumer); parent::onConsume($consumer);
$this->position->getWorld()->dropItem($this->position->add(0.5, 0.5, 0.5), $this->getCandle()->asItem()); $this->position->getWorld()->dropItem($this->position->asVector3()->add(0.5, 0.5, 0.5), $this->getCandle()->asItem());
} }
} }

View File

@ -185,7 +185,7 @@ class Campfire extends Transparent{
if($item->getTypeId() === ItemTypeIds::FIRE_CHARGE){ if($item->getTypeId() === ItemTypeIds::FIRE_CHARGE){
$item->pop(); $item->pop();
$this->ignite(); $this->ignite();
$this->position->getWorld()->addSound($this->position, new BlazeShootSound()); $this->position->getWorld()->addSound($this->position->asVector3(), new BlazeShootSound());
return true; return true;
}elseif($item->getTypeId() === ItemTypeIds::FLINT_AND_STEEL || $item->hasEnchantment(VanillaEnchantments::FIRE_ASPECT())){ }elseif($item->getTypeId() === ItemTypeIds::FLINT_AND_STEEL || $item->hasEnchantment(VanillaEnchantments::FIRE_ASPECT())){
if($item instanceof Durable){ if($item instanceof Durable){
@ -205,7 +205,7 @@ class Campfire extends Transparent{
$ingredient->setCount(1); $ingredient->setCount(1);
if(count($this->inventory->addItem($ingredient)) === 0){ if(count($this->inventory->addItem($ingredient)) === 0){
$item->pop(); $item->pop();
$this->position->getWorld()->addSound($this->position, new ItemFrameAddItemSound()); $this->position->getWorld()->addSound($this->position->asVector3(), new ItemFrameAddItemSound());
return true; return true;
} }
} }
@ -259,26 +259,26 @@ class Campfire extends Transparent{
$this->inventory->setItem($slot, VanillaItems::AIR()); $this->inventory->setItem($slot, VanillaItems::AIR());
$this->setCookingTime($slot, 0); $this->setCookingTime($slot, 0);
$this->position->getWorld()->dropItem($this->position->add(0.5, 1, 0.5), $ev->getResult()); $this->position->getWorld()->dropItem($this->position->asVector3()->add(0.5, 1, 0.5), $ev->getResult());
} }
} }
if(count($items) > 0){ if(count($items) > 0){
$this->position->getWorld()->setBlock($this->position, $this); $this->position->getWorld()->setBlock($this->position, $this);
} }
if(mt_rand(1, 6) === 1){ if(mt_rand(1, 6) === 1){
$this->position->getWorld()->addSound($this->position, $furnaceType->getCookSound()); $this->position->getWorld()->addSound($this->position->asVector3(), $furnaceType->getCookSound());
} }
$this->position->getWorld()->scheduleDelayedBlockUpdate($this->position, self::UPDATE_INTERVAL_TICKS); $this->position->getWorld()->scheduleDelayedBlockUpdate($this->position, self::UPDATE_INTERVAL_TICKS);
} }
} }
private function extinguish() : void{ private function extinguish() : void{
$this->position->getWorld()->addSound($this->position, new FireExtinguishSound()); $this->position->getWorld()->addSound($this->position->asVector3(), new FireExtinguishSound());
$this->position->getWorld()->setBlock($this->position, $this->setLit(false)); $this->position->getWorld()->setBlock($this->position, $this->setLit(false));
} }
private function ignite() : void{ private function ignite() : void{
$this->position->getWorld()->addSound($this->position, new FlintSteelSound()); $this->position->getWorld()->addSound($this->position->asVector3(), new FlintSteelSound());
$this->position->getWorld()->setBlock($this->position, $this->setLit(true)); $this->position->getWorld()->setBlock($this->position, $this->setLit(true));
$this->position->getWorld()->scheduleDelayedBlockUpdate($this->position, self::UPDATE_INTERVAL_TICKS); $this->position->getWorld()->scheduleDelayedBlockUpdate($this->position, self::UPDATE_INTERVAL_TICKS);
} }

View File

@ -69,7 +69,7 @@ final class Cauldron extends Transparent{
*/ */
private function fill(int $amount, FillableCauldron $result, Item $usedItem, Item $returnedItem, array &$returnedItems) : void{ private function fill(int $amount, FillableCauldron $result, Item $usedItem, Item $returnedItem, array &$returnedItems) : void{
$this->position->getWorld()->setBlock($this->position, $result->setFillLevel($amount)); $this->position->getWorld()->setBlock($this->position, $result->setFillLevel($amount));
$this->position->getWorld()->addSound($this->position->add(0.5, 0.5, 0.5), $result->getFillSound()); $this->position->getWorld()->addSound($this->position->asVector3()->add(0.5, 0.5, 0.5), $result->getFillSound());
$usedItem->pop(); $usedItem->pop();
$returnedItems[] = $returnedItem; $returnedItems[] = $returnedItem;
@ -95,10 +95,10 @@ final class Cauldron extends Transparent{
public function onNearbyBlockChange() : void{ public function onNearbyBlockChange() : void{
$world = $this->position->getWorld(); $world = $this->position->getWorld();
if($world->getBlock($this->position->up())->getTypeId() === BlockTypeIds::WATER){ if($this->getSide(Facing::UP)->getTypeId() === BlockTypeIds::WATER){
$cauldron = VanillaBlocks::WATER_CAULDRON()->setFillLevel(FillableCauldron::MAX_FILL_LEVEL); $cauldron = VanillaBlocks::WATER_CAULDRON()->setFillLevel(FillableCauldron::MAX_FILL_LEVEL);
$world->setBlock($this->position, $cauldron); $world->setBlock($this->position, $cauldron);
$world->addSound($this->position->add(0.5, 0.5, 0.5), $cauldron->getFillSound()); $world->addSound($this->position->asVector3()->add(0.5, 0.5, 0.5), $cauldron->getFillSound());
} }
} }
} }

View File

@ -90,8 +90,8 @@ class CaveVines extends Flowable{
public function onInteract(Item $item, int $face, Vector3 $clickVector, ?Player $player = null, array &$returnedItems = []) : bool{ public function onInteract(Item $item, int $face, Vector3 $clickVector, ?Player $player = null, array &$returnedItems = []) : bool{
if($this->berries){ if($this->berries){
$this->position->getWorld()->dropItem($this->position, $this->asItem()); $this->position->getWorld()->dropItem($this->position->asVector3(), $this->asItem());
$this->position->getWorld()->addSound($this->position, new GlowBerriesPickSound()); $this->position->getWorld()->addSound($this->position->asVector3(), new GlowBerriesPickSound());
$this->position->getWorld()->setBlock($this->position, $this->setBerries(false)); $this->position->getWorld()->setBlock($this->position, $this->setBerries(false));
return true; return true;
@ -117,7 +117,7 @@ class CaveVines extends Flowable{
if($this->age < self::MAX_AGE && mt_rand(1, 10) === 1){ if($this->age < self::MAX_AGE && mt_rand(1, 10) === 1){
$growthPos = $this->position->getSide(Facing::DOWN); $growthPos = $this->position->getSide(Facing::DOWN);
$world = $growthPos->getWorld(); $world = $growthPos->getWorld();
if($world->isInWorld($growthPos->getFloorX(), $growthPos->getFloorY(), $growthPos->getFloorZ())){ if($world->isInWorld($growthPos->x, $growthPos->y, $growthPos->z)){
$block = $world->getBlock($growthPos); $block = $world->getBlock($growthPos);
if($block->getTypeId() === BlockTypeIds::AIR){ if($block->getTypeId() === BlockTypeIds::AIR){
$newState = VanillaBlocks::CAVE_VINES() $newState = VanillaBlocks::CAVE_VINES()

View File

@ -27,15 +27,12 @@ use pocketmine\block\utils\AgeableTrait;
use pocketmine\block\utils\StaticSupportTrait; use pocketmine\block\utils\StaticSupportTrait;
use pocketmine\entity\projectile\Projectile; use pocketmine\entity\projectile\Projectile;
use pocketmine\event\block\StructureGrowEvent; use pocketmine\event\block\StructureGrowEvent;
use pocketmine\math\Axis;
use pocketmine\math\AxisAlignedBB; use pocketmine\math\AxisAlignedBB;
use pocketmine\math\Facing; use pocketmine\math\Facing;
use pocketmine\math\RayTraceResult; use pocketmine\math\RayTraceResult;
use pocketmine\math\Vector3;
use pocketmine\world\BlockTransaction; use pocketmine\world\BlockTransaction;
use pocketmine\world\sound\ChorusFlowerDieSound; use pocketmine\world\sound\ChorusFlowerDieSound;
use pocketmine\world\sound\ChorusFlowerGrowSound; use pocketmine\world\sound\ChorusFlowerGrowSound;
use pocketmine\world\World;
use function array_rand; use function array_rand;
use function min; use function min;
use function mt_rand; use function mt_rand;
@ -54,24 +51,22 @@ final class ChorusFlower extends Flowable{
} }
private function canBeSupportedAt(Block $block) : bool{ private function canBeSupportedAt(Block $block) : bool{
$position = $block->position; $down = $block->getSide(Facing::DOWN);
$world = $position->getWorld();
$down = $world->getBlock($position->down());
if($down->getTypeId() === BlockTypeIds::END_STONE || $down->getTypeId() === BlockTypeIds::CHORUS_PLANT){ if($down->getTypeId() === BlockTypeIds::END_STONE || $down->getTypeId() === BlockTypeIds::CHORUS_PLANT){
return true; return true;
} }
$plantAdjacent = false; $plantAdjacent = false;
foreach($position->sidesAroundAxis(Axis::Y) as $sidePosition){ foreach(Facing::HORIZONTAL as $side){
$block = $world->getBlock($sidePosition); $sideBlock = $block->getSide($side);
if($block->getTypeId() === BlockTypeIds::CHORUS_PLANT){ if($sideBlock->getTypeId() === BlockTypeIds::CHORUS_PLANT){
if($plantAdjacent){ //at most one plant may be horizontally adjacent if($plantAdjacent){ //at most one plant may be horizontally adjacent
return false; return false;
} }
$plantAdjacent = true; $plantAdjacent = true;
}elseif($block->getTypeId() !== BlockTypeIds::AIR){ }elseif($sideBlock->getTypeId() !== BlockTypeIds::AIR){
return false; return false;
} }
} }
@ -92,7 +87,7 @@ final class ChorusFlower extends Flowable{
$stemHeight = 0; $stemHeight = 0;
$endStoneBelow = false; $endStoneBelow = false;
for($yOffset = 0; $yOffset < self::MAX_STEM_HEIGHT; $yOffset++, $stemHeight++){ for($yOffset = 0; $yOffset < self::MAX_STEM_HEIGHT; $yOffset++, $stemHeight++){
$down = $world->getBlock($this->position->down($yOffset + 1)); $down = $this->getSide(Facing::DOWN, $yOffset + 1);
if($down->getTypeId() !== BlockTypeIds::CHORUS_PLANT){ if($down->getTypeId() !== BlockTypeIds::CHORUS_PLANT){
if($down->getTypeId() === BlockTypeIds::END_STONE){ if($down->getTypeId() === BlockTypeIds::END_STONE){
@ -105,12 +100,13 @@ final class ChorusFlower extends Flowable{
return [$stemHeight, $endStoneBelow]; return [$stemHeight, $endStoneBelow];
} }
private function allHorizontalBlocksEmpty(World $world, Vector3 $position, ?int $except) : bool{ private function allHorizontalBlocksEmpty(BlockPosition $position, ?int $except) : bool{
foreach($position->sidesAroundAxis(Axis::Y) as $facing => $sidePosition){ $world = $position->getWorld();
foreach(Facing::HORIZONTAL as $facing){
if($facing === $except){ if($facing === $except){
continue; continue;
} }
if($world->getBlock($sidePosition)->getTypeId() !== BlockTypeIds::AIR){ if($world->getBlock($position->getSide($facing))->getTypeId() !== BlockTypeIds::AIR){
return false; return false;
} }
} }
@ -121,7 +117,7 @@ final class ChorusFlower extends Flowable{
private function canGrowUpwards(int $stemHeight, bool $endStoneBelow) : bool{ private function canGrowUpwards(int $stemHeight, bool $endStoneBelow) : bool{
$world = $this->position->getWorld(); $world = $this->position->getWorld();
$up = $this->position->up(); $up = $this->position->getSide(Facing::UP);
if( if(
//the space above must be empty and writable //the space above must be empty and writable
!$world->isInWorld($up->x, $up->y, $up->z) || !$world->isInWorld($up->x, $up->y, $up->z) ||
@ -129,7 +125,7 @@ final class ChorusFlower extends Flowable{
( (
//the space above that must be empty, but doesn't need to be writable //the space above that must be empty, but doesn't need to be writable
$world->isInWorld($up->x, $up->y + 1, $up->z) && $world->isInWorld($up->x, $up->y + 1, $up->z) &&
$world->getBlock($up->up())->getTypeId() !== BlockTypeIds::AIR $world->getBlock($up->getSide(Facing::UP))->getTypeId() !== BlockTypeIds::AIR
) )
){ ){
return false; return false;
@ -145,7 +141,7 @@ final class ChorusFlower extends Flowable{
} }
} }
return $this->allHorizontalBlocksEmpty($world, $up, null); return $this->allHorizontalBlocksEmpty($up, null);
} }
private function grow(int $facing, int $ageChange, ?BlockTransaction $tx) : BlockTransaction{ private function grow(int $facing, int $ageChange, ?BlockTransaction $tx) : BlockTransaction{
@ -183,8 +179,8 @@ final class ChorusFlower extends Flowable{
$sidePosition = $this->position->getSide($facing); $sidePosition = $this->position->getSide($facing);
if( if(
$world->getBlock($sidePosition)->getTypeId() === BlockTypeIds::AIR && $world->getBlock($sidePosition)->getTypeId() === BlockTypeIds::AIR &&
$world->getBlock($sidePosition->down())->getTypeId() === BlockTypeIds::AIR && $world->getBlock($sidePosition->getSide(Facing::DOWN))->getTypeId() === BlockTypeIds::AIR &&
$this->allHorizontalBlocksEmpty($world, $sidePosition, Facing::opposite($facing)) $this->allHorizontalBlocksEmpty($sidePosition, Facing::opposite($facing))
){ ){
$tx = $this->grow($facing, 1, $tx); $tx = $this->grow($facing, 1, $tx);
} }
@ -196,10 +192,10 @@ final class ChorusFlower extends Flowable{
$ev = new StructureGrowEvent($this, $tx, null); $ev = new StructureGrowEvent($this, $tx, null);
$ev->call(); $ev->call();
if(!$ev->isCancelled() && $tx->apply()){ if(!$ev->isCancelled() && $tx->apply()){
$world->addSound($this->position->add(0.5, 0.5, 0.5), new ChorusFlowerGrowSound()); $world->addSound($this->position->asVector3()->add(0.5, 0.5, 0.5), new ChorusFlowerGrowSound());
} }
}else{ }else{
$world->addSound($this->position->add(0.5, 0.5, 0.5), new ChorusFlowerDieSound()); $world->addSound($this->position->asVector3()->add(0.5, 0.5, 0.5), new ChorusFlowerDieSound());
$this->position->getWorld()->setBlock($this->position, $this->setAge(self::MAX_AGE)); $this->position->getWorld()->setBlock($this->position, $this->setAge(self::MAX_AGE));
} }
} }

View File

@ -26,7 +26,6 @@ namespace pocketmine\block;
use pocketmine\block\utils\StaticSupportTrait; use pocketmine\block\utils\StaticSupportTrait;
use pocketmine\item\Item; use pocketmine\item\Item;
use pocketmine\item\VanillaItems; use pocketmine\item\VanillaItems;
use pocketmine\math\Axis;
use pocketmine\math\AxisAlignedBB; use pocketmine\math\AxisAlignedBB;
use pocketmine\math\Facing; use pocketmine\math\Facing;
use function mt_rand; use function mt_rand;
@ -51,21 +50,18 @@ final class ChorusPlant extends Flowable{
} }
private function canBeSupportedAt(Block $block) : bool{ private function canBeSupportedAt(Block $block) : bool{
$position = $block->position; $down = $block->getSide(Facing::DOWN);
$world = $position->getWorld(); $verticalAir = $down->getTypeId() === BlockTypeIds::AIR || $block->getSide(Facing::UP)->getTypeId() === BlockTypeIds::AIR;
$down = $world->getBlock($position->down()); foreach(Facing::HORIZONTAL as $facing){
$verticalAir = $down->getTypeId() === BlockTypeIds::AIR || $world->getBlock($position->up())->getTypeId() === BlockTypeIds::AIR; $sideBlock = $block->getSide($facing);
foreach($position->sidesAroundAxis(Axis::Y) as $sidePosition){ if($sideBlock->getTypeId() === BlockTypeIds::CHORUS_PLANT){
$block = $world->getBlock($sidePosition);
if($block->getTypeId() === BlockTypeIds::CHORUS_PLANT){
if(!$verticalAir){ if(!$verticalAir){
return false; return false;
} }
if($this->canBeSupportedBy($block->getSide(Facing::DOWN))){ if($this->canBeSupportedBy($sideBlock->getSide(Facing::DOWN))){
return true; return true;
} }
} }

View File

@ -26,6 +26,7 @@ namespace pocketmine\block;
use pocketmine\block\utils\BlockEventHelper; use pocketmine\block\utils\BlockEventHelper;
use pocketmine\block\utils\CoralTypeTrait; use pocketmine\block\utils\CoralTypeTrait;
use pocketmine\item\Item; use pocketmine\item\Item;
use pocketmine\math\Facing;
use function mt_rand; use function mt_rand;
final class CoralBlock extends Opaque{ final class CoralBlock extends Opaque{
@ -39,11 +40,9 @@ final class CoralBlock extends Opaque{
public function onScheduledUpdate() : void{ public function onScheduledUpdate() : void{
if(!$this->dead){ if(!$this->dead){
$world = $this->position->getWorld();
$hasWater = false; $hasWater = false;
foreach($this->position->sides() as $vector3){ foreach(Facing::ALL as $facing){
if($world->getBlock($vector3) instanceof Water){ if($this->getSide($facing) instanceof Water){
$hasWater = true; $hasWater = true;
break; break;
} }

View File

@ -63,7 +63,7 @@ class Dirt extends Opaque{
$item->applyDamage(1); $item->applyDamage(1);
$newBlock = $this->dirtType === DirtType::NORMAL ? VanillaBlocks::FARMLAND() : VanillaBlocks::DIRT(); $newBlock = $this->dirtType === DirtType::NORMAL ? VanillaBlocks::FARMLAND() : VanillaBlocks::DIRT();
$center = $this->position->add(0.5, 0.5, 0.5); $center = $this->position->asVector3()->add(0.5, 0.5, 0.5);
$world->addSound($center, new ItemUseOnBlockSound($newBlock)); $world->addSound($center, new ItemUseOnBlockSound($newBlock));
$world->setBlock($this->position, $newBlock); $world->setBlock($this->position, $newBlock);
if($this->dirtType === DirtType::ROOTED){ if($this->dirtType === DirtType::ROOTED){
@ -83,7 +83,7 @@ class Dirt extends Opaque{
}elseif(($item instanceof Potion || $item instanceof SplashPotion) && $item->getType() === PotionType::WATER){ }elseif(($item instanceof Potion || $item instanceof SplashPotion) && $item->getType() === PotionType::WATER){
$item->pop(); $item->pop();
$world->setBlock($this->position, VanillaBlocks::MUD()); $world->setBlock($this->position, VanillaBlocks::MUD());
$world->addSound($this->position, new WaterSplashSound(0.5)); $world->addSound($this->position->asVector3(), new WaterSplashSound(0.5));
return true; return true;
} }

View File

@ -152,7 +152,7 @@ class Door extends Transparent{
} }
$world->setBlock($this->position, $this); $world->setBlock($this->position, $this);
$world->addSound($this->position, new DoorSound()); $world->addSound($this->position->asVector3(), new DoorSound());
return true; return true;
} }

View File

@ -66,16 +66,17 @@ class DragonEgg extends Transparent implements Fallable{
$this->position->z + mt_rand(-16, 16) $this->position->z + mt_rand(-16, 16)
); );
if($block instanceof Air){ if($block instanceof Air){
$ev = new BlockTeleportEvent($this, $block->position); //TODO: this needs migrating to BlockPosition, but having World in there presents some issues
$ev = new BlockTeleportEvent($this, $block->position->asVector3());
$ev->call(); $ev->call();
if($ev->isCancelled()){ if($ev->isCancelled()){
break; break;
} }
$blockPos = $ev->getTo(); $blockPos = $ev->getTo();
$world->addParticle($this->position, new DragonEggTeleportParticle($this->position->x - $blockPos->x, $this->position->y - $blockPos->y, $this->position->z - $blockPos->z)); $world->addParticle($this->position->asVector3(), new DragonEggTeleportParticle($this->position->x - $blockPos->getFloorX(), $this->position->y - $blockPos->getFloorY(), $this->position->z - $blockPos->getFloorZ()));
$world->setBlock($this->position, VanillaBlocks::AIR()); $world->setBlock($this->position, VanillaBlocks::AIR());
$world->setBlock($blockPos, $this); $world->setBlockAt($blockPos->getFloorX(), $blockPos->getFloorY(), $blockPos->getFloorZ(), $this);
break; break;
} }
} }

View File

@ -161,9 +161,9 @@ class Farmland extends Transparent{
protected function canHydrate() : bool{ protected function canHydrate() : bool{
$world = $this->position->getWorld(); $world = $this->position->getWorld();
$startX = $this->position->getFloorX() - (int) (self::WATER_SEARCH_HORIZONTAL_LENGTH / 2); $startX = $this->position->x - (int) (self::WATER_SEARCH_HORIZONTAL_LENGTH / 2);
$startY = $this->position->getFloorY(); $startY = $this->position->y;
$startZ = $this->position->getFloorZ() - (int) (self::WATER_SEARCH_HORIZONTAL_LENGTH / 2); $startZ = $this->position->z - (int) (self::WATER_SEARCH_HORIZONTAL_LENGTH / 2);
if($this->waterPositionIndex !== self::WATER_POSITION_INDEX_UNKNOWN){ if($this->waterPositionIndex !== self::WATER_POSITION_INDEX_UNKNOWN){
$raw = $this->waterPositionIndex; $raw = $this->waterPositionIndex;

View File

@ -111,7 +111,7 @@ class FenceGate extends Transparent{
$world = $this->position->getWorld(); $world = $this->position->getWorld();
$world->setBlock($this->position, $this); $world->setBlock($this->position, $this);
$world->addSound($this->position, new DoorSound()); $world->addSound($this->position->asVector3(), new DoorSound());
return true; return true;
} }

View File

@ -79,7 +79,7 @@ abstract class FillableCauldron extends Transparent{
return; return;
} }
$this->position->getWorld()->setBlock($this->position, $this->withFillLevel($this->fillLevel + $amount)); $this->position->getWorld()->setBlock($this->position, $this->withFillLevel($this->fillLevel + $amount));
$this->position->getWorld()->addSound($this->position->add(0.5, 0.5, 0.5), $this->getFillSound()); $this->position->getWorld()->addSound($this->position->asVector3()->add(0.5, 0.5, 0.5), $this->getFillSound());
$usedItem->pop(); $usedItem->pop();
$returnedItems[] = $returnedItem; $returnedItems[] = $returnedItem;
@ -94,7 +94,7 @@ abstract class FillableCauldron extends Transparent{
} }
$this->position->getWorld()->setBlock($this->position, $this->withFillLevel($this->fillLevel - $amount)); $this->position->getWorld()->setBlock($this->position, $this->withFillLevel($this->fillLevel - $amount));
$this->position->getWorld()->addSound($this->position->add(0.5, 0.5, 0.5), $this->getEmptySound()); $this->position->getWorld()->addSound($this->position->asVector3()->add(0.5, 0.5, 0.5), $this->getEmptySound());
$usedItem->pop(); $usedItem->pop();
$returnedItems[] = $returnedItem; $returnedItems[] = $returnedItem;

View File

@ -161,7 +161,7 @@ class Fire extends BaseFire{
$ageDivisor = $this->age + 30; $ageDivisor = $this->age + 30;
for($y = -1; $y <= 4; ++$y){ for($y = -1; $y <= 4; ++$y){
$targetY = $y + (int) $this->position->y; $targetY = $y + $this->position->y;
if($targetY < World::Y_MIN || $targetY >= World::Y_MAX){ if($targetY < World::Y_MIN || $targetY >= World::Y_MAX){
continue; continue;
} }
@ -169,12 +169,12 @@ class Fire extends BaseFire{
$randomBound = 100 + ($y > 1 ? ($y - 1) * 100 : 0); $randomBound = 100 + ($y > 1 ? ($y - 1) * 100 : 0);
for($z = -1; $z <= 1; ++$z){ for($z = -1; $z <= 1; ++$z){
$targetZ = $z + (int) $this->position->z; $targetZ = $z + $this->position->z;
for($x = -1; $x <= 1; ++$x){ for($x = -1; $x <= 1; ++$x){
if($x === 0 && $y === 0 && $z === 0){ if($x === 0 && $y === 0 && $z === 0){
continue; continue;
} }
$targetX = $x + (int) $this->position->x; $targetX = $x + $this->position->x;
if(!$world->isInWorld($targetX, $targetY, $targetZ)){ if(!$world->isInWorld($targetX, $targetY, $targetZ)){
continue; continue;
} }
@ -190,9 +190,10 @@ class Fire extends BaseFire{
//TODO: fire can't spread if it's raining in any horizontally adjacent block, or the current one //TODO: fire can't spread if it's raining in any horizontally adjacent block, or the current one
$encouragement = 0; $encouragement = 0;
foreach($block->position->sides() as $vector3){ foreach(Facing::ALL as $facing){
if($world->isInWorld($vector3->x, $vector3->y, $vector3->z)){ $sidePos = $block->position->getSide($facing);
$encouragement = max($encouragement, $world->getBlockAt($vector3->x, $vector3->y, $vector3->z)->getFlameEncouragement()); if($world->isInWorld($sidePos->x, $sidePos->y, $sidePos->z)){
$encouragement = max($encouragement, $world->getBlockAt($sidePos->x, $sidePos->y, $sidePos->z)->getFlameEncouragement());
} }
} }

View File

@ -58,7 +58,7 @@ final class FloorCoralFan extends BaseCoral{
public function place(BlockTransaction $tx, Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ public function place(BlockTransaction $tx, Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, ?Player $player = null) : bool{
if($player !== null){ if($player !== null){
$playerBlockPos = $player->getPosition()->floor(); $playerBlockPos = $player->getPosition()->floor();
$directionVector = $blockReplace->position->subtractVector($playerBlockPos)->normalize(); $directionVector = $blockReplace->position->asVector3()->subtractVector($playerBlockPos)->normalize();
$angle = rad2deg(atan2($directionVector->getZ(), $directionVector->getX())); $angle = rad2deg(atan2($directionVector->getZ(), $directionVector->getX()));
if($angle <= 45 || 315 <= $angle || (135 <= $angle && $angle <= 225)){ if($angle <= 45 || 315 <= $angle || (135 <= $angle && $angle <= 225)){

View File

@ -111,7 +111,7 @@ class FlowerPot extends Flowable{
$removedItems = $player->getInventory()->addItem(...$removedItems); $removedItems = $player->getInventory()->addItem(...$removedItems);
} }
foreach($removedItems as $drops){ foreach($removedItems as $drops){
$world->dropItem($this->position->add(0.5, 0.5, 0.5), $drops); $world->dropItem($this->position->asVector3()->add(0.5, 0.5, 0.5), $drops);
} }
$this->setPlant(null); $this->setPlant(null);

View File

@ -73,7 +73,7 @@ class Furnace extends Opaque{
$furnace = $world->getTile($this->position); $furnace = $world->getTile($this->position);
if($furnace instanceof TileFurnace && $furnace->onUpdate()){ if($furnace instanceof TileFurnace && $furnace->onUpdate()){
if(mt_rand(1, 60) === 1){ //in vanilla this is between 1 and 5 seconds; try to average about 3 if(mt_rand(1, 60) === 1){ //in vanilla this is between 1 and 5 seconds; try to average about 3
$world->addSound($this->position, $furnace->getFurnaceType()->getCookSound()); $world->addSound($this->position->asVector3(), $furnace->getFurnaceType()->getCookSound());
} }
$world->scheduleDelayedBlockUpdate($this->position, 1); //TODO: check this $world->scheduleDelayedBlockUpdate($this->position, 1); //TODO: check this
} }

View File

@ -32,7 +32,6 @@ use pocketmine\math\AxisAlignedBB;
use pocketmine\math\Facing; use pocketmine\math\Facing;
use pocketmine\math\Vector3; use pocketmine\math\Vector3;
use pocketmine\player\Player; use pocketmine\player\Player;
use pocketmine\world\World;
use function count; use function count;
use function shuffle; use function shuffle;
@ -84,7 +83,8 @@ class GlowLichen extends Transparent{
return $result->setFace($spreadFace, true); return $result->setFace($spreadFace, true);
} }
private function spread(World $world, Vector3 $replacePos, int $spreadFace) : bool{ private function spread(BlockPosition $replacePos, int $spreadFace) : bool{
$world = $replacePos->getWorld();
$supportBlock = $world->getBlock($replacePos->getSide($spreadFace)); $supportBlock = $world->getBlock($replacePos->getSide($spreadFace));
$supportFace = Facing::opposite($spreadFace); $supportFace = Facing::opposite($spreadFace);
@ -117,12 +117,10 @@ class GlowLichen extends Transparent{
} }
private function spreadAroundSupport(int $sourceFace) : bool{ private function spreadAroundSupport(int $sourceFace) : bool{
$world = $this->position->getWorld();
$supportPos = $this->position->getSide($sourceFace); $supportPos = $this->position->getSide($sourceFace);
foreach(self::getShuffledSpreadFaces($sourceFace) as $spreadFace){ foreach(self::getShuffledSpreadFaces($sourceFace) as $spreadFace){
$replacePos = $supportPos->getSide($spreadFace); $replacePos = $supportPos->getSide($spreadFace);
if($this->spread($world, $replacePos, Facing::opposite($spreadFace))){ if($this->spread($replacePos, Facing::opposite($spreadFace))){
return true; return true;
} }
} }
@ -131,11 +129,9 @@ class GlowLichen extends Transparent{
} }
private function spreadAdjacentToSupport(int $sourceFace) : bool{ private function spreadAdjacentToSupport(int $sourceFace) : bool{
$world = $this->position->getWorld();
foreach(self::getShuffledSpreadFaces($sourceFace) as $spreadFace){ foreach(self::getShuffledSpreadFaces($sourceFace) as $spreadFace){
$replacePos = $this->position->getSide($spreadFace); $replacePos = $this->position->getSide($spreadFace);
if($this->spread($world, $replacePos, $sourceFace)){ if($this->spread($replacePos, $sourceFace)){
return true; return true;
} }
} }
@ -144,7 +140,7 @@ class GlowLichen extends Transparent{
private function spreadWithinSelf(int $sourceFace) : bool{ private function spreadWithinSelf(int $sourceFace) : bool{
foreach(self::getShuffledSpreadFaces($sourceFace) as $spreadFace){ foreach(self::getShuffledSpreadFaces($sourceFace) as $spreadFace){
if(!$this->hasFace($spreadFace) && $this->spread($this->position->getWorld(), $this->position, $spreadFace)){ if(!$this->hasFace($spreadFace) && $this->spread($this->position, $spreadFace)){
return true; return true;
} }
} }

View File

@ -88,7 +88,7 @@ class Grass extends Opaque{
$world = $this->position->getWorld(); $world = $this->position->getWorld();
if($item instanceof Fertilizer){ if($item instanceof Fertilizer){
$item->pop(); $item->pop();
TallGrassObject::growGrass($world, $this->position, new Random(mt_rand()), 8, 2); TallGrassObject::growGrass($world, $this->position->asVector3(), new Random(mt_rand()), 8, 2);
return true; return true;
} }
@ -96,14 +96,14 @@ class Grass extends Opaque{
if($item instanceof Hoe){ if($item instanceof Hoe){
$item->applyDamage(1); $item->applyDamage(1);
$newBlock = VanillaBlocks::FARMLAND(); $newBlock = VanillaBlocks::FARMLAND();
$world->addSound($this->position->add(0.5, 0.5, 0.5), new ItemUseOnBlockSound($newBlock)); $world->addSound($this->position->asVector3()->add(0.5, 0.5, 0.5), new ItemUseOnBlockSound($newBlock));
$world->setBlock($this->position, $newBlock); $world->setBlock($this->position, $newBlock);
return true; return true;
}elseif($item instanceof Shovel){ }elseif($item instanceof Shovel){
$item->applyDamage(1); $item->applyDamage(1);
$newBlock = VanillaBlocks::GRASS_PATH(); $newBlock = VanillaBlocks::GRASS_PATH();
$world->addSound($this->position->add(0.5, 0.5, 0.5), new ItemUseOnBlockSound($newBlock)); $world->addSound($this->position->asVector3()->add(0.5, 0.5, 0.5), new ItemUseOnBlockSound($newBlock));
$world->setBlock($this->position, $newBlock); $world->setBlock($this->position, $newBlock);
return true; return true;

View File

@ -135,11 +135,11 @@ class ItemFrame extends Flowable{
if($this->framedItem !== null){ if($this->framedItem !== null){
$this->itemRotation = ($this->itemRotation + 1) % self::ROTATIONS; $this->itemRotation = ($this->itemRotation + 1) % self::ROTATIONS;
$this->position->getWorld()->addSound($this->position, new ItemFrameRotateItemSound()); $this->position->getWorld()->addSound($this->position->asVector3(), new ItemFrameRotateItemSound());
}elseif(!$item->isNull()){ }elseif(!$item->isNull()){
$this->framedItem = $item->pop(); $this->framedItem = $item->pop();
$this->position->getWorld()->addSound($this->position, new ItemFrameAddItemSound()); $this->position->getWorld()->addSound($this->position->asVector3(), new ItemFrameAddItemSound());
}else{ }else{
return true; return true;
} }
@ -155,8 +155,8 @@ class ItemFrame extends Flowable{
} }
$world = $this->position->getWorld(); $world = $this->position->getWorld();
if(Utils::getRandomFloat() <= $this->itemDropChance){ if(Utils::getRandomFloat() <= $this->itemDropChance){
$world->dropItem($this->position->add(0.5, 0.5, 0.5), clone $this->framedItem); $world->dropItem($this->position->asVector3()->add(0.5, 0.5, 0.5), clone $this->framedItem);
$world->addSound($this->position, new ItemFrameRemoveItemSound()); $world->addSound($this->position->asVector3(), new ItemFrameRemoveItemSound());
} }
$this->setFramedItem(null); $this->setFramedItem(null);
$world->setBlock($this->position, $this); $world->setBlock($this->position, $this);

View File

@ -61,7 +61,7 @@ class Jukebox extends Opaque{
public function ejectRecord() : void{ public function ejectRecord() : void{
if($this->record !== null){ if($this->record !== null){
$this->position->getWorld()->dropItem($this->position->add(0.5, 1, 0.5), $this->record); $this->position->getWorld()->dropItem($this->position->asVector3()->add(0.5, 1, 0.5), $this->record);
$this->record = null; $this->record = null;
$this->stopSound(); $this->stopSound();
} }
@ -76,12 +76,12 @@ class Jukebox extends Opaque{
public function startSound() : void{ public function startSound() : void{
if($this->record !== null){ if($this->record !== null){
$this->position->getWorld()->addSound($this->position, new RecordSound($this->record->getRecordType())); $this->position->getWorld()->addSound($this->position->asVector3(), new RecordSound($this->record->getRecordType()));
} }
} }
public function stopSound() : void{ public function stopSound() : void{
$this->position->getWorld()->addSound($this->position, new RecordStopSound()); $this->position->getWorld()->addSound($this->position->asVector3(), new RecordStopSound());
} }
public function onBreak(Item $item, ?Player $player = null, array &$returnedItems = []) : bool{ public function onBreak(Item $item, ?Player $player = null, array &$returnedItems = []) : bool{

View File

@ -51,7 +51,7 @@ class Ladder extends Transparent{
} }
public function onEntityInside(Entity $entity) : bool{ public function onEntityInside(Entity $entity) : bool{
if($entity instanceof Living && $entity->getPosition()->floor()->distanceSquared($this->position) < 1){ //entity coordinates must be inside block if($entity instanceof Living && $entity->getPosition()->floor()->distanceSquared($this->position->asVector3()) < 1){ //entity coordinates must be inside block
$entity->resetFallDistance(); $entity->resetFallDistance();
$entity->onGround = true; $entity->onGround = true;
} }

View File

@ -81,7 +81,7 @@ class Leaves extends Transparent{
* @phpstan-param array<int, true> $visited * @phpstan-param array<int, true> $visited
* @phpstan-param-out array<int, true> $visited * @phpstan-param-out array<int, true> $visited
*/ */
protected function findLog(Vector3 $pos, array &$visited = [], int $distance = 0) : bool{ protected function findLog(BlockPosition $pos, array &$visited = [], int $distance = 0) : bool{
$index = World::blockHash($pos->x, $pos->y, $pos->z); $index = World::blockHash($pos->x, $pos->y, $pos->z);
if(isset($visited[$index])){ if(isset($visited[$index])){
return false; return false;

View File

@ -123,7 +123,7 @@ class Lectern extends Transparent{
if($this->book === null && $item instanceof WritableBookBase){ if($this->book === null && $item instanceof WritableBookBase){
$world = $this->position->getWorld(); $world = $this->position->getWorld();
$world->setBlock($this->position, $this->setBook($item)); $world->setBlock($this->position, $this->setBook($item));
$world->addSound($this->position, new LecternPlaceBookSound()); $world->addSound($this->position->asVector3(), new LecternPlaceBookSound());
$item->pop(); $item->pop();
} }
return true; return true;
@ -132,7 +132,7 @@ class Lectern extends Transparent{
public function onAttack(Item $item, int $face, ?Player $player = null) : bool{ public function onAttack(Item $item, int $face, ?Player $player = null) : bool{
if($this->book !== null){ if($this->book !== null){
$world = $this->position->getWorld(); $world = $this->position->getWorld();
$world->dropItem($this->position->up(), $this->book); $world->dropItem($this->position->getSide(Facing::UP)->asVector3(), $this->book);
$world->setBlock($this->position, $this->setBook(null)); $world->setBlock($this->position, $this->setBook(null));
} }
return false; return false;

View File

@ -95,7 +95,7 @@ class Lever extends Flowable{
$world = $this->position->getWorld(); $world = $this->position->getWorld();
$world->setBlock($this->position, $this); $world->setBlock($this->position, $this);
$world->addSound( $world->addSound(
$this->position->add(0.5, 0.5, 0.5), $this->position->asVector3()->add(0.5, 0.5, 0.5),
$this->activated ? new RedstonePowerOnSound() : new RedstonePowerOffSound() $this->activated ? new RedstonePowerOnSound() : new RedstonePowerOffSound()
); );
return true; return true;

View File

@ -165,9 +165,9 @@ abstract class Liquid extends Transparent{
$vX = $vY = $vZ = 0; $vX = $vY = $vZ = 0;
$x = $this->position->getFloorX(); $x = $this->position->x;
$y = $this->position->getFloorY(); $y = $this->position->y;
$z = $this->position->getFloorZ(); $z = $this->position->z;
$decay = $this->getEffectiveFlowDecay($this); $decay = $this->getEffectiveFlowDecay($this);
@ -259,9 +259,9 @@ abstract class Liquid extends Transparent{
$world = $this->position->getWorld(); $world = $this->position->getWorld();
$x = $this->position->getFloorX(); $x = $this->position->x;
$y = $this->position->getFloorY(); $y = $this->position->y;
$z = $this->position->getFloorZ(); $z = $this->position->z;
if(!$this->isSource()){ if(!$this->isSource()){
$smallestFlowDecay = -100; $smallestFlowDecay = -100;
@ -368,7 +368,7 @@ abstract class Liquid extends Transparent{
protected function liquidCollide(Block $cause, Block $result) : bool{ protected function liquidCollide(Block $cause, Block $result) : bool{
if(BlockEventHelper::form($this, $result, $cause)){ if(BlockEventHelper::form($this, $result, $cause)){
$this->position->getWorld()->addSound($this->position->add(0.5, 0.5, 0.5), new FizzSound(2.6 + (Utils::getRandomFloat() - Utils::getRandomFloat()) * 0.8)); $this->position->getWorld()->addSound($this->position->asVector3()->add(0.5, 0.5, 0.5), new FizzSound(2.6 + (Utils::getRandomFloat() - Utils::getRandomFloat()) * 0.8));
} }
return true; return true;
} }

View File

@ -117,7 +117,7 @@ class NetherVines extends Flowable{
for($i = 1; $i <= $growthAmount; $i++){ for($i = 1; $i <= $growthAmount; $i++){
$growthPos = $pos->getSide($this->growthFace, $i); $growthPos = $pos->getSide($this->growthFace, $i);
if(!$world->isInWorld($growthPos->getFloorX(), $growthPos->getFloorY(), $growthPos->getFloorZ()) || !$world->getBlock($growthPos)->canBeReplaced()){ if(!$world->isInWorld($growthPos->x, $growthPos->y, $growthPos->z) || !$world->getBlock($growthPos)->canBeReplaced()){
break; break;
} }
$tx->addBlock($growthPos, (clone $top)->setAge(min(++$age, self::MAX_AGE))); $tx->addBlock($growthPos, (clone $top)->setAge(min(++$age, self::MAX_AGE)));

View File

@ -89,7 +89,7 @@ class PinkPetals extends Flowable{
if($this->count < self::MAX_COUNT){ if($this->count < self::MAX_COUNT){
$grew = BlockEventHelper::grow($this, (clone $this)->setCount($this->count + 1), $player); $grew = BlockEventHelper::grow($this, (clone $this)->setCount($this->count + 1), $player);
}else{ }else{
$this->position->getWorld()->dropItem($this->position->add(0, 0.5, 0), $this->asItem()); $this->position->getWorld()->dropItem($this->position->asVector3()->add(0, 0.5, 0), $this->asItem());
$grew = true; $grew = true;
} }
if($grew){ if($grew){

View File

@ -73,7 +73,7 @@ final class PitcherCrop extends Flowable{
$tx = new BlockTransaction($this->position->getWorld()); $tx = new BlockTransaction($this->position->getWorld());
$tx->addBlock($this->position, VanillaBlocks::DOUBLE_PITCHER_CROP()->setTop(false)); $tx->addBlock($this->position, VanillaBlocks::DOUBLE_PITCHER_CROP()->setTop(false));
$tx->addBlock($this->position->up(), VanillaBlocks::DOUBLE_PITCHER_CROP()->setTop(true)); $tx->addBlock($this->position->getSide(Facing::UP), VanillaBlocks::DOUBLE_PITCHER_CROP()->setTop(true));
$ev = new StructureGrowEvent($this, $tx, $player); $ev = new StructureGrowEvent($this, $tx, $player);
$ev->call(); $ev->call();

View File

@ -27,6 +27,7 @@ use pocketmine\block\tile\Cauldron as TileCauldron;
use pocketmine\item\Item; use pocketmine\item\Item;
use pocketmine\item\ItemTypeIds; use pocketmine\item\ItemTypeIds;
use pocketmine\item\VanillaItems; use pocketmine\item\VanillaItems;
use pocketmine\math\Facing;
use pocketmine\math\Vector3; use pocketmine\math\Vector3;
use pocketmine\player\Player; use pocketmine\player\Player;
use pocketmine\world\sound\CauldronEmptyPotionSound; use pocketmine\world\sound\CauldronEmptyPotionSound;
@ -107,10 +108,10 @@ final class PotionCauldron extends FillableCauldron{
public function onNearbyBlockChange() : void{ public function onNearbyBlockChange() : void{
$world = $this->position->getWorld(); $world = $this->position->getWorld();
if($world->getBlock($this->position->up())->getTypeId() === BlockTypeIds::WATER){ if($this->getSide(Facing::UP)->getTypeId() === BlockTypeIds::WATER){
$cauldron = VanillaBlocks::WATER_CAULDRON()->setFillLevel(FillableCauldron::MAX_FILL_LEVEL); $cauldron = VanillaBlocks::WATER_CAULDRON()->setFillLevel(FillableCauldron::MAX_FILL_LEVEL);
$world->setBlock($this->position, $cauldron); $world->setBlock($this->position, $cauldron);
$world->addSound($this->position->add(0.5, 0.5, 0.5), $cauldron->getFillSound()); $world->addSound($this->position->asVector3()->add(0.5, 0.5, 0.5), $cauldron->getFillSound());
} }
} }
} }

View File

@ -139,7 +139,7 @@ abstract class PressurePlate extends Transparent{
if($newState !== null){ if($newState !== null){
$world->setBlock($this->position, $newState); $world->setBlock($this->position, $newState);
if($pressedChange !== null){ if($pressedChange !== null){
$world->addSound($this->position, $pressedChange ? $world->addSound($this->position->asVector3(), $pressedChange ?
new PressurePlateActivateSound($this) : new PressurePlateActivateSound($this) :
new PressurePlateDeactivateSound($this) new PressurePlateDeactivateSound($this)
); );

View File

@ -38,7 +38,7 @@ class Pumpkin extends Opaque{
$item->applyDamage(1); $item->applyDamage(1);
$world = $this->position->getWorld(); $world = $this->position->getWorld();
$world->setBlock($this->position, VanillaBlocks::CARVED_PUMPKIN()->setFacing($face)); $world->setBlock($this->position, VanillaBlocks::CARVED_PUMPKIN()->setFacing($face));
$world->dropItem($this->position->add(0.5, 0.5, 0.5), VanillaItems::PUMPKIN_SEEDS()->setCount(1)); $world->dropItem($this->position->asVector3()->add(0.5, 0.5, 0.5), VanillaItems::PUMPKIN_SEEDS()->setCount(1));
return true; return true;
} }
return false; return false;

View File

@ -81,7 +81,7 @@ class Sapling extends Flowable{
public function onRandomTick() : void{ public function onRandomTick() : void{
$world = $this->position->getWorld(); $world = $this->position->getWorld();
if($world->getFullLightAt($this->position->getFloorX(), $this->position->getFloorY(), $this->position->getFloorZ()) >= 8 && mt_rand(1, 7) === 1){ if($world->getFullLightAt($this->position->x, $this->position->y, $this->position->z) >= 8 && mt_rand(1, 7) === 1){
if($this->ready){ if($this->ready){
$this->grow(null); $this->grow(null);
}else{ }else{
@ -94,7 +94,7 @@ class Sapling extends Flowable{
private function grow(?Player $player) : bool{ private function grow(?Player $player) : bool{
$random = new Random(mt_rand()); $random = new Random(mt_rand());
$tree = TreeFactory::get($random, $this->saplingType->getTreeType()); $tree = TreeFactory::get($random, $this->saplingType->getTreeType());
$transaction = $tree?->getBlockTransaction($this->position->getWorld(), $this->position->getFloorX(), $this->position->getFloorY(), $this->position->getFloorZ(), $random); $transaction = $tree?->getBlockTransaction($this->position->getWorld(), $this->position->x, $this->position->y, $this->position->z, $random);
if($transaction === null){ if($transaction === null){
return false; return false;
} }

View File

@ -33,7 +33,6 @@ use pocketmine\math\Facing;
use pocketmine\math\Vector3; use pocketmine\math\Vector3;
use pocketmine\player\Player; use pocketmine\player\Player;
use pocketmine\world\BlockTransaction; use pocketmine\world\BlockTransaction;
use pocketmine\world\Position;
use function mt_rand; use function mt_rand;
class SmallDripleaf extends Transparent{ class SmallDripleaf extends Transparent{
@ -98,9 +97,9 @@ class SmallDripleaf extends Transparent{
return false; return false;
} }
private function canGrowTo(Position $pos) : bool{ private function canGrowTo(BlockPosition $pos) : bool{
$world = $pos->getWorld(); $world = $pos->getWorld();
if(!$world->isInWorld($pos->getFloorX(), $pos->getFloorY(), $pos->getFloorZ())){ if(!$world->isInWorld($pos->x, $pos->y, $pos->z)){
return false; return false;
} }
$block = $world->getBlock($pos); $block = $world->getBlock($pos);

View File

@ -32,7 +32,6 @@ use pocketmine\math\Facing;
use pocketmine\math\Vector3; use pocketmine\math\Vector3;
use pocketmine\player\Player; use pocketmine\player\Player;
use pocketmine\world\BlockTransaction; use pocketmine\world\BlockTransaction;
use pocketmine\world\Position;
class Sugarcane extends Flowable{ class Sugarcane extends Flowable{
use AgeableTrait; use AgeableTrait;
@ -42,16 +41,16 @@ class Sugarcane extends Flowable{
public const MAX_AGE = 15; public const MAX_AGE = 15;
private function seekToBottom() : Position{ private function seekToBottom() : BlockPosition{
$world = $this->position->getWorld(); $world = $this->position->getWorld();
$bottom = $this->position; $bottom = $this->position;
while(($next = $world->getBlock($bottom->down()))->hasSameTypeId($this)){ while(($next = $world->getBlock($bottom->getSide(Facing::DOWN)))->hasSameTypeId($this)){
$bottom = $next->position; $bottom = $next->position;
} }
return $bottom; return $bottom;
} }
private function grow(Position $pos, ?Player $player = null) : bool{ private function grow(BlockPosition $pos, ?Player $player = null) : bool{
$grew = false; $grew = false;
$world = $pos->getWorld(); $world = $pos->getWorld();
for($y = 1; $y < 3; ++$y){ for($y = 1; $y < 3; ++$y){

View File

@ -81,8 +81,9 @@ class SweetBerryBush extends Flowable{
} }
}elseif(($dropAmount = $this->getBerryDropAmount()) > 0){ }elseif(($dropAmount = $this->getBerryDropAmount()) > 0){
$world->setBlock($this->position, $this->setAge(self::STAGE_BUSH_NO_BERRIES)); $world->setBlock($this->position, $this->setAge(self::STAGE_BUSH_NO_BERRIES));
$world->dropItem($this->position, $this->asItem()->setCount($dropAmount)); $posV3 = $this->position->asVector3();
$world->addSound($this->position, new SweetBerriesPickSound()); $world->dropItem($posV3, $this->asItem()->setCount($dropAmount));
$world->addSound($posV3, new SweetBerriesPickSound());
} }
return true; return true;

View File

@ -100,7 +100,7 @@ class TNT extends Opaque{
$mot = (new Random())->nextSignedFloat() * M_PI * 2; $mot = (new Random())->nextSignedFloat() * M_PI * 2;
$tnt = new PrimedTNT(Location::fromObject($this->position->add(0.5, 0, 0.5), $world)); $tnt = new PrimedTNT(Location::fromObject($this->position->asVector3()->add(0.5, 0, 0.5), $world));
$tnt->setFuse($fuse); $tnt->setFuse($fuse);
$tnt->setWorksUnderwater($this->worksUnderwater); $tnt->setWorksUnderwater($this->worksUnderwater);
$tnt->setMotion(new Vector3(-sin($mot) * 0.02, 0.2, -cos($mot) * 0.02)); $tnt->setMotion(new Vector3(-sin($mot) * 0.02, 0.2, -cos($mot) * 0.02));

View File

@ -88,7 +88,7 @@ class Trapdoor extends Transparent{
$this->open = !$this->open; $this->open = !$this->open;
$world = $this->position->getWorld(); $world = $this->position->getWorld();
$world->setBlock($this->position, $this); $world->setBlock($this->position, $this);
$world->addSound($this->position, new DoorSound()); $world->addSound($this->position->asVector3(), new DoorSound());
return true; return true;
} }
} }

View File

@ -36,6 +36,7 @@ use pocketmine\item\Potion;
use pocketmine\item\PotionType; use pocketmine\item\PotionType;
use pocketmine\item\SplashPotion; use pocketmine\item\SplashPotion;
use pocketmine\item\VanillaItems; use pocketmine\item\VanillaItems;
use pocketmine\math\Facing;
use pocketmine\math\Vector3; use pocketmine\math\Vector3;
use pocketmine\player\Player; use pocketmine\player\Player;
use pocketmine\world\sound\CauldronAddDyeSound; use pocketmine\world\sound\CauldronAddDyeSound;
@ -119,7 +120,7 @@ final class WaterCauldron extends FillableCauldron{
}) !== null && ($newColor = $dyeColor->getRgbValue())->toRGBA() !== $this->customWaterColor?->toRGBA() }) !== null && ($newColor = $dyeColor->getRgbValue())->toRGBA() !== $this->customWaterColor?->toRGBA()
){ ){
$world->setBlock($this->position, $this->setCustomWaterColor($this->customWaterColor === null ? $newColor : Color::mix($this->customWaterColor, $newColor))); $world->setBlock($this->position, $this->setCustomWaterColor($this->customWaterColor === null ? $newColor : Color::mix($this->customWaterColor, $newColor)));
$world->addSound($this->position->add(0.5, 0.5, 0.5), new CauldronAddDyeSound()); $world->addSound($this->position->asVector3()->add(0.5, 0.5, 0.5), new CauldronAddDyeSound());
$item->pop(); $item->pop();
}elseif($item instanceof Potion || $item instanceof SplashPotion){ //TODO: lingering potion }elseif($item instanceof Potion || $item instanceof SplashPotion){ //TODO: lingering potion
@ -139,12 +140,12 @@ final class WaterCauldron extends FillableCauldron{
} && $item->getCustomColor()?->toRGBA() !== $this->customWaterColor->toRGBA()){ } && $item->getCustomColor()?->toRGBA() !== $this->customWaterColor->toRGBA()){
$item->setCustomColor($this->customWaterColor); $item->setCustomColor($this->customWaterColor);
$world->setBlock($this->position, $this->withFillLevel($this->getFillLevel() - self::DYE_ARMOR_USE_AMOUNT)); $world->setBlock($this->position, $this->withFillLevel($this->getFillLevel() - self::DYE_ARMOR_USE_AMOUNT));
$world->addSound($this->position->add(0.5, 0.5, 0.5), new CauldronDyeItemSound()); $world->addSound($this->position->asVector3()->add(0.5, 0.5, 0.5), new CauldronDyeItemSound());
} }
}elseif($item->getCustomColor() !== null){ }elseif($item->getCustomColor() !== null){
$item->clearCustomColor(); $item->clearCustomColor();
$world->setBlock($this->position, $this->withFillLevel($this->getFillLevel() - self::CLEAN_ARMOR_USE_AMOUNT)); $world->setBlock($this->position, $this->withFillLevel($this->getFillLevel() - self::CLEAN_ARMOR_USE_AMOUNT));
$world->addSound($this->position->add(0.5, 0.5, 0.5), new CauldronCleanItemSound()); $world->addSound($this->position->asVector3()->add(0.5, 0.5, 0.5), new CauldronCleanItemSound());
} }
}elseif($item instanceof Banner){ }elseif($item instanceof Banner){
$patterns = $item->getPatterns(); $patterns = $item->getPatterns();
@ -153,7 +154,7 @@ final class WaterCauldron extends FillableCauldron{
$item->setPatterns($patterns); $item->setPatterns($patterns);
$world->setBlock($this->position, $this->withFillLevel($this->getFillLevel() - self::CLEAN_BANNER_USE_AMOUNT)); $world->setBlock($this->position, $this->withFillLevel($this->getFillLevel() - self::CLEAN_BANNER_USE_AMOUNT));
$world->addSound($this->position->add(0.5, 0.5, 0.5), new CauldronCleanItemSound()); $world->addSound($this->position->asVector3()->add(0.5, 0.5, 0.5), new CauldronCleanItemSound());
} }
}elseif(ItemTypeIds::toBlockTypeId($item->getTypeId()) === BlockTypeIds::DYED_SHULKER_BOX){ }elseif(ItemTypeIds::toBlockTypeId($item->getTypeId()) === BlockTypeIds::DYED_SHULKER_BOX){
if($this->customWaterColor === null){ if($this->customWaterColor === null){
@ -164,7 +165,7 @@ final class WaterCauldron extends FillableCauldron{
$returnedItems[] = $newItem; $returnedItems[] = $newItem;
$world->setBlock($this->position, $this->withFillLevel($this->getFillLevel() - self::CLEAN_SHULKER_BOX_USE_AMOUNT)); $world->setBlock($this->position, $this->withFillLevel($this->getFillLevel() - self::CLEAN_SHULKER_BOX_USE_AMOUNT));
$world->addSound($this->position->add(0.5, 0.5, 0.5), new CauldronCleanItemSound()); $world->addSound($this->position->asVector3()->add(0.5, 0.5, 0.5), new CauldronCleanItemSound());
} }
}else{ }else{
match($item->getTypeId()){ match($item->getTypeId()){
@ -195,13 +196,13 @@ final class WaterCauldron extends FillableCauldron{
public function onNearbyBlockChange() : void{ public function onNearbyBlockChange() : void{
$hasCustomWaterColor = $this->customWaterColor !== null; $hasCustomWaterColor = $this->customWaterColor !== null;
if($this->getFillLevel() < self::MAX_FILL_LEVEL || $hasCustomWaterColor){ if($this->getFillLevel() < self::MAX_FILL_LEVEL || $hasCustomWaterColor){
$world = $this->position->getWorld(); if($this->getSide(Facing::UP)->getTypeId() === BlockTypeIds::WATER){
if($world->getBlock($this->position->up())->getTypeId() === BlockTypeIds::WATER){
if($hasCustomWaterColor){ if($hasCustomWaterColor){
//TODO: particles //TODO: particles
} }
$world = $this->position->getWorld();
$world->setBlock($this->position, $this->setCustomWaterColor(null)->setFillLevel(FillableCauldron::MAX_FILL_LEVEL)); $world->setBlock($this->position, $this->setCustomWaterColor(null)->setFillLevel(FillableCauldron::MAX_FILL_LEVEL));
$world->addSound($this->position->add(0.5, 0.5, 0.5), $this->getFillSound()); $world->addSound($this->position->asVector3()->add(0.5, 0.5, 0.5), $this->getFillSound());
} }
} }
} }

View File

@ -67,7 +67,7 @@ class Wood extends Opaque{
$item->applyDamage(1); $item->applyDamage(1);
$this->stripped = true; $this->stripped = true;
$this->position->getWorld()->setBlock($this->position, $this); $this->position->getWorld()->setBlock($this->position, $this);
$this->position->getWorld()->addSound($this->position, new ItemUseOnBlockSound($this)); $this->position->getWorld()->addSound($this->position->asVector3(), new ItemUseOnBlockSound($this));
return true; return true;
} }
return false; return false;

View File

@ -50,7 +50,7 @@ trait AnimatedBlockInventoryTrait{
if($this->holder->isValid() && $this->getViewerCount() === 1){ if($this->holder->isValid() && $this->getViewerCount() === 1){
//TODO: this crap really shouldn't be managed by the inventory //TODO: this crap really shouldn't be managed by the inventory
$this->animateBlock(true); $this->animateBlock(true);
$this->holder->getWorld()->addSound($this->holder->add(0.5, 0.5, 0.5), $this->getOpenSound()); $this->holder->getWorld()->addSound($this->holder->asVector3()->add(0.5, 0.5, 0.5), $this->getOpenSound());
} }
} }
@ -60,7 +60,7 @@ trait AnimatedBlockInventoryTrait{
if($this->holder->isValid() && $this->getViewerCount() === 1){ if($this->holder->isValid() && $this->getViewerCount() === 1){
//TODO: this crap really shouldn't be managed by the inventory //TODO: this crap really shouldn't be managed by the inventory
$this->animateBlock(false); $this->animateBlock(false);
$this->holder->getWorld()->addSound($this->holder->add(0.5, 0.5, 0.5), $this->getCloseSound()); $this->holder->getWorld()->addSound($this->holder->asVector3()->add(0.5, 0.5, 0.5), $this->getCloseSound());
} }
parent::onClose($who); parent::onClose($who);
} }

View File

@ -23,9 +23,9 @@ declare(strict_types=1);
namespace pocketmine\block\inventory; namespace pocketmine\block\inventory;
use pocketmine\block\BlockPosition;
use pocketmine\inventory\SimpleInventory; use pocketmine\inventory\SimpleInventory;
use pocketmine\inventory\TemporaryInventory; use pocketmine\inventory\TemporaryInventory;
use pocketmine\world\Position;
class AnvilInventory extends SimpleInventory implements BlockInventory, TemporaryInventory{ class AnvilInventory extends SimpleInventory implements BlockInventory, TemporaryInventory{
use BlockInventoryTrait; use BlockInventoryTrait;
@ -33,7 +33,7 @@ class AnvilInventory extends SimpleInventory implements BlockInventory, Temporar
public const SLOT_INPUT = 0; public const SLOT_INPUT = 0;
public const SLOT_MATERIAL = 1; public const SLOT_MATERIAL = 1;
public function __construct(Position $holder){ public function __construct(BlockPosition $holder){
$this->holder = $holder; $this->holder = $holder;
parent::__construct(2); parent::__construct(2);
} }

View File

@ -24,8 +24,8 @@ declare(strict_types=1);
namespace pocketmine\block\inventory; namespace pocketmine\block\inventory;
use pocketmine\block\Barrel; use pocketmine\block\Barrel;
use pocketmine\block\BlockPosition;
use pocketmine\inventory\SimpleInventory; use pocketmine\inventory\SimpleInventory;
use pocketmine\world\Position;
use pocketmine\world\sound\BarrelCloseSound; use pocketmine\world\sound\BarrelCloseSound;
use pocketmine\world\sound\BarrelOpenSound; use pocketmine\world\sound\BarrelOpenSound;
use pocketmine\world\sound\Sound; use pocketmine\world\sound\Sound;
@ -33,7 +33,7 @@ use pocketmine\world\sound\Sound;
class BarrelInventory extends SimpleInventory implements BlockInventory{ class BarrelInventory extends SimpleInventory implements BlockInventory{
use AnimatedBlockInventoryTrait; use AnimatedBlockInventoryTrait;
public function __construct(Position $holder){ public function __construct(BlockPosition $holder){
$this->holder = $holder; $this->holder = $holder;
parent::__construct(27); parent::__construct(27);
} }

View File

@ -23,8 +23,8 @@ declare(strict_types=1);
namespace pocketmine\block\inventory; namespace pocketmine\block\inventory;
use pocketmine\world\Position; use pocketmine\block\BlockPosition;
interface BlockInventory{ interface BlockInventory{
public function getHolder() : Position; public function getHolder() : BlockPosition;
} }

View File

@ -23,12 +23,12 @@ declare(strict_types=1);
namespace pocketmine\block\inventory; namespace pocketmine\block\inventory;
use pocketmine\world\Position; use pocketmine\block\BlockPosition;
trait BlockInventoryTrait{ trait BlockInventoryTrait{
protected Position $holder; protected BlockPosition $holder;
public function getHolder() : Position{ public function getHolder() : BlockPosition{
return $this->holder; return $this->holder;
} }
} }

View File

@ -23,8 +23,8 @@ declare(strict_types=1);
namespace pocketmine\block\inventory; namespace pocketmine\block\inventory;
use pocketmine\block\BlockPosition;
use pocketmine\inventory\SimpleInventory; use pocketmine\inventory\SimpleInventory;
use pocketmine\world\Position;
class BrewingStandInventory extends SimpleInventory implements BlockInventory{ class BrewingStandInventory extends SimpleInventory implements BlockInventory{
use BlockInventoryTrait; use BlockInventoryTrait;
@ -35,7 +35,7 @@ class BrewingStandInventory extends SimpleInventory implements BlockInventory{
public const SLOT_BOTTLE_RIGHT = 3; public const SLOT_BOTTLE_RIGHT = 3;
public const SLOT_FUEL = 4; public const SLOT_FUEL = 4;
public function __construct(Position $holder, int $size = 5){ public function __construct(BlockPosition $holder, int $size = 5){
$this->holder = $holder; $this->holder = $holder;
parent::__construct($size); parent::__construct($size);
} }

View File

@ -23,13 +23,13 @@ declare(strict_types=1);
namespace pocketmine\block\inventory; namespace pocketmine\block\inventory;
use pocketmine\block\BlockPosition;
use pocketmine\inventory\SimpleInventory; use pocketmine\inventory\SimpleInventory;
use pocketmine\world\Position;
class CampfireInventory extends SimpleInventory implements BlockInventory{ class CampfireInventory extends SimpleInventory implements BlockInventory{
use BlockInventoryTrait; use BlockInventoryTrait;
public function __construct(Position $holder){ public function __construct(BlockPosition $holder){
$this->holder = $holder; $this->holder = $holder;
parent::__construct(4); parent::__construct(4);
} }

View File

@ -23,14 +23,14 @@ declare(strict_types=1);
namespace pocketmine\block\inventory; namespace pocketmine\block\inventory;
use pocketmine\block\BlockPosition;
use pocketmine\inventory\SimpleInventory; use pocketmine\inventory\SimpleInventory;
use pocketmine\inventory\TemporaryInventory; use pocketmine\inventory\TemporaryInventory;
use pocketmine\world\Position;
final class CartographyTableInventory extends SimpleInventory implements BlockInventory, TemporaryInventory{ final class CartographyTableInventory extends SimpleInventory implements BlockInventory, TemporaryInventory{
use BlockInventoryTrait; use BlockInventoryTrait;
public function __construct(Position $holder){ public function __construct(BlockPosition $holder){
$this->holder = $holder; $this->holder = $holder;
parent::__construct(2); parent::__construct(2);
} }

View File

@ -23,10 +23,10 @@ declare(strict_types=1);
namespace pocketmine\block\inventory; namespace pocketmine\block\inventory;
use pocketmine\block\BlockPosition;
use pocketmine\inventory\SimpleInventory; use pocketmine\inventory\SimpleInventory;
use pocketmine\network\mcpe\protocol\BlockEventPacket; use pocketmine\network\mcpe\protocol\BlockEventPacket;
use pocketmine\network\mcpe\protocol\types\BlockPosition; use pocketmine\network\mcpe\protocol\types\BlockPosition as ProtocolBlockPosition;
use pocketmine\world\Position;
use pocketmine\world\sound\ChestCloseSound; use pocketmine\world\sound\ChestCloseSound;
use pocketmine\world\sound\ChestOpenSound; use pocketmine\world\sound\ChestOpenSound;
use pocketmine\world\sound\Sound; use pocketmine\world\sound\Sound;
@ -34,7 +34,7 @@ use pocketmine\world\sound\Sound;
class ChestInventory extends SimpleInventory implements BlockInventory{ class ChestInventory extends SimpleInventory implements BlockInventory{
use AnimatedBlockInventoryTrait; use AnimatedBlockInventoryTrait;
public function __construct(Position $holder){ public function __construct(BlockPosition $holder){
$this->holder = $holder; $this->holder = $holder;
parent::__construct(27); parent::__construct(27);
} }
@ -51,6 +51,6 @@ class ChestInventory extends SimpleInventory implements BlockInventory{
$holder = $this->getHolder(); $holder = $this->getHolder();
//event ID is always 1 for a chest //event ID is always 1 for a chest
$holder->getWorld()->broadcastPacketToViewers($holder, BlockEventPacket::create(BlockPosition::fromVector3($holder), 1, $isOpen ? 1 : 0)); $holder->getWorld()->broadcastPacketToViewers($holder->asVector3(), BlockEventPacket::create(new ProtocolBlockPosition($holder->x, $holder->y, $holder->z), 1, $isOpen ? 1 : 0));
} }
} }

View File

@ -23,14 +23,14 @@ declare(strict_types=1);
namespace pocketmine\block\inventory; namespace pocketmine\block\inventory;
use pocketmine\block\BlockPosition;
use pocketmine\crafting\CraftingGrid; use pocketmine\crafting\CraftingGrid;
use pocketmine\inventory\TemporaryInventory; use pocketmine\inventory\TemporaryInventory;
use pocketmine\world\Position;
final class CraftingTableInventory extends CraftingGrid implements BlockInventory, TemporaryInventory{ final class CraftingTableInventory extends CraftingGrid implements BlockInventory, TemporaryInventory{
use BlockInventoryTrait; use BlockInventoryTrait;
public function __construct(Position $holder){ public function __construct(BlockPosition $holder){
$this->holder = $holder; $this->holder = $holder;
parent::__construct(CraftingGrid::SIZE_BIG); parent::__construct(CraftingGrid::SIZE_BIG);
} }

View File

@ -23,13 +23,13 @@ declare(strict_types=1);
namespace pocketmine\block\inventory; namespace pocketmine\block\inventory;
use pocketmine\block\BlockPosition;
use pocketmine\event\player\PlayerEnchantingOptionsRequestEvent; use pocketmine\event\player\PlayerEnchantingOptionsRequestEvent;
use pocketmine\inventory\SimpleInventory; use pocketmine\inventory\SimpleInventory;
use pocketmine\inventory\TemporaryInventory; use pocketmine\inventory\TemporaryInventory;
use pocketmine\item\enchantment\EnchantingHelper as Helper; use pocketmine\item\enchantment\EnchantingHelper as Helper;
use pocketmine\item\enchantment\EnchantingOption; use pocketmine\item\enchantment\EnchantingOption;
use pocketmine\item\Item; use pocketmine\item\Item;
use pocketmine\world\Position;
use function array_values; use function array_values;
use function count; use function count;
@ -45,7 +45,7 @@ class EnchantInventory extends SimpleInventory implements BlockInventory, Tempor
*/ */
private array $options = []; private array $options = [];
public function __construct(Position $holder){ public function __construct(BlockPosition $holder){
$this->holder = $holder; $this->holder = $holder;
parent::__construct(2); parent::__construct(2);
} }

View File

@ -23,14 +23,14 @@ declare(strict_types=1);
namespace pocketmine\block\inventory; namespace pocketmine\block\inventory;
use pocketmine\block\BlockPosition;
use pocketmine\block\tile\EnderChest; use pocketmine\block\tile\EnderChest;
use pocketmine\inventory\DelegateInventory; use pocketmine\inventory\DelegateInventory;
use pocketmine\inventory\Inventory; use pocketmine\inventory\Inventory;
use pocketmine\inventory\PlayerEnderInventory; use pocketmine\inventory\PlayerEnderInventory;
use pocketmine\network\mcpe\protocol\BlockEventPacket; use pocketmine\network\mcpe\protocol\BlockEventPacket;
use pocketmine\network\mcpe\protocol\types\BlockPosition; use pocketmine\network\mcpe\protocol\types\BlockPosition as ProtocolBlockPosition;
use pocketmine\player\Player; use pocketmine\player\Player;
use pocketmine\world\Position;
use pocketmine\world\sound\EnderChestCloseSound; use pocketmine\world\sound\EnderChestCloseSound;
use pocketmine\world\sound\EnderChestOpenSound; use pocketmine\world\sound\EnderChestOpenSound;
use pocketmine\world\sound\Sound; use pocketmine\world\sound\Sound;
@ -44,7 +44,7 @@ class EnderChestInventory extends DelegateInventory implements BlockInventory{
} }
public function __construct( public function __construct(
Position $holder, BlockPosition $holder,
private PlayerEnderInventory $inventory private PlayerEnderInventory $inventory
){ ){
parent::__construct($inventory); parent::__construct($inventory);
@ -75,7 +75,8 @@ class EnderChestInventory extends DelegateInventory implements BlockInventory{
$holder = $this->getHolder(); $holder = $this->getHolder();
//event ID is always 1 for a chest //event ID is always 1 for a chest
$holder->getWorld()->broadcastPacketToViewers($holder, BlockEventPacket::create(BlockPosition::fromVector3($holder), 1, $isOpen ? 1 : 0)); //TODO: maybe broadcast should use BlockPosition
$holder->getWorld()->broadcastPacketToViewers($holder->asVector3(), BlockEventPacket::create(new ProtocolBlockPosition($holder->x, $holder->y, $holder->z), 1, $isOpen ? 1 : 0));
} }
public function onClose(Player $who) : void{ public function onClose(Player $who) : void{

View File

@ -23,10 +23,10 @@ declare(strict_types=1);
namespace pocketmine\block\inventory; namespace pocketmine\block\inventory;
use pocketmine\block\BlockPosition;
use pocketmine\crafting\FurnaceType; use pocketmine\crafting\FurnaceType;
use pocketmine\inventory\SimpleInventory; use pocketmine\inventory\SimpleInventory;
use pocketmine\item\Item; use pocketmine\item\Item;
use pocketmine\world\Position;
class FurnaceInventory extends SimpleInventory implements BlockInventory{ class FurnaceInventory extends SimpleInventory implements BlockInventory{
use BlockInventoryTrait; use BlockInventoryTrait;
@ -36,7 +36,7 @@ class FurnaceInventory extends SimpleInventory implements BlockInventory{
public const SLOT_RESULT = 2; public const SLOT_RESULT = 2;
public function __construct( public function __construct(
Position $holder, BlockPosition $holder,
private FurnaceType $furnaceType private FurnaceType $furnaceType
){ ){
$this->holder = $holder; $this->holder = $holder;

View File

@ -23,13 +23,13 @@ declare(strict_types=1);
namespace pocketmine\block\inventory; namespace pocketmine\block\inventory;
use pocketmine\block\BlockPosition;
use pocketmine\inventory\SimpleInventory; use pocketmine\inventory\SimpleInventory;
use pocketmine\world\Position;
class HopperInventory extends SimpleInventory implements BlockInventory{ class HopperInventory extends SimpleInventory implements BlockInventory{
use BlockInventoryTrait; use BlockInventoryTrait;
public function __construct(Position $holder, int $size = 5){ public function __construct(BlockPosition $holder, int $size = 5){
$this->holder = $holder; $this->holder = $holder;
parent::__construct($size); parent::__construct($size);
} }

View File

@ -23,9 +23,9 @@ declare(strict_types=1);
namespace pocketmine\block\inventory; namespace pocketmine\block\inventory;
use pocketmine\block\BlockPosition;
use pocketmine\inventory\SimpleInventory; use pocketmine\inventory\SimpleInventory;
use pocketmine\inventory\TemporaryInventory; use pocketmine\inventory\TemporaryInventory;
use pocketmine\world\Position;
final class LoomInventory extends SimpleInventory implements BlockInventory, TemporaryInventory{ final class LoomInventory extends SimpleInventory implements BlockInventory, TemporaryInventory{
use BlockInventoryTrait; use BlockInventoryTrait;
@ -34,7 +34,7 @@ final class LoomInventory extends SimpleInventory implements BlockInventory, Tem
public const SLOT_DYE = 1; public const SLOT_DYE = 1;
public const SLOT_PATTERN = 2; public const SLOT_PATTERN = 2;
public function __construct(Position $holder, int $size = 3){ public function __construct(BlockPosition $holder, int $size = 3){
$this->holder = $holder; $this->holder = $holder;
parent::__construct($size); parent::__construct($size);
} }

View File

@ -23,12 +23,13 @@ declare(strict_types=1);
namespace pocketmine\block\inventory; namespace pocketmine\block\inventory;
use pocketmine\block\BlockPosition;
use pocketmine\block\BlockTypeIds; use pocketmine\block\BlockTypeIds;
use pocketmine\inventory\SimpleInventory; use pocketmine\inventory\SimpleInventory;
use pocketmine\item\Item; use pocketmine\item\Item;
use pocketmine\item\ItemTypeIds; use pocketmine\item\ItemTypeIds;
use pocketmine\network\mcpe\protocol\BlockEventPacket; use pocketmine\network\mcpe\protocol\BlockEventPacket;
use pocketmine\network\mcpe\protocol\types\BlockPosition; use pocketmine\network\mcpe\protocol\types\BlockPosition as ProtocolBlockPosition;
use pocketmine\world\Position; use pocketmine\world\Position;
use pocketmine\world\sound\ShulkerBoxCloseSound; use pocketmine\world\sound\ShulkerBoxCloseSound;
use pocketmine\world\sound\ShulkerBoxOpenSound; use pocketmine\world\sound\ShulkerBoxOpenSound;
@ -37,7 +38,7 @@ use pocketmine\world\sound\Sound;
class ShulkerBoxInventory extends SimpleInventory implements BlockInventory{ class ShulkerBoxInventory extends SimpleInventory implements BlockInventory{
use AnimatedBlockInventoryTrait; use AnimatedBlockInventoryTrait;
public function __construct(Position $holder){ public function __construct(BlockPosition $holder){
$this->holder = $holder; $this->holder = $holder;
parent::__construct(27); parent::__construct(27);
} }
@ -62,6 +63,7 @@ class ShulkerBoxInventory extends SimpleInventory implements BlockInventory{
$holder = $this->getHolder(); $holder = $this->getHolder();
//event ID is always 1 for a chest //event ID is always 1 for a chest
$holder->getWorld()->broadcastPacketToViewers($holder, BlockEventPacket::create(BlockPosition::fromVector3($holder), 1, $isOpen ? 1 : 0)); //TODO: maybe broadcast should use block position
$holder->getWorld()->broadcastPacketToViewers($holder->asVector3(), BlockEventPacket::create(new ProtocolBlockPosition($holder->x, $holder->y, $holder->z), 1, $isOpen ? 1 : 0));
} }
} }

View File

@ -23,14 +23,14 @@ declare(strict_types=1);
namespace pocketmine\block\inventory; namespace pocketmine\block\inventory;
use pocketmine\block\BlockPosition;
use pocketmine\inventory\SimpleInventory; use pocketmine\inventory\SimpleInventory;
use pocketmine\inventory\TemporaryInventory; use pocketmine\inventory\TemporaryInventory;
use pocketmine\world\Position;
final class SmithingTableInventory extends SimpleInventory implements BlockInventory, TemporaryInventory{ final class SmithingTableInventory extends SimpleInventory implements BlockInventory, TemporaryInventory{
use BlockInventoryTrait; use BlockInventoryTrait;
public function __construct(Position $holder){ public function __construct(BlockPosition $holder){
$this->holder = $holder; $this->holder = $holder;
parent::__construct(3); parent::__construct(3);
} }

View File

@ -23,16 +23,16 @@ declare(strict_types=1);
namespace pocketmine\block\inventory; namespace pocketmine\block\inventory;
use pocketmine\block\BlockPosition;
use pocketmine\inventory\SimpleInventory; use pocketmine\inventory\SimpleInventory;
use pocketmine\inventory\TemporaryInventory; use pocketmine\inventory\TemporaryInventory;
use pocketmine\world\Position;
class StonecutterInventory extends SimpleInventory implements BlockInventory, TemporaryInventory{ class StonecutterInventory extends SimpleInventory implements BlockInventory, TemporaryInventory{
use BlockInventoryTrait; use BlockInventoryTrait;
public const SLOT_INPUT = 0; public const SLOT_INPUT = 0;
public function __construct(Position $holder){ public function __construct(BlockPosition $holder){
$this->holder = $holder; $this->holder = $holder;
parent::__construct(1); parent::__construct(1);
} }

View File

@ -23,10 +23,9 @@ declare(strict_types=1);
namespace pocketmine\block\tile; namespace pocketmine\block\tile;
use pocketmine\block\BlockPosition;
use pocketmine\block\inventory\BarrelInventory; use pocketmine\block\inventory\BarrelInventory;
use pocketmine\math\Vector3;
use pocketmine\nbt\tag\CompoundTag; use pocketmine\nbt\tag\CompoundTag;
use pocketmine\world\World;
class Barrel extends Spawnable implements Container, Nameable{ class Barrel extends Spawnable implements Container, Nameable{
use NameableTrait; use NameableTrait;
@ -34,8 +33,8 @@ class Barrel extends Spawnable implements Container, Nameable{
protected BarrelInventory $inventory; protected BarrelInventory $inventory;
public function __construct(World $world, Vector3 $pos){ public function __construct(BlockPosition $position){
parent::__construct($world, $pos); parent::__construct($position);
$this->inventory = new BarrelInventory($this->position); $this->inventory = new BarrelInventory($this->position);
} }

View File

@ -88,6 +88,6 @@ final class Bell extends Spawnable{
default => throw new AssumptionFailedError("Unreachable") default => throw new AssumptionFailedError("Unreachable")
}); });
$nbt->setInt(self::TAG_TICKS, 0); $nbt->setInt(self::TAG_TICKS, 0);
return BlockActorDataPacket::create(BlockPosition::fromVector3($this->position), new CacheableNbt($nbt)); return BlockActorDataPacket::create(new BlockPosition($this->position->x, $this->position->y, $this->position->z), new CacheableNbt($nbt));
} }
} }

View File

@ -23,6 +23,7 @@ declare(strict_types=1);
namespace pocketmine\block\tile; namespace pocketmine\block\tile;
use pocketmine\block\BlockPosition;
use pocketmine\block\inventory\BrewingStandInventory; use pocketmine\block\inventory\BrewingStandInventory;
use pocketmine\crafting\BrewingRecipe; use pocketmine\crafting\BrewingRecipe;
use pocketmine\event\block\BrewingFuelUseEvent; use pocketmine\event\block\BrewingFuelUseEvent;
@ -31,12 +32,10 @@ use pocketmine\inventory\CallbackInventoryListener;
use pocketmine\inventory\Inventory; use pocketmine\inventory\Inventory;
use pocketmine\item\Item; use pocketmine\item\Item;
use pocketmine\item\VanillaItems; use pocketmine\item\VanillaItems;
use pocketmine\math\Vector3;
use pocketmine\nbt\tag\CompoundTag; use pocketmine\nbt\tag\CompoundTag;
use pocketmine\network\mcpe\protocol\ContainerSetDataPacket; use pocketmine\network\mcpe\protocol\ContainerSetDataPacket;
use pocketmine\player\Player; use pocketmine\player\Player;
use pocketmine\world\sound\PotionFinishBrewingSound; use pocketmine\world\sound\PotionFinishBrewingSound;
use pocketmine\world\World;
use function array_map; use function array_map;
use function count; use function count;
@ -60,11 +59,11 @@ class BrewingStand extends Spawnable implements Container, Nameable{
private int $maxFuelTime = 0; private int $maxFuelTime = 0;
private int $remainingFuelTime = 0; private int $remainingFuelTime = 0;
public function __construct(World $world, Vector3 $pos){ public function __construct(BlockPosition $position){
parent::__construct($world, $pos); parent::__construct($position);
$this->inventory = new BrewingStandInventory($this->position); $this->inventory = new BrewingStandInventory($this->position);
$this->inventory->getListeners()->add(CallbackInventoryListener::onAnyChange(static function(Inventory $unused) use ($world, $pos) : void{ $this->inventory->getListeners()->add(CallbackInventoryListener::onAnyChange(static function(Inventory $unused) use ($position) : void{
$world->scheduleDelayedBlockUpdate($pos, 1); $position->getWorld()->scheduleDelayedBlockUpdate($position, 1);
})); }));
} }
@ -215,7 +214,7 @@ class BrewingStand extends Spawnable implements Container, Nameable{
} }
if($anythingBrewed){ if($anythingBrewed){
$this->position->getWorld()->addSound($this->position->add(0.5, 0.5, 0.5), new PotionFinishBrewingSound()); $this->position->getWorld()->addSound($this->position->asVector3()->add(0.5, 0.5, 0.5), new PotionFinishBrewingSound());
} }
$ingredient->pop(); $ingredient->pop();

View File

@ -23,16 +23,15 @@ declare(strict_types=1);
namespace pocketmine\block\tile; namespace pocketmine\block\tile;
use pocketmine\block\BlockPosition;
use pocketmine\block\Campfire as BlockCampfire; use pocketmine\block\Campfire as BlockCampfire;
use pocketmine\block\inventory\CampfireInventory; use pocketmine\block\inventory\CampfireInventory;
use pocketmine\inventory\CallbackInventoryListener; use pocketmine\inventory\CallbackInventoryListener;
use pocketmine\inventory\Inventory; use pocketmine\inventory\Inventory;
use pocketmine\item\Item; use pocketmine\item\Item;
use pocketmine\math\Vector3;
use pocketmine\nbt\tag\CompoundTag; use pocketmine\nbt\tag\CompoundTag;
use pocketmine\nbt\tag\IntTag; use pocketmine\nbt\tag\IntTag;
use pocketmine\network\mcpe\convert\TypeConverter; use pocketmine\network\mcpe\convert\TypeConverter;
use pocketmine\world\World;
class Campfire extends Spawnable implements Container{ class Campfire extends Spawnable implements Container{
use ContainerTrait; use ContainerTrait;
@ -51,14 +50,15 @@ class Campfire extends Spawnable implements Container{
/** @var array<int, int> */ /** @var array<int, int> */
private array $cookingTimes = []; private array $cookingTimes = [];
public function __construct(World $world, Vector3 $pos){ public function __construct(BlockPosition $position){
parent::__construct($world, $pos); parent::__construct($position);
$this->inventory = new CampfireInventory($this->position); $this->inventory = new CampfireInventory($this->position);
$this->inventory->getListeners()->add(CallbackInventoryListener::onAnyChange( $this->inventory->getListeners()->add(CallbackInventoryListener::onAnyChange(
static function(Inventory $unused) use ($world, $pos) : void{ static function(Inventory $unused) use ($position) : void{
$block = $world->getBlock($pos); $world = $position->getWorld();
$block = $world->getBlock($position);
if($block instanceof BlockCampfire){ if($block instanceof BlockCampfire){
$world->setBlock($pos, $block); $world->setBlock($position, $block);
} }
}) })
); );

View File

@ -23,13 +23,13 @@ declare(strict_types=1);
namespace pocketmine\block\tile; namespace pocketmine\block\tile;
use pocketmine\block\BlockPosition;
use pocketmine\block\inventory\ChestInventory; use pocketmine\block\inventory\ChestInventory;
use pocketmine\block\inventory\DoubleChestInventory; use pocketmine\block\inventory\DoubleChestInventory;
use pocketmine\math\Vector3; use pocketmine\math\Vector3;
use pocketmine\nbt\tag\CompoundTag; use pocketmine\nbt\tag\CompoundTag;
use pocketmine\nbt\tag\IntTag; use pocketmine\nbt\tag\IntTag;
use pocketmine\world\format\Chunk; use pocketmine\world\format\Chunk;
use pocketmine\world\World;
use function abs; use function abs;
class Chest extends Spawnable implements Container, Nameable{ class Chest extends Spawnable implements Container, Nameable{
@ -50,8 +50,8 @@ class Chest extends Spawnable implements Container, Nameable{
private ?int $pairX = null; private ?int $pairX = null;
private ?int $pairZ = null; private ?int $pairZ = null;
public function __construct(World $world, Vector3 $pos){ public function __construct(BlockPosition $position){
parent::__construct($world, $pos); parent::__construct($position);
$this->inventory = new ChestInventory($this->position); $this->inventory = new ChestInventory($this->position);
} }

View File

@ -23,18 +23,17 @@ declare(strict_types=1);
namespace pocketmine\block\tile; namespace pocketmine\block\tile;
use pocketmine\block\BlockPosition;
use pocketmine\block\utils\ChiseledBookshelfSlot; use pocketmine\block\utils\ChiseledBookshelfSlot;
use pocketmine\data\bedrock\item\SavedItemData; use pocketmine\data\bedrock\item\SavedItemData;
use pocketmine\data\bedrock\item\SavedItemStackData; use pocketmine\data\bedrock\item\SavedItemStackData;
use pocketmine\data\SavedDataLoadingException; use pocketmine\data\SavedDataLoadingException;
use pocketmine\inventory\SimpleInventory; use pocketmine\inventory\SimpleInventory;
use pocketmine\item\Item; use pocketmine\item\Item;
use pocketmine\math\Vector3;
use pocketmine\nbt\NBT; use pocketmine\nbt\NBT;
use pocketmine\nbt\tag\CompoundTag; use pocketmine\nbt\tag\CompoundTag;
use pocketmine\nbt\tag\ListTag; use pocketmine\nbt\tag\ListTag;
use pocketmine\nbt\tag\StringTag; use pocketmine\nbt\tag\StringTag;
use pocketmine\world\World;
use function count; use function count;
class ChiseledBookshelf extends Tile implements Container{ class ChiseledBookshelf extends Tile implements Container{
@ -46,8 +45,8 @@ class ChiseledBookshelf extends Tile implements Container{
private ?ChiseledBookshelfSlot $lastInteractedSlot = null; private ?ChiseledBookshelfSlot $lastInteractedSlot = null;
public function __construct(World $world, Vector3 $pos){ public function __construct(BlockPosition $position){
parent::__construct($world, $pos); parent::__construct($position);
$this->inventory = new SimpleInventory(count(ChiseledBookshelfSlot::cases())); $this->inventory = new SimpleInventory(count(ChiseledBookshelfSlot::cases()));
} }

View File

@ -23,6 +23,7 @@ declare(strict_types=1);
namespace pocketmine\block\tile; namespace pocketmine\block\tile;
use pocketmine\block\BlockPosition;
use pocketmine\data\bedrock\item\SavedItemStackData; use pocketmine\data\bedrock\item\SavedItemStackData;
use pocketmine\data\SavedDataLoadingException; use pocketmine\data\SavedDataLoadingException;
use pocketmine\inventory\Inventory; use pocketmine\inventory\Inventory;
@ -31,7 +32,6 @@ use pocketmine\nbt\NBT;
use pocketmine\nbt\tag\CompoundTag; use pocketmine\nbt\tag\CompoundTag;
use pocketmine\nbt\tag\ListTag; use pocketmine\nbt\tag\ListTag;
use pocketmine\nbt\tag\StringTag; use pocketmine\nbt\tag\StringTag;
use pocketmine\world\Position;
/** /**
* This trait implements most methods in the {@link Container} interface. It should only be used by Tiles. * This trait implements most methods in the {@link Container} interface. It should only be used by Tiles.
@ -90,9 +90,9 @@ trait ContainerTrait{
} }
/** /**
* @see Position::asPosition() * @see Tile::getPosition()
*/ */
abstract protected function getPosition() : Position; abstract protected function getPosition() : BlockPosition;
/** /**
* @see Tile::onBlockDestroyedHook() * @see Tile::onBlockDestroyedHook()
@ -102,7 +102,7 @@ trait ContainerTrait{
$pos = $this->getPosition(); $pos = $this->getPosition();
$world = $pos->getWorld(); $world = $pos->getWorld();
$dropPos = $pos->add(0.5, 0.5, 0.5); $dropPos = $pos->asVector3()->add(0.5, 0.5, 0.5);
foreach($inv->getContents() as $k => $item){ foreach($inv->getContents() as $k => $item){
$world->dropItem($dropPos, $item); $world->dropItem($dropPos, $item);
} }

View File

@ -23,6 +23,7 @@ declare(strict_types=1);
namespace pocketmine\block\tile; namespace pocketmine\block\tile;
use pocketmine\block\BlockPosition;
use pocketmine\block\Furnace as BlockFurnace; use pocketmine\block\Furnace as BlockFurnace;
use pocketmine\block\inventory\FurnaceInventory; use pocketmine\block\inventory\FurnaceInventory;
use pocketmine\crafting\FurnaceRecipe; use pocketmine\crafting\FurnaceRecipe;
@ -32,11 +33,9 @@ use pocketmine\event\inventory\FurnaceSmeltEvent;
use pocketmine\inventory\CallbackInventoryListener; use pocketmine\inventory\CallbackInventoryListener;
use pocketmine\inventory\Inventory; use pocketmine\inventory\Inventory;
use pocketmine\item\Item; use pocketmine\item\Item;
use pocketmine\math\Vector3;
use pocketmine\nbt\tag\CompoundTag; use pocketmine\nbt\tag\CompoundTag;
use pocketmine\network\mcpe\protocol\ContainerSetDataPacket; use pocketmine\network\mcpe\protocol\ContainerSetDataPacket;
use pocketmine\player\Player; use pocketmine\player\Player;
use pocketmine\world\World;
use function array_map; use function array_map;
use function max; use function max;
@ -53,12 +52,12 @@ abstract class Furnace extends Spawnable implements Container, Nameable{
private int $cookTime = 0; private int $cookTime = 0;
private int $maxFuelTime = 0; private int $maxFuelTime = 0;
public function __construct(World $world, Vector3 $pos){ public function __construct(BlockPosition $position){
parent::__construct($world, $pos); parent::__construct($position);
$this->inventory = new FurnaceInventory($this->position, $this->getFurnaceType()); $this->inventory = new FurnaceInventory($this->position, $this->getFurnaceType());
$this->inventory->getListeners()->add(CallbackInventoryListener::onAnyChange( $this->inventory->getListeners()->add(CallbackInventoryListener::onAnyChange(
static function(Inventory $unused) use ($world, $pos) : void{ static function(Inventory $unused) use ($position) : void{
$world->scheduleDelayedBlockUpdate($pos, 1); $position->getWorld()->scheduleDelayedBlockUpdate($position, 1);
}) })
); );
} }

View File

@ -23,10 +23,9 @@ declare(strict_types=1);
namespace pocketmine\block\tile; namespace pocketmine\block\tile;
use pocketmine\block\BlockPosition;
use pocketmine\block\inventory\HopperInventory; use pocketmine\block\inventory\HopperInventory;
use pocketmine\math\Vector3;
use pocketmine\nbt\tag\CompoundTag; use pocketmine\nbt\tag\CompoundTag;
use pocketmine\world\World;
class Hopper extends Spawnable implements Container, Nameable{ class Hopper extends Spawnable implements Container, Nameable{
@ -38,8 +37,8 @@ class Hopper extends Spawnable implements Container, Nameable{
private HopperInventory $inventory; private HopperInventory $inventory;
private int $transferCooldown = 0; private int $transferCooldown = 0;
public function __construct(World $world, Vector3 $pos){ public function __construct(BlockPosition $position){
parent::__construct($world, $pos); parent::__construct($position);
$this->inventory = new HopperInventory($this->position); $this->inventory = new HopperInventory($this->position);
} }

View File

@ -23,13 +23,12 @@ declare(strict_types=1);
namespace pocketmine\block\tile; namespace pocketmine\block\tile;
use pocketmine\block\BlockPosition;
use pocketmine\item\Item; use pocketmine\item\Item;
use pocketmine\item\VanillaItems; use pocketmine\item\VanillaItems;
use pocketmine\math\Vector3;
use pocketmine\nbt\tag\CompoundTag; use pocketmine\nbt\tag\CompoundTag;
use pocketmine\nbt\tag\FloatTag; use pocketmine\nbt\tag\FloatTag;
use pocketmine\network\mcpe\convert\TypeConverter; use pocketmine\network\mcpe\convert\TypeConverter;
use pocketmine\world\World;
/** /**
* @deprecated * @deprecated
@ -44,9 +43,9 @@ class ItemFrame extends Spawnable{
private int $itemRotation = 0; private int $itemRotation = 0;
private float $itemDropChance = 1.0; private float $itemDropChance = 1.0;
public function __construct(World $world, Vector3 $pos){ public function __construct(BlockPosition $position){
$this->item = VanillaItems::AIR(); $this->item = VanillaItems::AIR();
parent::__construct($world, $pos); parent::__construct($position);
} }
public function readSaveData(CompoundTag $nbt) : void{ public function readSaveData(CompoundTag $nbt) : void{

View File

@ -65,6 +65,6 @@ class Jukebox extends Spawnable{
} }
protected function onBlockDestroyedHook() : void{ protected function onBlockDestroyedHook() : void{
$this->position->getWorld()->addSound($this->position, new RecordStopSound()); $this->position->getWorld()->addSound($this->position->asVector3(), new RecordStopSound());
} }
} }

View File

@ -23,12 +23,11 @@ declare(strict_types=1);
namespace pocketmine\block\tile; namespace pocketmine\block\tile;
use pocketmine\block\BlockPosition;
use pocketmine\block\inventory\ShulkerBoxInventory; use pocketmine\block\inventory\ShulkerBoxInventory;
use pocketmine\item\Item; use pocketmine\item\Item;
use pocketmine\math\Facing; use pocketmine\math\Facing;
use pocketmine\math\Vector3;
use pocketmine\nbt\tag\CompoundTag; use pocketmine\nbt\tag\CompoundTag;
use pocketmine\world\World;
class ShulkerBox extends Spawnable implements Container, Nameable{ class ShulkerBox extends Spawnable implements Container, Nameable{
use NameableTrait { use NameableTrait {
@ -42,8 +41,8 @@ class ShulkerBox extends Spawnable implements Container, Nameable{
protected ShulkerBoxInventory $inventory; protected ShulkerBoxInventory $inventory;
public function __construct(World $world, Vector3 $pos){ public function __construct(BlockPosition $position){
parent::__construct($world, $pos); parent::__construct($position);
$this->inventory = new ShulkerBoxInventory($this->position); $this->inventory = new ShulkerBoxInventory($this->position);
} }

View File

@ -23,15 +23,14 @@ declare(strict_types=1);
namespace pocketmine\block\tile; namespace pocketmine\block\tile;
use pocketmine\block\BlockPosition;
use pocketmine\block\utils\SignText; use pocketmine\block\utils\SignText;
use pocketmine\color\Color; use pocketmine\color\Color;
use pocketmine\math\Vector3;
use pocketmine\nbt\tag\ByteTag; use pocketmine\nbt\tag\ByteTag;
use pocketmine\nbt\tag\CompoundTag; use pocketmine\nbt\tag\CompoundTag;
use pocketmine\nbt\tag\IntTag; use pocketmine\nbt\tag\IntTag;
use pocketmine\nbt\tag\StringTag; use pocketmine\nbt\tag\StringTag;
use pocketmine\utils\Binary; use pocketmine\utils\Binary;
use pocketmine\world\World;
use function array_pad; use function array_pad;
use function array_slice; use function array_slice;
use function explode; use function explode;
@ -72,9 +71,9 @@ class Sign extends Spawnable{
protected ?int $editorEntityRuntimeId = null; protected ?int $editorEntityRuntimeId = null;
public function __construct(World $world, Vector3 $pos){ public function __construct(BlockPosition $position){
$this->text = new SignText(); $this->text = new SignText();
parent::__construct($world, $pos); parent::__construct($position);
} }
private function readTextTag(CompoundTag $nbt, bool $lightingBugResolved) : void{ private function readTextTag(CompoundTag $nbt, bool $lightingBugResolved) : void{

View File

@ -28,15 +28,13 @@ declare(strict_types=1);
namespace pocketmine\block\tile; namespace pocketmine\block\tile;
use pocketmine\block\Block; use pocketmine\block\Block;
use pocketmine\block\BlockPosition;
use pocketmine\item\Item; use pocketmine\item\Item;
use pocketmine\math\Vector3;
use pocketmine\nbt\NbtDataException; use pocketmine\nbt\NbtDataException;
use pocketmine\nbt\tag\CompoundTag; use pocketmine\nbt\tag\CompoundTag;
use pocketmine\timings\Timings; use pocketmine\timings\Timings;
use pocketmine\timings\TimingsHandler; use pocketmine\timings\TimingsHandler;
use pocketmine\VersionInfo; use pocketmine\VersionInfo;
use pocketmine\world\Position;
use pocketmine\world\World;
use function get_class; use function get_class;
abstract class Tile{ abstract class Tile{
@ -46,12 +44,12 @@ abstract class Tile{
public const TAG_Y = "y"; public const TAG_Y = "y";
public const TAG_Z = "z"; public const TAG_Z = "z";
protected Position $position;
public bool $closed = false; public bool $closed = false;
protected TimingsHandler $timings; protected TimingsHandler $timings;
public function __construct(World $world, Vector3 $pos){ public function __construct(
$this->position = Position::fromObject($pos, $world); protected BlockPosition $position,
){
$this->timings = Timings::getTileEntityTimings($this); $this->timings = Timings::getTileEntityTimings($this);
} }
@ -70,9 +68,9 @@ abstract class Tile{
public function saveNBT() : CompoundTag{ public function saveNBT() : CompoundTag{
$nbt = CompoundTag::create() $nbt = CompoundTag::create()
->setString(self::TAG_ID, TileFactory::getInstance()->getSaveId(get_class($this))) ->setString(self::TAG_ID, TileFactory::getInstance()->getSaveId(get_class($this)))
->setInt(self::TAG_X, $this->position->getFloorX()) ->setInt(self::TAG_X, $this->position->x)
->setInt(self::TAG_Y, $this->position->getFloorY()) ->setInt(self::TAG_Y, $this->position->y)
->setInt(self::TAG_Z, $this->position->getFloorZ()) ->setInt(self::TAG_Z, $this->position->z)
->setLong(VersionInfo::TAG_WORLD_DATA_VERSION, VersionInfo::WORLD_DATA_VERSION); ->setLong(VersionInfo::TAG_WORLD_DATA_VERSION, VersionInfo::WORLD_DATA_VERSION);
$this->writeSaveData($nbt); $this->writeSaveData($nbt);
@ -99,7 +97,7 @@ abstract class Tile{
return $this->position->getWorld()->getBlock($this->position); return $this->position->getWorld()->getBlock($this->position);
} }
public function getPosition() : Position{ public function getPosition() : BlockPosition{
return $this->position; return $this->position;
} }

View File

@ -23,8 +23,8 @@ declare(strict_types=1);
namespace pocketmine\block\tile; namespace pocketmine\block\tile;
use pocketmine\block\BlockPosition;
use pocketmine\data\SavedDataLoadingException; use pocketmine\data\SavedDataLoadingException;
use pocketmine\math\Vector3;
use pocketmine\nbt\NbtException; use pocketmine\nbt\NbtException;
use pocketmine\nbt\tag\CompoundTag; use pocketmine\nbt\tag\CompoundTag;
use pocketmine\utils\SingletonTrait; use pocketmine\utils\SingletonTrait;
@ -130,7 +130,7 @@ final class TileFactory{
* @var Tile $tile * @var Tile $tile
* @see Tile::__construct() * @see Tile::__construct()
*/ */
$tile = new $class($world, new Vector3($nbt->getInt(Tile::TAG_X), $nbt->getInt(Tile::TAG_Y), $nbt->getInt(Tile::TAG_Z))); $tile = new $class(new BlockPosition($nbt->getInt(Tile::TAG_X), $nbt->getInt(Tile::TAG_Y), $nbt->getInt(Tile::TAG_Z), $world));
$tile->readSaveData($nbt); $tile->readSaveData($nbt);
}catch(NbtException $e){ }catch(NbtException $e){
throw new SavedDataLoadingException($e->getMessage(), 0, $e); throw new SavedDataLoadingException($e->getMessage(), 0, $e);

View File

@ -34,7 +34,7 @@ trait AmethystTrait{
* @see Block::onProjectileHit() * @see Block::onProjectileHit()
*/ */
public function onProjectileHit(Projectile $projectile, RayTraceResult $hitResult) : void{ public function onProjectileHit(Projectile $projectile, RayTraceResult $hitResult) : void{
$this->position->getWorld()->addSound($this->position, new AmethystBlockChimeSound()); $this->position->getWorld()->addSound($this->position->asVector3(), new AmethystBlockChimeSound());
$this->position->getWorld()->addSound($this->position, new BlockPunchSound($this)); $this->position->getWorld()->addSound($this->position->asVector3(), new BlockPunchSound($this));
} }
} }

View File

@ -54,9 +54,9 @@ trait CandleTrait{
}elseif($item->getTypeId() === ItemTypeIds::FIRE_CHARGE){ }elseif($item->getTypeId() === ItemTypeIds::FIRE_CHARGE){
$item->pop(); $item->pop();
//TODO: not sure if this is intentional, but it's what Bedrock currently does as of 1.20.10 //TODO: not sure if this is intentional, but it's what Bedrock currently does as of 1.20.10
$this->position->getWorld()->addSound($this->position, new BlazeShootSound()); $this->position->getWorld()->addSound($this->position->asVector3(), new BlazeShootSound());
} }
$this->position->getWorld()->addSound($this->position, new FlintSteelSound()); $this->position->getWorld()->addSound($this->position->asVector3(), new FlintSteelSound());
$this->position->getWorld()->setBlock($this->position, $this->setLit(true)); $this->position->getWorld()->setBlock($this->position, $this->setLit(true));
return true; return true;
@ -65,7 +65,7 @@ trait CandleTrait{
if(!$this->lit){ if(!$this->lit){
return true; return true;
} }
$this->position->getWorld()->addSound($this->position, new FireExtinguishSound()); $this->position->getWorld()->addSound($this->position->asVector3(), new FireExtinguishSound());
$this->position->getWorld()->setBlock($this->position, $this->setLit(false)); $this->position->getWorld()->setBlock($this->position, $this->setLit(false));
return true; return true;

View File

@ -63,7 +63,7 @@ trait CopperTrait{
$this->waxed = true; $this->waxed = true;
$this->position->getWorld()->setBlock($this->position, $this); $this->position->getWorld()->setBlock($this->position, $this);
//TODO: orange particles are supposed to appear when applying wax //TODO: orange particles are supposed to appear when applying wax
$this->position->getWorld()->addSound($this->position, new CopperWaxApplySound()); $this->position->getWorld()->addSound($this->position->asVector3(), new CopperWaxApplySound());
$item->pop(); $item->pop();
return true; return true;
} }
@ -73,7 +73,7 @@ trait CopperTrait{
$this->waxed = false; $this->waxed = false;
$this->position->getWorld()->setBlock($this->position, $this); $this->position->getWorld()->setBlock($this->position, $this);
//TODO: white particles are supposed to appear when removing wax //TODO: white particles are supposed to appear when removing wax
$this->position->getWorld()->addSound($this->position, new CopperWaxRemoveSound()); $this->position->getWorld()->addSound($this->position->asVector3(), new CopperWaxRemoveSound());
$item->applyDamage(1); $item->applyDamage(1);
return true; return true;
} }
@ -83,7 +83,7 @@ trait CopperTrait{
$this->oxidation = $previousOxidation; $this->oxidation = $previousOxidation;
$this->position->getWorld()->setBlock($this->position, $this); $this->position->getWorld()->setBlock($this->position, $this);
//TODO: turquoise particles are supposed to appear when removing oxidation //TODO: turquoise particles are supposed to appear when removing oxidation
$this->position->getWorld()->addSound($this->position, new ScrapeSound()); $this->position->getWorld()->addSound($this->position->asVector3(), new ScrapeSound());
$item->applyDamage(1); $item->applyDamage(1);
return true; return true;
} }

View File

@ -56,9 +56,9 @@ final class CropGrowthHelper{
$position = $block->getPosition(); $position = $block->getPosition();
$world = $position->getWorld(); $world = $position->getWorld();
$baseX = $position->getFloorX(); $baseX = $position->x;
$baseY = $position->getFloorY(); $baseY = $position->y;
$baseZ = $position->getFloorZ(); $baseZ = $position->z;
$farmland = $world->getBlockAt($baseX, $baseY - 1, $baseZ); $farmland = $world->getBlockAt($baseX, $baseY - 1, $baseZ);

View File

@ -24,12 +24,12 @@ declare(strict_types=1);
namespace pocketmine\block\utils; namespace pocketmine\block\utils;
use pocketmine\block\Block; use pocketmine\block\Block;
use pocketmine\block\BlockPosition;
use pocketmine\block\VanillaBlocks; use pocketmine\block\VanillaBlocks;
use pocketmine\entity\Location; use pocketmine\entity\Location;
use pocketmine\entity\object\FallingBlock; use pocketmine\entity\object\FallingBlock;
use pocketmine\math\Facing; use pocketmine\math\Facing;
use pocketmine\utils\AssumptionFailedError; use pocketmine\utils\AssumptionFailedError;
use pocketmine\world\Position;
use pocketmine\world\sound\Sound; use pocketmine\world\sound\Sound;
/** /**
@ -39,7 +39,7 @@ use pocketmine\world\sound\Sound;
*/ */
trait FallableTrait{ trait FallableTrait{
abstract protected function getPosition() : Position; abstract protected function getPosition() : BlockPosition;
public function onNearbyBlockChange() : void{ public function onNearbyBlockChange() : void{
$pos = $this->getPosition(); $pos = $this->getPosition();
@ -51,7 +51,7 @@ trait FallableTrait{
$block = $this; $block = $this;
if(!($block instanceof Block)) throw new AssumptionFailedError(__TRAIT__ . " should only be used by Blocks"); if(!($block instanceof Block)) throw new AssumptionFailedError(__TRAIT__ . " should only be used by Blocks");
$fall = new FallingBlock(Location::fromObject($pos->add(0.5, 0, 0.5), $world), $block); $fall = new FallingBlock(Location::fromObject($pos->asVector3()->add(0.5, 0, 0.5), $world), $block);
$fall->spawnToAll(); $fall->spawnToAll();
} }
} }

View File

@ -26,6 +26,7 @@ namespace pocketmine\entity;
use DaveRandom\CallbackValidator\CallbackType; use DaveRandom\CallbackValidator\CallbackType;
use DaveRandom\CallbackValidator\ParameterType; use DaveRandom\CallbackValidator\ParameterType;
use DaveRandom\CallbackValidator\ReturnType; use DaveRandom\CallbackValidator\ReturnType;
use pocketmine\block\BlockPosition;
use pocketmine\block\RuntimeBlockStateRegistry; use pocketmine\block\RuntimeBlockStateRegistry;
use pocketmine\data\bedrock\LegacyEntityIdToStringIdMap; use pocketmine\data\bedrock\LegacyEntityIdToStringIdMap;
use pocketmine\data\bedrock\PotionTypeIdMap; use pocketmine\data\bedrock\PotionTypeIdMap;
@ -48,7 +49,6 @@ use pocketmine\entity\projectile\Snowball;
use pocketmine\entity\projectile\SplashPotion; use pocketmine\entity\projectile\SplashPotion;
use pocketmine\item\Item; use pocketmine\item\Item;
use pocketmine\math\Facing; use pocketmine\math\Facing;
use pocketmine\math\Vector3;
use pocketmine\nbt\NbtException; use pocketmine\nbt\NbtException;
use pocketmine\nbt\tag\ByteTag; use pocketmine\nbt\tag\ByteTag;
use pocketmine\nbt\tag\CompoundTag; use pocketmine\nbt\tag\CompoundTag;
@ -143,7 +143,7 @@ final class EntityFactory{
if($motive === null){ if($motive === null){
throw new SavedDataLoadingException("Unknown painting motive"); throw new SavedDataLoadingException("Unknown painting motive");
} }
$blockIn = new Vector3($nbt->getInt(Painting::TAG_TILE_X), $nbt->getInt(Painting::TAG_TILE_Y), $nbt->getInt(Painting::TAG_TILE_Z)); $blockIn = new BlockPosition($nbt->getInt(Painting::TAG_TILE_X), $nbt->getInt(Painting::TAG_TILE_Y), $nbt->getInt(Painting::TAG_TILE_Z), $world);
if(($directionTag = $nbt->getTag(Painting::TAG_DIRECTION_BE)) instanceof ByteTag){ if(($directionTag = $nbt->getTag(Painting::TAG_DIRECTION_BE)) instanceof ByteTag){
$facing = Painting::DATA_TO_FACING[$directionTag->getValue()] ?? Facing::NORTH; $facing = Painting::DATA_TO_FACING[$directionTag->getValue()] ?? Facing::NORTH;
}elseif(($facingTag = $nbt->getTag(Painting::TAG_FACING_JE)) instanceof ByteTag){ }elseif(($facingTag = $nbt->getTag(Painting::TAG_FACING_JE)) instanceof ByteTag){

View File

@ -377,11 +377,12 @@ abstract class Living extends Entity{
} }
protected function onHitGround() : ?float{ protected function onHitGround() : ?float{
$fallBlockPos = $this->location->floor(); $fallBlockX = $this->location->getFloorX();
$fallBlock = $this->getWorld()->getBlock($fallBlockPos); $fallBlockY = $this->location->getFloorY();
$fallBlockZ = $this->location->getFloorZ();
$fallBlock = $this->getWorld()->getBlockAt($fallBlockX, $fallBlockY, $fallBlockZ);
if(count($fallBlock->getCollisionBoxes()) === 0){ if(count($fallBlock->getCollisionBoxes()) === 0){
$fallBlockPos = $fallBlockPos->down(); $fallBlock = $this->getWorld()->getBlockAt($fallBlockX, $fallBlockY - 1, $fallBlockZ);
$fallBlock = $this->getWorld()->getBlock($fallBlockPos);
} }
$newVerticalVelocity = $fallBlock->onEntityLand($this); $newVerticalVelocity = $fallBlock->onEntityLand($this);

View File

@ -132,7 +132,7 @@ class FallingBlock extends Entity{
$world = $this->getWorld(); $world = $this->getWorld();
$pos = $this->location->add(-$this->size->getWidth() / 2, $this->size->getHeight(), -$this->size->getWidth() / 2)->floor(); $pos = $this->location->add(-$this->size->getWidth() / 2, $this->size->getHeight(), -$this->size->getWidth() / 2)->floor();
$this->block->position($world, $pos->x, $pos->y, $pos->z); $this->block->position($world, $pos->getFloorX(), $pos->getFloorY(), $pos->getFloorZ());
$blockTarget = null; $blockTarget = null;
if($this->block instanceof Fallable){ if($this->block instanceof Fallable){
@ -143,7 +143,7 @@ class FallingBlock extends Entity{
$this->flagForDespawn(); $this->flagForDespawn();
$blockResult = $blockTarget ?? $this->block; $blockResult = $blockTarget ?? $this->block;
$block = $world->getBlock($pos); $block = $world->getBlock($this->block->getPosition());
if(!$block->canBeReplaced() || !$world->isInWorld($pos->getFloorX(), $pos->getFloorY(), $pos->getFloorZ()) || ($this->onGround && abs($this->location->y - $this->location->getFloorY()) > 0.001)){ if(!$block->canBeReplaced() || !$world->isInWorld($pos->getFloorX(), $pos->getFloorY(), $pos->getFloorZ()) || ($this->onGround && abs($this->location->y - $this->location->getFloorY()) > 0.001)){
$world->dropItem($this->location, $this->block->asItem()); $world->dropItem($this->location, $this->block->asItem());
$world->addSound($pos->add(0.5, 0.5, 0.5), new BlockBreakSound($blockResult)); $world->addSound($pos->add(0.5, 0.5, 0.5), new BlockBreakSound($blockResult));
@ -152,7 +152,7 @@ class FallingBlock extends Entity{
$ev->call(); $ev->call();
if(!$ev->isCancelled()){ if(!$ev->isCancelled()){
$b = $ev->getTo(); $b = $ev->getTo();
$world->setBlock($pos, $b); $world->setBlock($this->block->getPosition(), $b);
if($this->onGround && $b instanceof Fallable && ($sound = $b->getLandSound()) !== null){ if($this->onGround && $b instanceof Fallable && ($sound = $b->getLandSound()) !== null){
$world->addSound($pos->add(0.5, 0.5, 0.5), $sound); $world->addSound($pos->add(0.5, 0.5, 0.5), $sound);
} }

View File

@ -23,6 +23,7 @@ declare(strict_types=1);
namespace pocketmine\entity\object; namespace pocketmine\entity\object;
use pocketmine\block\BlockPosition;
use pocketmine\block\VanillaBlocks; use pocketmine\block\VanillaBlocks;
use pocketmine\entity\Entity; use pocketmine\entity\Entity;
use pocketmine\entity\EntitySizeInfo; use pocketmine\entity\EntitySizeInfo;
@ -64,13 +65,13 @@ class Painting extends Entity{
Facing::EAST => 3 Facing::EAST => 3
]; ];
protected Vector3 $blockIn; protected BlockPosition $blockIn;
protected int $facing; protected int $facing;
protected PaintingMotive $motive; protected PaintingMotive $motive;
public function __construct(Location $location, Vector3 $blockIn, int $facing, PaintingMotive $motive, ?CompoundTag $nbt = null){ public function __construct(Location $location, BlockPosition $blockIn, int $facing, PaintingMotive $motive, ?CompoundTag $nbt = null){
$this->motive = $motive; $this->motive = $motive;
$this->blockIn = $blockIn->asVector3(); $this->blockIn = $blockIn;
$this->facing = $facing; $this->facing = $facing;
parent::__construct($location, $nbt); parent::__construct($location, $nbt);
} }
@ -92,9 +93,9 @@ class Painting extends Entity{
public function saveNBT() : CompoundTag{ public function saveNBT() : CompoundTag{
$nbt = parent::saveNBT(); $nbt = parent::saveNBT();
$nbt->setInt(self::TAG_TILE_X, (int) $this->blockIn->x); $nbt->setInt(self::TAG_TILE_X, $this->blockIn->x);
$nbt->setInt(self::TAG_TILE_Y, (int) $this->blockIn->y); $nbt->setInt(self::TAG_TILE_Y, $this->blockIn->y);
$nbt->setInt(self::TAG_TILE_Z, (int) $this->blockIn->z); $nbt->setInt(self::TAG_TILE_Z, $this->blockIn->z);
$nbt->setByte(self::TAG_FACING_JE, self::FACING_TO_DATA[$this->facing]); $nbt->setByte(self::TAG_FACING_JE, self::FACING_TO_DATA[$this->facing]);
$nbt->setByte(self::TAG_DIRECTION_BE, self::FACING_TO_DATA[$this->facing]); //Save both for full compatibility $nbt->setByte(self::TAG_DIRECTION_BE, self::FACING_TO_DATA[$this->facing]); //Save both for full compatibility
@ -202,7 +203,7 @@ class Painting extends Entity{
/** /**
* Returns whether a painting with the specified motive can be placed at the given position. * Returns whether a painting with the specified motive can be placed at the given position.
*/ */
public static function canFit(World $world, Vector3 $blockIn, int $facing, bool $checkOverlap, PaintingMotive $motive) : bool{ public static function canFit(World $world, BlockPosition $blockIn, int $facing, bool $checkOverlap, PaintingMotive $motive) : bool{
$width = $motive->getWidth(); $width = $motive->getWidth();
$height = $motive->getHeight(); $height = $motive->getHeight();
@ -213,7 +214,7 @@ class Painting extends Entity{
$oppositeSide = Facing::opposite($facing); $oppositeSide = Facing::opposite($facing);
$startPos = $blockIn->asVector3()->getSide(Facing::opposite($rotatedFace), $horizontalStart)->getSide(Facing::DOWN, $verticalStart); $startPos = $blockIn->getSide(Facing::opposite($rotatedFace), $horizontalStart)->getSide(Facing::DOWN, $verticalStart);
for($w = 0; $w < $width; ++$w){ for($w = 0; $w < $width; ++$w){
for($h = 0; $h < $height; ++$h){ for($h = 0; $h < $height; ++$h){

View File

@ -68,9 +68,9 @@ class IceBomb extends Throwable{
$pos = $blockHit->getPosition(); $pos = $blockHit->getPosition();
$world = $pos->getWorld(); $world = $pos->getWorld();
$posX = $pos->getFloorX(); $posX = $pos->x;
$posY = $pos->getFloorY(); $posY = $pos->y;
$posZ = $pos->getFloorZ(); $posZ = $pos->z;
$ice = VanillaBlocks::ICE(); $ice = VanillaBlocks::ICE();
for($x = $posX - 1; $x <= $posX + 1; $x++){ for($x = $posX - 1; $x <= $posX + 1; $x++){

View File

@ -24,6 +24,7 @@ declare(strict_types=1);
namespace pocketmine\entity\projectile; namespace pocketmine\entity\projectile;
use pocketmine\block\Block; use pocketmine\block\Block;
use pocketmine\block\BlockPosition;
use pocketmine\data\SavedDataLoadingException; use pocketmine\data\SavedDataLoadingException;
use pocketmine\entity\Entity; use pocketmine\entity\Entity;
use pocketmine\entity\Living; use pocketmine\entity\Living;
@ -60,7 +61,7 @@ abstract class Projectile extends Entity{
private const TAG_TILE_Z = "tileZ"; //TAG_Int private const TAG_TILE_Z = "tileZ"; //TAG_Int
protected float $damage = 0.0; protected float $damage = 0.0;
protected ?Vector3 $blockHit = null; protected ?BlockPosition $blockHit = null;
public function __construct(Location $location, ?Entity $shootingEntity, ?CompoundTag $nbt = null){ public function __construct(Location $location, ?Entity $shootingEntity, ?CompoundTag $nbt = null){
parent::__construct($location, $nbt); parent::__construct($location, $nbt);
@ -90,9 +91,9 @@ abstract class Projectile extends Entity{
/** @var IntTag[] $values */ /** @var IntTag[] $values */
$values = $stuckOnBlockPosTag->getValue(); $values = $stuckOnBlockPosTag->getValue();
$this->blockHit = new Vector3($values[0]->getValue(), $values[1]->getValue(), $values[2]->getValue()); $this->blockHit = new BlockPosition($values[0]->getValue(), $values[1]->getValue(), $values[2]->getValue(), $this->getWorld());
}elseif(($tileXTag = $nbt->getTag(self::TAG_TILE_X)) instanceof IntTag && ($tileYTag = $nbt->getTag(self::TAG_TILE_Y)) instanceof IntTag && ($tileZTag = $nbt->getTag(self::TAG_TILE_Z)) instanceof IntTag){ }elseif(($tileXTag = $nbt->getTag(self::TAG_TILE_X)) instanceof IntTag && ($tileYTag = $nbt->getTag(self::TAG_TILE_Y)) instanceof IntTag && ($tileZTag = $nbt->getTag(self::TAG_TILE_Z)) instanceof IntTag){
$this->blockHit = new Vector3($tileXTag->getValue(), $tileYTag->getValue(), $tileZTag->getValue()); $this->blockHit = new BlockPosition($tileXTag->getValue(), $tileYTag->getValue(), $tileZTag->getValue(), $this->getWorld());
} }
} }
@ -133,9 +134,9 @@ abstract class Projectile extends Entity{
if($this->blockHit !== null){ if($this->blockHit !== null){
$nbt->setTag(self::TAG_STUCK_ON_BLOCK_POS, new ListTag([ $nbt->setTag(self::TAG_STUCK_ON_BLOCK_POS, new ListTag([
new IntTag($this->blockHit->getFloorX()), new IntTag($this->blockHit->x),
new IntTag($this->blockHit->getFloorY()), new IntTag($this->blockHit->y),
new IntTag($this->blockHit->getFloorZ()) new IntTag($this->blockHit->z)
])); ]));
} }
@ -147,7 +148,7 @@ abstract class Projectile extends Entity{
} }
public function onNearbyBlockChange() : void{ public function onNearbyBlockChange() : void{
if($this->blockHit !== null && $this->getWorld()->isInLoadedTerrain($this->blockHit)){ if($this->blockHit !== null && $this->getWorld()->isInLoadedTerrain($this->blockHit->asVector3())){
$blockHit = $this->getWorld()->getBlock($this->blockHit); $blockHit = $this->getWorld()->getBlock($this->blockHit);
if(!$blockHit->collidesWithBB($this->getBoundingBox()->expandedCopy(0.001, 0.001, 0.001))){ if(!$blockHit->collidesWithBB($this->getBoundingBox()->expandedCopy(0.001, 0.001, 0.001))){
$this->blockHit = null; $this->blockHit = null;
@ -176,7 +177,7 @@ abstract class Projectile extends Entity{
$world = $this->getWorld(); $world = $this->getWorld();
foreach(VoxelRayTrace::betweenPoints($start, $end) as $vector3){ foreach(VoxelRayTrace::betweenPoints($start, $end) as $vector3){
$block = $world->getBlockAt($vector3->x, $vector3->y, $vector3->z); $block = $world->getBlockAt($vector3->getFloorX(), $vector3->getFloorY(), $vector3->getFloorZ());
$blockHitResult = $this->calculateInterceptWithBlock($block, $start, $end); $blockHitResult = $this->calculateInterceptWithBlock($block, $start, $end);
if($blockHitResult !== null){ if($blockHitResult !== null){
@ -314,7 +315,7 @@ abstract class Projectile extends Entity{
* Called when the projectile collides with a Block. * Called when the projectile collides with a Block.
*/ */
protected function onHitBlock(Block $blockHit, RayTraceResult $hitResult) : void{ protected function onHitBlock(Block $blockHit, RayTraceResult $hitResult) : void{
$this->blockHit = $blockHit->getPosition()->asVector3(); $this->blockHit = $blockHit->getPosition();
$blockHit->onProjectileHit($this, $hitResult); $blockHit->onProjectileHit($this, $hitResult);
} }
} }

View File

@ -56,7 +56,7 @@ class Bucket extends Item{
$ev->call(); $ev->call();
if(!$ev->isCancelled()){ if(!$ev->isCancelled()){
$player->getWorld()->setBlock($blockClicked->getPosition(), VanillaBlocks::AIR()); $player->getWorld()->setBlock($blockClicked->getPosition(), VanillaBlocks::AIR());
$player->getWorld()->addSound($blockClicked->getPosition()->add(0.5, 0.5, 0.5), $blockClicked->getBucketFillSound()); $player->getWorld()->addSound($blockClicked->getPosition()->asVector3()->add(0.5, 0.5, 0.5), $blockClicked->getBucketFillSound());
$this->pop(); $this->pop();
$returnedItems[] = $ev->getItem(); $returnedItems[] = $ev->getItem();

View File

@ -40,14 +40,14 @@ class EndCrystal extends Item{
$pos = $blockClicked->getPosition(); $pos = $blockClicked->getPosition();
$world = $pos->getWorld(); $world = $pos->getWorld();
$bb = AxisAlignedBB::one() $bb = AxisAlignedBB::one()
->offset($pos->getX(), $pos->getY(), $pos->getZ()) ->offset($pos->x, $pos->y, $pos->z)
->extend(Facing::UP, 1); ->extend(Facing::UP, 1);
if( if(
count($world->getNearbyEntities($bb)) === 0 && count($world->getNearbyEntities($bb)) === 0 &&
$blockClicked->getSide(Facing::UP)->getTypeId() === BlockTypeIds::AIR && $blockClicked->getSide(Facing::UP)->getTypeId() === BlockTypeIds::AIR &&
$blockClicked->getSide(Facing::UP, 2)->getTypeId() === BlockTypeIds::AIR $blockClicked->getSide(Facing::UP, 2)->getTypeId() === BlockTypeIds::AIR
){ ){
$crystal = new EntityEndCrystal(Location::fromObject($pos->add(0.5, 1, 0.5), $world)); $crystal = new EntityEndCrystal(Location::fromObject($pos->asVector3()->add(0.5, 1, 0.5), $world));
$crystal->spawnToAll(); $crystal->spawnToAll();
$this->pop(); $this->pop();

View File

@ -36,7 +36,7 @@ class FireCharge extends Item{
if($blockReplace->getTypeId() === BlockTypeIds::AIR){ if($blockReplace->getTypeId() === BlockTypeIds::AIR){
$world = $player->getWorld(); $world = $player->getWorld();
$world->setBlock($blockReplace->getPosition(), VanillaBlocks::FIRE()); $world->setBlock($blockReplace->getPosition(), VanillaBlocks::FIRE());
$world->addSound($blockReplace->getPosition()->add(0.5, 0.5, 0.5), new BlazeShootSound()); $world->addSound($blockReplace->getPosition()->asVector3()->add(0.5, 0.5, 0.5), new BlazeShootSound());
$this->pop(); $this->pop();

View File

@ -36,7 +36,7 @@ class FlintSteel extends Tool{
if($blockReplace->getTypeId() === BlockTypeIds::AIR){ if($blockReplace->getTypeId() === BlockTypeIds::AIR){
$world = $player->getWorld(); $world = $player->getWorld();
$world->setBlock($blockReplace->getPosition(), VanillaBlocks::FIRE()); $world->setBlock($blockReplace->getPosition(), VanillaBlocks::FIRE());
$world->addSound($blockReplace->getPosition()->add(0.5, 0.5, 0.5), new FlintSteelSound()); $world->addSound($blockReplace->getPosition()->asVector3()->add(0.5, 0.5, 0.5), new FlintSteelSound());
$this->applyDamage(1); $this->applyDamage(1);

View File

@ -66,7 +66,7 @@ class LiquidBucket extends Item{
$ev->call(); $ev->call();
if(!$ev->isCancelled()){ if(!$ev->isCancelled()){
$player->getWorld()->setBlock($blockReplace->getPosition(), $resultBlock->getFlowingForm()); $player->getWorld()->setBlock($blockReplace->getPosition(), $resultBlock->getFlowingForm());
$player->getWorld()->addSound($blockReplace->getPosition()->add(0.5, 0.5, 0.5), $resultBlock->getBucketEmptySound()); $player->getWorld()->addSound($blockReplace->getPosition()->asVector3()->add(0.5, 0.5, 0.5), $resultBlock->getBucketEmptySound());
$this->pop(); $this->pop();
$returnedItems[] = $ev->getItem(); $returnedItems[] = $ev->getItem();

View File

@ -74,13 +74,14 @@ class PaintingItem extends Item{
$motive = $motives[array_rand($motives)]; $motive = $motives[array_rand($motives)];
$replacePos = $blockReplace->getPosition(); $replacePos = $blockReplace->getPosition();
$replaceVec3 = $replacePos->asVector3();
$clickedPos = $blockClicked->getPosition(); $clickedPos = $blockClicked->getPosition();
$entity = new Painting(Location::fromObject($replacePos, $replacePos->getWorld()), $clickedPos, $face, $motive); $entity = new Painting(Location::fromObject($replaceVec3, $replacePos->getWorld()), $clickedPos, $face, $motive);
$this->pop(); $this->pop();
$entity->spawnToAll(); $entity->spawnToAll();
$player->getWorld()->addSound($replacePos->add(0.5, 0.5, 0.5), new PaintingPlaceSound()); $player->getWorld()->addSound($replaceVec3->add(0.5, 0.5, 0.5), new PaintingPlaceSound());
return ItemUseResult::SUCCESS; return ItemUseResult::SUCCESS;
} }
} }

Some files were not shown because too many files have changed in this diff Show More