Merge commit 'a2543ff80d2906bccda1a4e2fdbd9d8e7d147fb3'

This commit is contained in:
Dylan K. Taylor 2020-04-18 17:33:05 +01:00
commit 86e051b7bf
76 changed files with 286 additions and 238 deletions

View File

@ -99,7 +99,7 @@ class Banner extends Transparent{
public function readStateFromWorld() : void{ public function readStateFromWorld() : void{
parent::readStateFromWorld(); parent::readStateFromWorld();
$tile = $this->pos->getWorld()->getTile($this->pos); $tile = $this->pos->getWorldNonNull()->getTile($this->pos);
if($tile instanceof TileBanner){ if($tile instanceof TileBanner){
$this->baseColor = $tile->getBaseColor(); $this->baseColor = $tile->getBaseColor();
$this->setPatterns($tile->getPatterns()); $this->setPatterns($tile->getPatterns());
@ -108,7 +108,7 @@ class Banner extends Transparent{
public function writeStateToWorld() : void{ public function writeStateToWorld() : void{
parent::writeStateToWorld(); parent::writeStateToWorld();
$tile = $this->pos->getWorld()->getTile($this->pos); $tile = $this->pos->getWorldNonNull()->getTile($this->pos);
assert($tile instanceof TileBanner); assert($tile instanceof TileBanner);
$tile->setBaseColor($this->baseColor); $tile->setBaseColor($this->baseColor);
$tile->setPatterns($this->patterns); $tile->setPatterns($this->patterns);
@ -171,7 +171,7 @@ class Banner extends Transparent{
public function onNearbyBlockChange() : void{ public function onNearbyBlockChange() : void{
if($this->getSide(Facing::opposite($this->facing))->getId() === BlockLegacyIds::AIR){ if($this->getSide(Facing::opposite($this->facing))->getId() === BlockLegacyIds::AIR){
$this->pos->getWorld()->useBreakOn($this->pos); $this->pos->getWorldNonNull()->useBreakOn($this->pos);
} }
} }

View File

@ -255,7 +255,7 @@ abstract class BaseRail extends Flowable{
if(isset($otherPossible[$otherSide])){ if(isset($otherPossible[$otherSide])){
$otherConnections[] = $otherSide; $otherConnections[] = $otherSide;
$other->setConnections($otherConnections); $other->setConnections($otherConnections);
$this->pos->getWorld()->setBlock($other->pos, $other); $this->pos->getWorldNonNull()->setBlock($other->pos, $other);
$changed = true; $changed = true;
$thisConnections[] = $thisSide; $thisConnections[] = $thisSide;
@ -268,7 +268,7 @@ abstract class BaseRail extends Flowable{
if($changed){ if($changed){
$this->setConnections($thisConnections); $this->setConnections($thisConnections);
$this->pos->getWorld()->setBlock($this->pos, $this); $this->pos->getWorldNonNull()->setBlock($this->pos, $this);
} }
} }
@ -287,11 +287,11 @@ abstract class BaseRail extends Flowable{
public function onNearbyBlockChange() : void{ public function onNearbyBlockChange() : void{
if($this->getSide(Facing::DOWN)->isTransparent()){ if($this->getSide(Facing::DOWN)->isTransparent()){
$this->pos->getWorld()->useBreakOn($this->pos); $this->pos->getWorldNonNull()->useBreakOn($this->pos);
}else{ }else{
foreach($this->connections as $connection){ foreach($this->connections as $connection){
if(($connection & self::FLAG_ASCEND) !== 0 and $this->getSide($connection & ~self::FLAG_ASCEND)->isTransparent()){ if(($connection & self::FLAG_ASCEND) !== 0 and $this->getSide($connection & ~self::FLAG_ASCEND)->isTransparent()){
$this->pos->getWorld()->useBreakOn($this->pos); $this->pos->getWorldNonNull()->useBreakOn($this->pos);
break; break;
} }
} }

View File

@ -73,7 +73,7 @@ class Bed extends Transparent{
public function readStateFromWorld() : void{ public function readStateFromWorld() : void{
parent::readStateFromWorld(); parent::readStateFromWorld();
//read extra state information from the tile - this is an ugly hack //read extra state information from the tile - this is an ugly hack
$tile = $this->pos->getWorld()->getTile($this->pos); $tile = $this->pos->getWorldNonNull()->getTile($this->pos);
if($tile instanceof TileBed){ if($tile instanceof TileBed){
$this->color = $tile->getColor(); $this->color = $tile->getColor();
} }
@ -82,7 +82,7 @@ class Bed extends Transparent{
public function writeStateToWorld() : void{ public function writeStateToWorld() : void{
parent::writeStateToWorld(); parent::writeStateToWorld();
//extra block properties storage hack //extra block properties storage hack
$tile = $this->pos->getWorld()->getTile($this->pos); $tile = $this->pos->getWorldNonNull()->getTile($this->pos);
if($tile instanceof TileBed){ if($tile instanceof TileBed){
$tile->setColor($this->color); $tile->setColor($this->color);
} }
@ -105,11 +105,11 @@ class Bed extends Transparent{
public function setOccupied(bool $occupied = true) : void{ public function setOccupied(bool $occupied = true) : void{
$this->occupied = $occupied; $this->occupied = $occupied;
$this->pos->getWorld()->setBlock($this->pos, $this, false); $this->pos->getWorldNonNull()->setBlock($this->pos, $this, false);
if(($other = $this->getOtherHalf()) !== null){ if(($other = $this->getOtherHalf()) !== null){
$other->occupied = $occupied; $other->occupied = $occupied;
$this->pos->getWorld()->setBlock($other->pos, $other, false); $this->pos->getWorldNonNull()->setBlock($other->pos, $other, false);
} }
} }
@ -139,7 +139,7 @@ class Bed extends Transparent{
return true; return true;
} }
$time = $this->pos->getWorld()->getTimeOfDay(); $time = $this->pos->getWorldNonNull()->getTimeOfDay();
$isNight = ($time >= World::TIME_NIGHT and $time < World::TIME_SUNRISE); $isNight = ($time >= World::TIME_NIGHT and $time < World::TIME_SUNRISE);

View File

@ -150,10 +150,10 @@ class Block{
} }
public function writeStateToWorld() : void{ public function writeStateToWorld() : void{
$this->pos->getWorld()->getChunkAtPosition($this->pos)->setFullBlock($this->pos->x & 0xf, $this->pos->y, $this->pos->z & 0xf, $this->getFullId()); $this->pos->getWorldNonNull()->getChunkAtPosition($this->pos)->setFullBlock($this->pos->x & 0xf, $this->pos->y, $this->pos->z & 0xf, $this->getFullId());
$tileType = $this->idInfo->getTileClass(); $tileType = $this->idInfo->getTileClass();
$oldTile = $this->pos->getWorld()->getTile($this->pos); $oldTile = $this->pos->getWorldNonNull()->getTile($this->pos);
if($oldTile !== null){ if($oldTile !== null){
if($tileType === null or !($oldTile instanceof $tileType)){ if($tileType === null or !($oldTile instanceof $tileType)){
$oldTile->close(); $oldTile->close();
@ -163,7 +163,7 @@ class Block{
} }
} }
if($oldTile === null and $tileType !== null){ if($oldTile === null and $tileType !== null){
$this->pos->getWorld()->addTile(TileFactory::create($tileType, $this->pos->getWorld(), $this->pos->asVector3())); $this->pos->getWorldNonNull()->addTile(TileFactory::create($tileType, $this->pos->getWorld(), $this->pos->asVector3()));
} }
} }
@ -222,10 +222,10 @@ class Block{
* Do the actions needed so the block is broken with the Item * Do the actions needed so the block is broken with the Item
*/ */
public function onBreak(Item $item, ?Player $player = null) : bool{ public function onBreak(Item $item, ?Player $player = null) : bool{
if(($t = $this->pos->getWorld()->getTile($this->pos)) !== null){ if(($t = $this->pos->getWorldNonNull()->getTile($this->pos)) !== null){
$t->onBlockDestroyed(); $t->onBlockDestroyed();
} }
$this->pos->getWorld()->setBlock($this->pos, VanillaBlocks::AIR()); $this->pos->getWorldNonNull()->setBlock($this->pos, VanillaBlocks::AIR());
return true; return true;
} }
@ -418,7 +418,7 @@ class Block{
public function getPickedItem(bool $addUserData = false) : Item{ public function getPickedItem(bool $addUserData = false) : Item{
$item = $this->asItem(); $item = $this->asItem();
if($addUserData){ if($addUserData){
$tile = $this->pos->getWorld()->getTile($this->pos); $tile = $this->pos->getWorldNonNull()->getTile($this->pos);
if($tile instanceof Tile){ if($tile instanceof Tile){
$nbt = $tile->getCleanedNBT(); $nbt = $tile->getCleanedNBT();
if($nbt instanceof CompoundTag){ if($nbt instanceof CompoundTag){
@ -480,7 +480,7 @@ class Block{
*/ */
public function getSide(int $side, int $step = 1){ public function getSide(int $side, int $step = 1){
if($this->pos->isValid()){ if($this->pos->isValid()){
return $this->pos->getWorld()->getBlock($this->pos->getSide($side, $step)); return $this->pos->getWorldNonNull()->getBlock($this->pos->getSide($side, $step));
} }
throw new \InvalidStateException("Block does not have a valid world"); throw new \InvalidStateException("Block does not have a valid world");

View File

@ -60,7 +60,7 @@ class BrewingStand extends Transparent{
public function onInteract(Item $item, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ public function onInteract(Item $item, int $face, Vector3 $clickVector, ?Player $player = null) : bool{
if($player instanceof Player){ if($player instanceof Player){
$stand = $this->pos->getWorld()->getTile($this->pos); $stand = $this->pos->getWorldNonNull()->getTile($this->pos);
if($stand instanceof TileBrewingStand and $stand->canOpenWith($item->getCustomName())){ if($stand instanceof TileBrewingStand and $stand->canOpenWith($item->getCustomName())){
$player->setCurrentWindow($stand->getInventory()); $player->setCurrentWindow($stand->getInventory());
} }

View File

@ -64,9 +64,9 @@ abstract class Button extends Flowable{
public function onInteract(Item $item, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ public function onInteract(Item $item, int $face, Vector3 $clickVector, ?Player $player = null) : bool{
if(!$this->powered){ if(!$this->powered){
$this->powered = true; $this->powered = true;
$this->pos->getWorld()->setBlock($this->pos, $this); $this->pos->getWorldNonNull()->setBlock($this->pos, $this);
$this->pos->getWorld()->scheduleDelayedBlockUpdate($this->pos, $this->getActivationTime()); $this->pos->getWorldNonNull()->scheduleDelayedBlockUpdate($this->pos, $this->getActivationTime());
$this->pos->getWorld()->addSound($this->pos->add(0.5, 0.5, 0.5), new RedstonePowerOnSound()); $this->pos->getWorldNonNull()->addSound($this->pos->add(0.5, 0.5, 0.5), new RedstonePowerOnSound());
} }
return true; return true;
@ -75,8 +75,8 @@ abstract class Button extends Flowable{
public function onScheduledUpdate() : void{ public function onScheduledUpdate() : void{
if($this->powered){ if($this->powered){
$this->powered = false; $this->powered = false;
$this->pos->getWorld()->setBlock($this->pos, $this); $this->pos->getWorldNonNull()->setBlock($this->pos, $this);
$this->pos->getWorld()->addSound($this->pos->add(0.5, 0.5, 0.5), new RedstonePowerOffSound()); $this->pos->getWorldNonNull()->addSound($this->pos->add(0.5, 0.5, 0.5), new RedstonePowerOffSound());
} }
} }
} }

View File

@ -76,12 +76,12 @@ class Cactus extends Transparent{
public function onNearbyBlockChange() : void{ public function onNearbyBlockChange() : void{
$down = $this->getSide(Facing::DOWN); $down = $this->getSide(Facing::DOWN);
if($down->getId() !== BlockLegacyIds::SAND and !$down->isSameType($this)){ if($down->getId() !== BlockLegacyIds::SAND and !$down->isSameType($this)){
$this->pos->getWorld()->useBreakOn($this->pos); $this->pos->getWorldNonNull()->useBreakOn($this->pos);
}else{ }else{
foreach(Facing::HORIZONTAL as $side){ foreach(Facing::HORIZONTAL as $side){
$b = $this->getSide($side); $b = $this->getSide($side);
if($b->isSolid()){ if($b->isSolid()){
$this->pos->getWorld()->useBreakOn($this->pos); $this->pos->getWorldNonNull()->useBreakOn($this->pos);
break; break;
} }
} }
@ -96,23 +96,23 @@ class Cactus extends Transparent{
if(!$this->getSide(Facing::DOWN)->isSameType($this)){ if(!$this->getSide(Facing::DOWN)->isSameType($this)){
if($this->age === 15){ if($this->age === 15){
for($y = 1; $y < 3; ++$y){ for($y = 1; $y < 3; ++$y){
$b = $this->pos->getWorld()->getBlockAt($this->pos->x, $this->pos->y + $y, $this->pos->z); $b = $this->pos->getWorldNonNull()->getBlockAt($this->pos->x, $this->pos->y + $y, $this->pos->z);
if($b->getId() === BlockLegacyIds::AIR){ if($b->getId() === BlockLegacyIds::AIR){
$ev = new BlockGrowEvent($b, VanillaBlocks::CACTUS()); $ev = new BlockGrowEvent($b, VanillaBlocks::CACTUS());
$ev->call(); $ev->call();
if($ev->isCancelled()){ if($ev->isCancelled()){
break; break;
} }
$this->pos->getWorld()->setBlock($b->pos, $ev->getNewState()); $this->pos->getWorldNonNull()->setBlock($b->pos, $ev->getNewState());
}else{ }else{
break; break;
} }
} }
$this->age = 0; $this->age = 0;
$this->pos->getWorld()->setBlock($this->pos, $this); $this->pos->getWorldNonNull()->setBlock($this->pos, $this);
}else{ }else{
++$this->age; ++$this->age;
$this->pos->getWorld()->setBlock($this->pos, $this); $this->pos->getWorldNonNull()->setBlock($this->pos, $this);
} }
} }
} }

View File

@ -78,7 +78,7 @@ class Cake extends Transparent implements FoodSource{
public function onNearbyBlockChange() : void{ public function onNearbyBlockChange() : void{
if($this->getSide(Facing::DOWN)->getId() === BlockLegacyIds::AIR){ //Replace with common break method if($this->getSide(Facing::DOWN)->getId() === BlockLegacyIds::AIR){ //Replace with common break method
$this->pos->getWorld()->setBlock($this->pos, VanillaBlocks::AIR()); $this->pos->getWorldNonNull()->setBlock($this->pos, VanillaBlocks::AIR());
} }
} }
@ -131,6 +131,6 @@ class Cake extends Transparent implements FoodSource{
} }
public function onConsume(Living $consumer) : void{ public function onConsume(Living $consumer) : void{
$this->pos->getWorld()->setBlock($this->pos, $this->getResidue()); $this->pos->getWorldNonNull()->setBlock($this->pos, $this->getResidue());
} }
} }

View File

@ -58,7 +58,7 @@ class Carpet extends Flowable{
public function onNearbyBlockChange() : void{ public function onNearbyBlockChange() : void{
if($this->getSide(Facing::DOWN)->getId() === BlockLegacyIds::AIR){ if($this->getSide(Facing::DOWN)->getId() === BlockLegacyIds::AIR){
$this->pos->getWorld()->useBreakOn($this->pos); $this->pos->getWorldNonNull()->useBreakOn($this->pos);
} }
} }

View File

@ -70,7 +70,7 @@ class Chest extends Transparent{
} }
public function onPostPlace() : void{ public function onPostPlace() : void{
$tile = $this->pos->getWorld()->getTile($this->pos); $tile = $this->pos->getWorldNonNull()->getTile($this->pos);
if($tile instanceof TileChest){ if($tile instanceof TileChest){
foreach([ foreach([
Facing::rotateY($this->facing, true), Facing::rotateY($this->facing, true),
@ -78,7 +78,7 @@ class Chest extends Transparent{
] as $side){ ] as $side){
$c = $this->getSide($side); $c = $this->getSide($side);
if($c instanceof Chest and $c->isSameType($this) and $c->facing === $this->facing){ if($c instanceof Chest and $c->isSameType($this) and $c->facing === $this->facing){
$pair = $this->pos->getWorld()->getTile($c->pos); $pair = $this->pos->getWorldNonNull()->getTile($c->pos);
if($pair instanceof TileChest and !$pair->isPaired()){ if($pair instanceof TileChest and !$pair->isPaired()){
$pair->pairWith($tile); $pair->pairWith($tile);
$tile->pairWith($pair); $tile->pairWith($pair);
@ -92,7 +92,7 @@ class Chest extends Transparent{
public function onInteract(Item $item, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ public function onInteract(Item $item, int $face, Vector3 $clickVector, ?Player $player = null) : bool{
if($player instanceof Player){ if($player instanceof Player){
$chest = $this->pos->getWorld()->getTile($this->pos); $chest = $this->pos->getWorldNonNull()->getTile($this->pos);
if($chest instanceof TileChest){ if($chest instanceof TileChest){
if( if(
!$this->getSide(Facing::UP)->isTransparent() or !$this->getSide(Facing::UP)->isTransparent() or

View File

@ -34,7 +34,7 @@ class CoarseDirt extends Dirt{
public function onInteract(Item $item, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ public function onInteract(Item $item, int $face, Vector3 $clickVector, ?Player $player = null) : bool{
if($face === Facing::UP and $item instanceof Hoe){ if($face === Facing::UP and $item instanceof Hoe){
$item->applyDamage(1); $item->applyDamage(1);
$this->pos->getWorld()->setBlock($this->pos, VanillaBlocks::DIRT()); $this->pos->getWorldNonNull()->setBlock($this->pos, VanillaBlocks::DIRT());
return true; return true;
} }

View File

@ -89,7 +89,7 @@ class CocoaBlock extends Transparent{
public function onInteract(Item $item, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ public function onInteract(Item $item, int $face, Vector3 $clickVector, ?Player $player = null) : bool{
if($this->age < 2 and $item instanceof Fertilizer){ if($this->age < 2 and $item instanceof Fertilizer){
$this->age++; $this->age++;
$this->pos->getWorld()->setBlock($this->pos, $this); $this->pos->getWorldNonNull()->setBlock($this->pos, $this);
$item->pop(); $item->pop();
@ -102,7 +102,7 @@ class CocoaBlock extends Transparent{
public function onNearbyBlockChange() : void{ public function onNearbyBlockChange() : void{
$side = $this->getSide(Facing::opposite($this->facing)); $side = $this->getSide(Facing::opposite($this->facing));
if(!($side instanceof Wood) or !$side->getTreeType()->equals(TreeType::JUNGLE())){ if(!($side instanceof Wood) or !$side->getTreeType()->equals(TreeType::JUNGLE())){
$this->pos->getWorld()->useBreakOn($this->pos); $this->pos->getWorldNonNull()->useBreakOn($this->pos);
} }
} }
@ -113,7 +113,7 @@ class CocoaBlock extends Transparent{
public function onRandomTick() : void{ public function onRandomTick() : void{
if($this->age < 2 and mt_rand(1, 5) === 1){ if($this->age < 2 and mt_rand(1, 5) === 1){
$this->age++; $this->age++;
$this->pos->getWorld()->setBlock($this->pos, $this); $this->pos->getWorldNonNull()->setBlock($this->pos, $this);
} }
} }

View File

@ -38,7 +38,7 @@ class ConcretePowder extends Opaque implements Fallable{
public function onNearbyBlockChange() : void{ public function onNearbyBlockChange() : void{
if(($block = $this->checkAdjacentWater()) !== null){ if(($block = $this->checkAdjacentWater()) !== null){
$this->pos->getWorld()->setBlock($this->pos, $block); $this->pos->getWorldNonNull()->setBlock($this->pos, $block);
}else{ }else{
$this->startFalling(); $this->startFalling();
} }

View File

@ -72,7 +72,7 @@ abstract class Crops extends Flowable{
$ev = new BlockGrowEvent($this, $block); $ev = new BlockGrowEvent($this, $block);
$ev->call(); $ev->call();
if(!$ev->isCancelled()){ if(!$ev->isCancelled()){
$this->pos->getWorld()->setBlock($this->pos, $ev->getNewState()); $this->pos->getWorldNonNull()->setBlock($this->pos, $ev->getNewState());
} }
$item->pop(); $item->pop();
@ -85,7 +85,7 @@ abstract class Crops extends Flowable{
public function onNearbyBlockChange() : void{ public function onNearbyBlockChange() : void{
if($this->getSide(Facing::DOWN)->getId() !== BlockLegacyIds::FARMLAND){ if($this->getSide(Facing::DOWN)->getId() !== BlockLegacyIds::FARMLAND){
$this->pos->getWorld()->useBreakOn($this->pos); $this->pos->getWorldNonNull()->useBreakOn($this->pos);
} }
} }
@ -100,7 +100,7 @@ abstract class Crops extends Flowable{
$ev = new BlockGrowEvent($this, $block); $ev = new BlockGrowEvent($this, $block);
$ev->call(); $ev->call();
if(!$ev->isCancelled()){ if(!$ev->isCancelled()){
$this->pos->getWorld()->setBlock($this->pos, $ev->getNewState()); $this->pos->getWorldNonNull()->setBlock($this->pos, $ev->getNewState());
} }
} }
} }

View File

@ -91,7 +91,7 @@ class DaylightSensor extends Transparent{
public function onInteract(Item $item, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ public function onInteract(Item $item, int $face, Vector3 $clickVector, ?Player $player = null) : bool{
$this->inverted = !$this->inverted; $this->inverted = !$this->inverted;
$this->power = $this->recalculatePower(); $this->power = $this->recalculatePower();
$this->pos->getWorld()->setBlock($this->pos, $this); $this->pos->getWorldNonNull()->setBlock($this->pos, $this);
return true; return true;
} }
@ -99,18 +99,18 @@ class DaylightSensor extends Transparent{
$newPower = $this->recalculatePower(); $newPower = $this->recalculatePower();
if($this->power !== $newPower){ if($this->power !== $newPower){
$this->power = $newPower; $this->power = $newPower;
$this->pos->getWorld()->setBlock($this->pos, $this); $this->pos->getWorldNonNull()->setBlock($this->pos, $this);
} }
$this->pos->getWorld()->scheduleDelayedBlockUpdate($this->pos, 20); $this->pos->getWorldNonNull()->scheduleDelayedBlockUpdate($this->pos, 20);
} }
private function recalculatePower() : int{ private function recalculatePower() : int{
$lightLevel = $this->pos->getWorld()->getRealBlockSkyLightAt($this->pos->x, $this->pos->y, $this->pos->z); $lightLevel = $this->pos->getWorldNonNull()->getRealBlockSkyLightAt($this->pos->x, $this->pos->y, $this->pos->z);
if($this->inverted){ if($this->inverted){
return 15 - $lightLevel; return 15 - $lightLevel;
} }
$sunAngle = $this->pos->getWorld()->getSunAnglePercentage(); $sunAngle = $this->pos->getWorldNonNull()->getSunAnglePercentage();
return max(0, (int) round($lightLevel * cos(($sunAngle + ((($sunAngle < 0.5 ? 0 : 1) - $sunAngle) / 5)) * 2 * M_PI))); return max(0, (int) round($lightLevel * cos(($sunAngle + ((($sunAngle < 0.5 ? 0 : 1) - $sunAngle) / 5)) * 2 * M_PI)));
} }

View File

@ -47,7 +47,7 @@ class DeadBush extends Flowable{
public function onNearbyBlockChange() : void{ public function onNearbyBlockChange() : void{
if($this->getSide(Facing::DOWN)->isTransparent()){ if($this->getSide(Facing::DOWN)->isTransparent()){
$this->pos->getWorld()->useBreakOn($this->pos); $this->pos->getWorldNonNull()->useBreakOn($this->pos);
} }
} }

View File

@ -38,7 +38,7 @@ class Dirt extends Opaque{
public function onInteract(Item $item, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ public function onInteract(Item $item, int $face, Vector3 $clickVector, ?Player $player = null) : bool{
if($face === Facing::UP and $item instanceof Hoe){ if($face === Facing::UP and $item instanceof Hoe){
$item->applyDamage(1); $item->applyDamage(1);
$this->pos->getWorld()->setBlock($this->pos, VanillaBlocks::FARMLAND()); $this->pos->getWorldNonNull()->setBlock($this->pos, VanillaBlocks::FARMLAND());
return true; return true;
} }

View File

@ -99,7 +99,7 @@ class Door extends Transparent{
public function onNearbyBlockChange() : void{ public function onNearbyBlockChange() : void{
if($this->getSide(Facing::DOWN)->getId() === BlockLegacyIds::AIR){ //Replace with common break method if($this->getSide(Facing::DOWN)->getId() === BlockLegacyIds::AIR){ //Replace with common break method
$this->pos->getWorld()->useBreakOn($this->pos); //this will delete both halves if they exist $this->pos->getWorldNonNull()->useBreakOn($this->pos); //this will delete both halves if they exist
} }
} }
@ -138,11 +138,11 @@ class Door extends Transparent{
$other = $this->getSide($this->top ? Facing::DOWN : Facing::UP); $other = $this->getSide($this->top ? Facing::DOWN : Facing::UP);
if($other instanceof Door and $other->isSameType($this)){ if($other instanceof Door and $other->isSameType($this)){
$other->open = $this->open; $other->open = $this->open;
$this->pos->getWorld()->setBlock($other->pos, $other); $this->pos->getWorldNonNull()->setBlock($other->pos, $other);
} }
$this->pos->getWorld()->setBlock($this->pos, $this); $this->pos->getWorldNonNull()->setBlock($this->pos, $this);
$this->pos->getWorld()->addSound($this->pos, new DoorSound()); $this->pos->getWorldNonNull()->addSound($this->pos, new DoorSound());
return true; return true;
} }

View File

@ -77,7 +77,7 @@ class DoublePlant extends Flowable{
public function onNearbyBlockChange() : void{ public function onNearbyBlockChange() : void{
if(!$this->isValidHalfPlant() or (!$this->top and $this->getSide(Facing::DOWN)->isTransparent())){ if(!$this->isValidHalfPlant() or (!$this->top and $this->getSide(Facing::DOWN)->isTransparent())){
$this->pos->getWorld()->useBreakOn($this->pos); $this->pos->getWorldNonNull()->useBreakOn($this->pos);
} }
} }

View File

@ -63,7 +63,7 @@ class DragonEgg extends Transparent implements Fallable{
public function teleport() : void{ public function teleport() : void{
for($tries = 0; $tries < 16; ++$tries){ for($tries = 0; $tries < 16; ++$tries){
$block = $this->pos->getWorld()->getBlockAt( $block = $this->pos->getWorldNonNull()->getBlockAt(
$this->pos->x + mt_rand(-16, 16), $this->pos->x + mt_rand(-16, 16),
max(0, min(World::Y_MAX - 1, $this->pos->y + mt_rand(-8, 8))), max(0, min(World::Y_MAX - 1, $this->pos->y + mt_rand(-8, 8))),
$this->pos->z + mt_rand(-16, 16) $this->pos->z + mt_rand(-16, 16)
@ -76,9 +76,9 @@ class DragonEgg extends Transparent implements Fallable{
} }
$blockPos = $ev->getTo(); $blockPos = $ev->getTo();
$this->pos->getWorld()->addParticle($this->pos, new DragonEggTeleportParticle($this->pos->x - $blockPos->x, $this->pos->y - $blockPos->y, $this->pos->z - $blockPos->z)); $this->pos->getWorldNonNull()->addParticle($this->pos, new DragonEggTeleportParticle($this->pos->x - $blockPos->x, $this->pos->y - $blockPos->y, $this->pos->z - $blockPos->z));
$this->pos->getWorld()->setBlock($this->pos, VanillaBlocks::AIR()); $this->pos->getWorldNonNull()->setBlock($this->pos, VanillaBlocks::AIR());
$this->pos->getWorld()->setBlock($blockPos, $this); $this->pos->getWorldNonNull()->setBlock($blockPos, $this);
break; break;
} }
} }

View File

@ -75,7 +75,7 @@ class EnderChest extends Transparent{
public function onInteract(Item $item, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ public function onInteract(Item $item, int $face, Vector3 $clickVector, ?Player $player = null) : bool{
if($player instanceof Player){ if($player instanceof Player){
$enderChest = $this->pos->getWorld()->getTile($this->pos); $enderChest = $this->pos->getWorldNonNull()->getTile($this->pos);
if($enderChest instanceof TileEnderChest and $this->getSide(Facing::UP)->isTransparent()){ if($enderChest instanceof TileEnderChest and $this->getSide(Facing::UP)->isTransparent()){
$player->getEnderChestInventory()->setHolderPosition($this->pos); $player->getEnderChestInventory()->setHolderPosition($this->pos);
$player->setCurrentWindow($player->getEnderChestInventory()); $player->setCurrentWindow($player->getEnderChestInventory());

View File

@ -58,7 +58,7 @@ class Farmland extends Transparent{
public function onNearbyBlockChange() : void{ public function onNearbyBlockChange() : void{
if($this->getSide(Facing::UP)->isSolid()){ if($this->getSide(Facing::UP)->isSolid()){
$this->pos->getWorld()->setBlock($this->pos, VanillaBlocks::DIRT()); $this->pos->getWorldNonNull()->setBlock($this->pos, VanillaBlocks::DIRT());
} }
} }
@ -70,13 +70,13 @@ class Farmland extends Transparent{
if(!$this->canHydrate()){ if(!$this->canHydrate()){
if($this->wetness > 0){ if($this->wetness > 0){
$this->wetness--; $this->wetness--;
$this->pos->getWorld()->setBlock($this->pos, $this, false); $this->pos->getWorldNonNull()->setBlock($this->pos, $this, false);
}else{ }else{
$this->pos->getWorld()->setBlock($this->pos, VanillaBlocks::DIRT()); $this->pos->getWorldNonNull()->setBlock($this->pos, VanillaBlocks::DIRT());
} }
}elseif($this->wetness < 7){ }elseif($this->wetness < 7){
$this->wetness = 7; $this->wetness = 7;
$this->pos->getWorld()->setBlock($this->pos, $this, false); $this->pos->getWorldNonNull()->setBlock($this->pos, $this, false);
} }
} }
@ -87,7 +87,7 @@ class Farmland extends Transparent{
for($y = $start->y; $y <= $end->y; ++$y){ for($y = $start->y; $y <= $end->y; ++$y){
for($z = $start->z; $z <= $end->z; ++$z){ for($z = $start->z; $z <= $end->z; ++$z){
for($x = $start->x; $x <= $end->x; ++$x){ for($x = $start->x; $x <= $end->x; ++$x){
if($this->pos->getWorld()->getBlockAt($x, $y, $z) instanceof Water){ if($this->pos->getWorldNonNull()->getBlockAt($x, $y, $z) instanceof Water){
return true; return true;
} }
} }

View File

@ -88,7 +88,7 @@ class FenceGate extends Transparent{
$inWall = $this->checkInWall(); $inWall = $this->checkInWall();
if($inWall !== $this->inWall){ if($inWall !== $this->inWall){
$this->inWall = $inWall; $this->inWall = $inWall;
$this->pos->getWorld()->setBlock($this->pos, $this); $this->pos->getWorldNonNull()->setBlock($this->pos, $this);
} }
} }
@ -101,8 +101,8 @@ class FenceGate extends Transparent{
} }
} }
$this->pos->getWorld()->setBlock($this->pos, $this); $this->pos->getWorldNonNull()->setBlock($this->pos, $this);
$this->pos->getWorld()->addSound($this->pos, new DoorSound()); $this->pos->getWorldNonNull()->addSound($this->pos, new DoorSound());
return true; return true;
} }

View File

@ -88,9 +88,9 @@ class Fire extends Flowable{
public function onNearbyBlockChange() : void{ public function onNearbyBlockChange() : void{
if(!$this->getSide(Facing::DOWN)->isSolid() and !$this->hasAdjacentFlammableBlocks()){ if(!$this->getSide(Facing::DOWN)->isSolid() and !$this->hasAdjacentFlammableBlocks()){
$this->pos->getWorld()->setBlock($this->pos, VanillaBlocks::AIR()); $this->pos->getWorldNonNull()->setBlock($this->pos, VanillaBlocks::AIR());
}else{ }else{
$this->pos->getWorld()->scheduleDelayedBlockUpdate($this->pos, mt_rand(30, 40)); $this->pos->getWorldNonNull()->scheduleDelayedBlockUpdate($this->pos, mt_rand(30, 40));
} }
} }
@ -124,10 +124,10 @@ class Fire extends Flowable{
} }
if($result !== null){ if($result !== null){
$this->pos->getWorld()->setBlock($this->pos, $result); $this->pos->getWorldNonNull()->setBlock($this->pos, $result);
} }
$this->pos->getWorld()->scheduleDelayedBlockUpdate($this->pos, mt_rand(30, 40)); $this->pos->getWorldNonNull()->scheduleDelayedBlockUpdate($this->pos, mt_rand(30, 40));
if($canSpread){ if($canSpread){
//TODO: raise upper bound for chance in humid biomes //TODO: raise upper bound for chance in humid biomes
@ -168,9 +168,9 @@ class Fire extends Flowable{
if(mt_rand(0, $this->age + 9) < 5){ //TODO: check rain if(mt_rand(0, $this->age + 9) < 5){ //TODO: check rain
$fire = clone $this; $fire = clone $this;
$fire->age = min(15, $fire->age + (mt_rand(0, 4) >> 2)); $fire->age = min(15, $fire->age + (mt_rand(0, 4) >> 2));
$this->pos->getWorld()->setBlock($block->pos, $fire); $this->pos->getWorldNonNull()->setBlock($block->pos, $fire);
}else{ }else{
$this->pos->getWorld()->setBlock($block->pos, VanillaBlocks::AIR()); $this->pos->getWorldNonNull()->setBlock($block->pos, VanillaBlocks::AIR());
} }
} }
} }

View File

@ -46,7 +46,7 @@ class Flower extends Flowable{
public function onNearbyBlockChange() : void{ public function onNearbyBlockChange() : void{
if($this->getSide(Facing::DOWN)->isTransparent()){ if($this->getSide(Facing::DOWN)->isTransparent()){
$this->pos->getWorld()->useBreakOn($this->pos); $this->pos->getWorldNonNull()->useBreakOn($this->pos);
} }
} }

View File

@ -61,7 +61,7 @@ class FlowerPot extends Flowable{
public function readStateFromWorld() : void{ public function readStateFromWorld() : void{
parent::readStateFromWorld(); parent::readStateFromWorld();
$tile = $this->pos->getWorld()->getTile($this->pos); $tile = $this->pos->getWorldNonNull()->getTile($this->pos);
if($tile instanceof TileFlowerPot){ if($tile instanceof TileFlowerPot){
$this->setPlant($tile->getPlant()); $this->setPlant($tile->getPlant());
}else{ }else{
@ -72,7 +72,7 @@ class FlowerPot extends Flowable{
public function writeStateToWorld() : void{ public function writeStateToWorld() : void{
parent::writeStateToWorld(); parent::writeStateToWorld();
$tile = $this->pos->getWorld()->getTile($this->pos); $tile = $this->pos->getWorldNonNull()->getTile($this->pos);
assert($tile instanceof TileFlowerPot); assert($tile instanceof TileFlowerPot);
$tile->setPlant($this->plant); $tile->setPlant($this->plant);
} }
@ -122,7 +122,7 @@ class FlowerPot extends Flowable{
public function onNearbyBlockChange() : void{ public function onNearbyBlockChange() : void{
if($this->getSide(Facing::DOWN)->isTransparent()){ if($this->getSide(Facing::DOWN)->isTransparent()){
$this->pos->getWorld()->useBreakOn($this->pos); $this->pos->getWorldNonNull()->useBreakOn($this->pos);
} }
} }
@ -134,7 +134,7 @@ class FlowerPot extends Flowable{
$this->setPlant($plant); $this->setPlant($plant);
$item->pop(); $item->pop();
$this->pos->getWorld()->setBlock($this->pos, $this); $this->pos->getWorldNonNull()->setBlock($this->pos, $this);
return true; return true;
} }

View File

@ -50,17 +50,17 @@ class FrostedIce extends Ice{
public function onNearbyBlockChange() : void{ public function onNearbyBlockChange() : void{
if(!$this->checkAdjacentBlocks(2)){ if(!$this->checkAdjacentBlocks(2)){
$this->pos->getWorld()->useBreakOn($this->pos); $this->pos->getWorldNonNull()->useBreakOn($this->pos);
}else{ }else{
$this->pos->getWorld()->scheduleDelayedBlockUpdate($this->pos, mt_rand(20, 40)); $this->pos->getWorldNonNull()->scheduleDelayedBlockUpdate($this->pos, mt_rand(20, 40));
} }
} }
public function onRandomTick() : void{ public function onRandomTick() : void{
if((!$this->checkAdjacentBlocks(4) or mt_rand(0, 2) === 0) and if((!$this->checkAdjacentBlocks(4) or mt_rand(0, 2) === 0) and
max( //TODO: move this to World max( //TODO: move this to World
$this->pos->getWorld()->getHighestAdjacentBlockLight($this->pos->x, $this->pos->y, $this->pos->z), $this->pos->getWorldNonNull()->getHighestAdjacentBlockLight($this->pos->x, $this->pos->y, $this->pos->z),
$this->pos->getWorld()->getHighestAdjacentBlockSkyLight($this->pos->x, $this->pos->y, $this->pos->z) - $this->pos->getWorld()->getSkyLightReduction() $this->pos->getWorldNonNull()->getHighestAdjacentBlockSkyLight($this->pos->x, $this->pos->y, $this->pos->z) - $this->pos->getWorldNonNull()->getSkyLightReduction()
) >= 12 - $this->age){ ) >= 12 - $this->age){
if($this->tryMelt()){ if($this->tryMelt()){
foreach($this->getAllSides() as $block){ foreach($this->getAllSides() as $block){
@ -70,7 +70,7 @@ class FrostedIce extends Ice{
} }
} }
}else{ }else{
$this->pos->getWorld()->scheduleDelayedBlockUpdate($this->pos, mt_rand(20, 40)); $this->pos->getWorldNonNull()->scheduleDelayedBlockUpdate($this->pos, mt_rand(20, 40));
} }
} }
@ -86,7 +86,7 @@ class FrostedIce extends Ice{
continue; continue;
} }
if( if(
$this->pos->getWorld()->getBlockAt($this->pos->x + $x, $this->pos->y, $this->pos->z + $z) instanceof FrostedIce and $this->pos->getWorldNonNull()->getBlockAt($this->pos->x + $x, $this->pos->y, $this->pos->z + $z) instanceof FrostedIce and
++$found >= $requirement ++$found >= $requirement
){ ){
return true; return true;
@ -103,13 +103,13 @@ class FrostedIce extends Ice{
*/ */
private function tryMelt() : bool{ private function tryMelt() : bool{
if($this->age >= 3){ if($this->age >= 3){
$this->pos->getWorld()->useBreakOn($this->pos); $this->pos->getWorldNonNull()->useBreakOn($this->pos);
return true; return true;
} }
$this->age++; $this->age++;
$this->pos->getWorld()->setBlock($this->pos, $this); $this->pos->getWorldNonNull()->setBlock($this->pos, $this);
$this->pos->getWorld()->scheduleDelayedBlockUpdate($this->pos, mt_rand(20, 40)); $this->pos->getWorldNonNull()->scheduleDelayedBlockUpdate($this->pos, mt_rand(20, 40));
return false; return false;
} }
} }

View File

@ -88,7 +88,7 @@ class Furnace extends Opaque{
public function onInteract(Item $item, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ public function onInteract(Item $item, int $face, Vector3 $clickVector, ?Player $player = null) : bool{
if($player instanceof Player){ if($player instanceof Player){
$furnace = $this->pos->getWorld()->getTile($this->pos); $furnace = $this->pos->getWorldNonNull()->getTile($this->pos);
if($furnace instanceof TileFurnace and $furnace->canOpenWith($item->getCustomName())){ if($furnace instanceof TileFurnace and $furnace->canOpenWith($item->getCustomName())){
$player->setCurrentWindow($furnace->getInventory()); $player->setCurrentWindow($furnace->getInventory());
} }
@ -98,9 +98,9 @@ class Furnace extends Opaque{
} }
public function onScheduledUpdate() : void{ public function onScheduledUpdate() : void{
$furnace = $this->pos->getWorld()->getTile($this->pos); $furnace = $this->pos->getWorldNonNull()->getTile($this->pos);
if($furnace instanceof TileFurnace and $furnace->onUpdate()){ if($furnace instanceof TileFurnace and $furnace->onUpdate()){
$this->pos->getWorld()->scheduleDelayedBlockUpdate($this->pos, 1); //TODO: check this $this->pos->getWorldNonNull()->scheduleDelayedBlockUpdate($this->pos, 1); //TODO: check this
} }
} }
} }

View File

@ -52,13 +52,13 @@ class Grass extends Opaque{
} }
public function onRandomTick() : void{ public function onRandomTick() : void{
$lightAbove = $this->pos->getWorld()->getFullLightAt($this->pos->x, $this->pos->y + 1, $this->pos->z); $lightAbove = $this->pos->getWorldNonNull()->getFullLightAt($this->pos->x, $this->pos->y + 1, $this->pos->z);
if($lightAbove < 4 and $this->pos->getWorld()->getBlockAt($this->pos->x, $this->pos->y + 1, $this->pos->z)->getLightFilter() >= 2){ if($lightAbove < 4 and $this->pos->getWorldNonNull()->getBlockAt($this->pos->x, $this->pos->y + 1, $this->pos->z)->getLightFilter() >= 2){
//grass dies //grass dies
$ev = new BlockSpreadEvent($this, $this, VanillaBlocks::DIRT()); $ev = new BlockSpreadEvent($this, $this, VanillaBlocks::DIRT());
$ev->call(); $ev->call();
if(!$ev->isCancelled()){ if(!$ev->isCancelled()){
$this->pos->getWorld()->setBlock($this->pos, $ev->getNewState(), false); $this->pos->getWorldNonNull()->setBlock($this->pos, $ev->getNewState(), false);
} }
}elseif($lightAbove >= 9){ }elseif($lightAbove >= 9){
//try grass spread //try grass spread
@ -67,12 +67,12 @@ class Grass extends Opaque{
$y = mt_rand($this->pos->y - 3, $this->pos->y + 1); $y = mt_rand($this->pos->y - 3, $this->pos->y + 1);
$z = mt_rand($this->pos->z - 1, $this->pos->z + 1); $z = mt_rand($this->pos->z - 1, $this->pos->z + 1);
$b = $this->pos->getWorld()->getBlockAt($x, $y, $z); $b = $this->pos->getWorldNonNull()->getBlockAt($x, $y, $z);
if( if(
!($b instanceof Dirt) or !($b instanceof Dirt) or
$b instanceof CoarseDirt or $b instanceof CoarseDirt or
$this->pos->getWorld()->getFullLightAt($x, $y + 1, $z) < 4 or $this->pos->getWorldNonNull()->getFullLightAt($x, $y + 1, $z) < 4 or
$this->pos->getWorld()->getBlockAt($x, $y + 1, $z)->getLightFilter() >= 2 $this->pos->getWorldNonNull()->getBlockAt($x, $y + 1, $z)->getLightFilter() >= 2
){ ){
continue; continue;
} }
@ -80,7 +80,7 @@ class Grass extends Opaque{
$ev = new BlockSpreadEvent($b, $this, VanillaBlocks::GRASS()); $ev = new BlockSpreadEvent($b, $this, VanillaBlocks::GRASS());
$ev->call(); $ev->call();
if(!$ev->isCancelled()){ if(!$ev->isCancelled()){
$this->pos->getWorld()->setBlock($b->pos, $ev->getNewState(), false); $this->pos->getWorldNonNull()->setBlock($b->pos, $ev->getNewState(), false);
} }
} }
} }
@ -92,17 +92,17 @@ class Grass extends Opaque{
} }
if($item instanceof Fertilizer){ if($item instanceof Fertilizer){
$item->pop(); $item->pop();
TallGrassObject::growGrass($this->pos->getWorld(), $this->pos, new Random(mt_rand()), 8, 2); TallGrassObject::growGrass($this->pos->getWorldNonNull(), $this->pos, new Random(mt_rand()), 8, 2);
return true; return true;
}elseif($item instanceof Hoe){ }elseif($item instanceof Hoe){
$item->applyDamage(1); $item->applyDamage(1);
$this->pos->getWorld()->setBlock($this->pos, VanillaBlocks::FARMLAND()); $this->pos->getWorldNonNull()->setBlock($this->pos, VanillaBlocks::FARMLAND());
return true; return true;
}elseif($item instanceof Shovel and $this->getSide(Facing::UP)->getId() === BlockLegacyIds::AIR){ }elseif($item instanceof Shovel and $this->getSide(Facing::UP)->getId() === BlockLegacyIds::AIR){
$item->applyDamage(1); $item->applyDamage(1);
$this->pos->getWorld()->setBlock($this->pos, VanillaBlocks::GRASS_PATH()); $this->pos->getWorldNonNull()->setBlock($this->pos, VanillaBlocks::GRASS_PATH());
return true; return true;
} }

View File

@ -42,7 +42,7 @@ class GrassPath extends Transparent{
public function onNearbyBlockChange() : void{ public function onNearbyBlockChange() : void{
if($this->getSide(Facing::UP)->isSolid()){ if($this->getSide(Facing::UP)->isSolid()){
$this->pos->getWorld()->setBlock($this->pos, VanillaBlocks::DIRT()); $this->pos->getWorldNonNull()->setBlock($this->pos, VanillaBlocks::DIRT());
} }
} }

View File

@ -76,7 +76,7 @@ class Hopper extends Transparent{
public function onInteract(Item $item, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ public function onInteract(Item $item, int $face, Vector3 $clickVector, ?Player $player = null) : bool{
if($player !== null){ if($player !== null){
$tile = $this->pos->getWorld()->getTile($this->pos); $tile = $this->pos->getWorldNonNull()->getTile($this->pos);
if($tile instanceof TileHopper){ //TODO: find a way to have inventories open on click without this boilerplate in every block if($tile instanceof TileHopper){ //TODO: find a way to have inventories open on click without this boilerplate in every block
$player->setCurrentWindow($tile->getInventory()); $player->setCurrentWindow($tile->getInventory());
} }

View File

@ -43,7 +43,7 @@ class Ice extends Transparent{
public function onBreak(Item $item, ?Player $player = null) : bool{ public function onBreak(Item $item, ?Player $player = null) : bool{
if(($player === null or $player->isSurvival()) and !$item->hasEnchantment(Enchantment::SILK_TOUCH())){ if(($player === null or $player->isSurvival()) and !$item->hasEnchantment(Enchantment::SILK_TOUCH())){
$this->pos->getWorld()->setBlock($this->pos, VanillaBlocks::WATER()); $this->pos->getWorldNonNull()->setBlock($this->pos, VanillaBlocks::WATER());
return true; return true;
} }
return parent::onBreak($item, $player); return parent::onBreak($item, $player);
@ -54,8 +54,8 @@ class Ice extends Transparent{
} }
public function onRandomTick() : void{ public function onRandomTick() : void{
if($this->pos->getWorld()->getHighestAdjacentBlockLight($this->pos->x, $this->pos->y, $this->pos->z) >= 12){ if($this->pos->getWorldNonNull()->getHighestAdjacentBlockLight($this->pos->x, $this->pos->y, $this->pos->z) >= 12){
$this->pos->getWorld()->useBreakOn($this->pos); $this->pos->getWorldNonNull()->useBreakOn($this->pos);
} }
} }

View File

@ -61,7 +61,7 @@ class ItemFrame extends Flowable{
public function readStateFromWorld() : void{ public function readStateFromWorld() : void{
parent::readStateFromWorld(); parent::readStateFromWorld();
$tile = $this->pos->getWorld()->getTile($this->pos); $tile = $this->pos->getWorldNonNull()->getTile($this->pos);
if($tile instanceof TileItemFrame){ if($tile instanceof TileItemFrame){
$this->framedItem = $tile->getItem(); $this->framedItem = $tile->getItem();
if($this->framedItem->isNull()){ if($this->framedItem->isNull()){
@ -74,7 +74,7 @@ class ItemFrame extends Flowable{
public function writeStateToWorld() : void{ public function writeStateToWorld() : void{
parent::writeStateToWorld(); parent::writeStateToWorld();
$tile = $this->pos->getWorld()->getTile($this->pos); $tile = $this->pos->getWorldNonNull()->getTile($this->pos);
if($tile instanceof TileItemFrame){ if($tile instanceof TileItemFrame){
$tile->setItem($this->framedItem); $tile->setItem($this->framedItem);
$tile->setItemRotation($this->itemRotation); $tile->setItemRotation($this->itemRotation);
@ -132,7 +132,7 @@ class ItemFrame extends Flowable{
return true; return true;
} }
$this->pos->getWorld()->setBlock($this->pos, $this); $this->pos->getWorldNonNull()->setBlock($this->pos, $this);
return true; return true;
} }
@ -142,16 +142,16 @@ class ItemFrame extends Flowable{
return false; return false;
} }
if(lcg_value() <= $this->itemDropChance){ if(lcg_value() <= $this->itemDropChance){
$this->pos->getWorld()->dropItem($this->pos->add(0.5, 0.5, 0.5), $this->getFramedItem()); $this->pos->getWorldNonNull()->dropItem($this->pos->add(0.5, 0.5, 0.5), $this->getFramedItem());
} }
$this->setFramedItem(null); $this->setFramedItem(null);
$this->pos->getWorld()->setBlock($this->pos, $this); $this->pos->getWorldNonNull()->setBlock($this->pos, $this);
return true; return true;
} }
public function onNearbyBlockChange() : void{ public function onNearbyBlockChange() : void{
if(!$this->getSide(Facing::opposite($this->facing))->isSolid()){ if(!$this->getSide(Facing::opposite($this->facing))->isSolid()){
$this->pos->getWorld()->useBreakOn($this->pos); $this->pos->getWorldNonNull()->useBreakOn($this->pos);
} }
} }

View File

@ -90,7 +90,7 @@ class Ladder extends Transparent{
public function onNearbyBlockChange() : void{ public function onNearbyBlockChange() : void{
if(!$this->getSide(Facing::opposite($this->facing))->isSolid()){ //Replace with common break method if(!$this->getSide(Facing::opposite($this->facing))->isSolid()){ //Replace with common break method
$this->pos->getWorld()->useBreakOn($this->pos); $this->pos->getWorldNonNull()->useBreakOn($this->pos);
} }
} }
} }

View File

@ -69,17 +69,17 @@ class Lantern extends Transparent{
} }
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(!$this->canAttachTo($this->pos->getWorld()->getBlock($blockReplace->getPos()->up())) and !$this->canAttachTo($this->pos->getWorld()->getBlock($blockReplace->getPos()->down()))){ if(!$this->canAttachTo($this->pos->getWorldNonNull()->getBlock($blockReplace->getPos()->up())) and !$this->canAttachTo($this->pos->getWorldNonNull()->getBlock($blockReplace->getPos()->down()))){
return false; return false;
} }
$this->hanging = ($face === Facing::DOWN or !$this->canAttachTo($this->pos->getWorld()->getBlock($blockReplace->getPos()->down()))); $this->hanging = ($face === Facing::DOWN or !$this->canAttachTo($this->pos->getWorldNonNull()->getBlock($blockReplace->getPos()->down())));
return parent::place($tx, $item, $blockReplace, $blockClicked, $face, $clickVector, $player); return parent::place($tx, $item, $blockReplace, $blockClicked, $face, $clickVector, $player);
} }
public function onNearbyBlockChange() : void{ public function onNearbyBlockChange() : void{
if(!$this->canAttachTo($this->pos->getWorld()->getBlock($this->hanging ? $this->pos->up() : $this->pos->down()))){ if(!$this->canAttachTo($this->pos->getWorldNonNull()->getBlock($this->hanging ? $this->pos->up() : $this->pos->down()))){
$this->pos->getWorld()->useBreakOn($this->pos); $this->pos->getWorldNonNull()->useBreakOn($this->pos);
} }
} }
} }

View File

@ -78,7 +78,7 @@ class Leaves extends Transparent{
} }
$visited[$index] = true; $visited[$index] = true;
$block = $this->pos->getWorld()->getBlock($pos); $block = $this->pos->getWorldNonNull()->getBlock($pos);
if($block instanceof Wood){ //type doesn't matter if($block instanceof Wood){ //type doesn't matter
return true; return true;
} }
@ -97,7 +97,7 @@ class Leaves extends Transparent{
public function onNearbyBlockChange() : void{ public function onNearbyBlockChange() : void{
if(!$this->noDecay and !$this->checkDecay){ if(!$this->noDecay and !$this->checkDecay){
$this->checkDecay = true; $this->checkDecay = true;
$this->pos->getWorld()->setBlock($this->pos, $this, false); $this->pos->getWorldNonNull()->setBlock($this->pos, $this, false);
} }
} }
@ -111,9 +111,9 @@ class Leaves extends Transparent{
$ev->call(); $ev->call();
if($ev->isCancelled() or $this->findLog($this->pos)){ if($ev->isCancelled() or $this->findLog($this->pos)){
$this->checkDecay = false; $this->checkDecay = false;
$this->pos->getWorld()->setBlock($this->pos, $this, false); $this->pos->getWorldNonNull()->setBlock($this->pos, $this, false);
}else{ }else{
$this->pos->getWorld()->useBreakOn($this->pos); $this->pos->getWorldNonNull()->useBreakOn($this->pos);
} }
} }
} }

View File

@ -107,14 +107,14 @@ class Lever extends Flowable{
} }
if(!$this->getSide($face)->isSolid()){ if(!$this->getSide($face)->isSolid()){
$this->pos->getWorld()->useBreakOn($this->pos); $this->pos->getWorldNonNull()->useBreakOn($this->pos);
} }
} }
public function onInteract(Item $item, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ public function onInteract(Item $item, int $face, Vector3 $clickVector, ?Player $player = null) : bool{
$this->powered = !$this->powered; $this->powered = !$this->powered;
$this->pos->getWorld()->setBlock($this->pos, $this); $this->pos->getWorldNonNull()->setBlock($this->pos, $this);
$this->pos->getWorld()->addSound( $this->pos->getWorldNonNull()->addSound(
$this->pos->add(0.5, 0.5, 0.5), $this->pos->add(0.5, 0.5, 0.5),
$this->powered ? new RedstonePowerOnSound() : new RedstonePowerOffSound() $this->powered ? new RedstonePowerOnSound() : new RedstonePowerOffSound()
); );

View File

@ -188,7 +188,7 @@ abstract class Liquid extends Transparent{
++$z; ++$z;
} }
$sideBlock = $this->pos->getWorld()->getBlockAt($x, $y, $z); $sideBlock = $this->pos->getWorldNonNull()->getBlockAt($x, $y, $z);
$blockDecay = $this->getEffectiveFlowDecay($sideBlock); $blockDecay = $this->getEffectiveFlowDecay($sideBlock);
if($blockDecay < 0){ if($blockDecay < 0){
@ -196,7 +196,7 @@ abstract class Liquid extends Transparent{
continue; continue;
} }
$blockDecay = $this->getEffectiveFlowDecay($this->pos->getWorld()->getBlockAt($x, $y - 1, $z)); $blockDecay = $this->getEffectiveFlowDecay($this->pos->getWorldNonNull()->getBlockAt($x, $y - 1, $z));
if($blockDecay >= 0){ if($blockDecay >= 0){
$realDecay = $blockDecay - ($decay - 8); $realDecay = $blockDecay - ($decay - 8);
@ -216,14 +216,14 @@ abstract class Liquid extends Transparent{
if($this->falling){ if($this->falling){
if( if(
!$this->canFlowInto($this->pos->getWorld()->getBlockAt($this->pos->x, $this->pos->y, $this->pos->z - 1)) or !$this->canFlowInto($this->pos->getWorldNonNull()->getBlockAt($this->pos->x, $this->pos->y, $this->pos->z - 1)) or
!$this->canFlowInto($this->pos->getWorld()->getBlockAt($this->pos->x, $this->pos->y, $this->pos->z + 1)) or !$this->canFlowInto($this->pos->getWorldNonNull()->getBlockAt($this->pos->x, $this->pos->y, $this->pos->z + 1)) or
!$this->canFlowInto($this->pos->getWorld()->getBlockAt($this->pos->x - 1, $this->pos->y, $this->pos->z)) or !$this->canFlowInto($this->pos->getWorldNonNull()->getBlockAt($this->pos->x - 1, $this->pos->y, $this->pos->z)) or
!$this->canFlowInto($this->pos->getWorld()->getBlockAt($this->pos->x + 1, $this->pos->y, $this->pos->z)) or !$this->canFlowInto($this->pos->getWorldNonNull()->getBlockAt($this->pos->x + 1, $this->pos->y, $this->pos->z)) or
!$this->canFlowInto($this->pos->getWorld()->getBlockAt($this->pos->x, $this->pos->y + 1, $this->pos->z - 1)) or !$this->canFlowInto($this->pos->getWorldNonNull()->getBlockAt($this->pos->x, $this->pos->y + 1, $this->pos->z - 1)) or
!$this->canFlowInto($this->pos->getWorld()->getBlockAt($this->pos->x, $this->pos->y + 1, $this->pos->z + 1)) or !$this->canFlowInto($this->pos->getWorldNonNull()->getBlockAt($this->pos->x, $this->pos->y + 1, $this->pos->z + 1)) or
!$this->canFlowInto($this->pos->getWorld()->getBlockAt($this->pos->x - 1, $this->pos->y + 1, $this->pos->z)) or !$this->canFlowInto($this->pos->getWorldNonNull()->getBlockAt($this->pos->x - 1, $this->pos->y + 1, $this->pos->z)) or
!$this->canFlowInto($this->pos->getWorld()->getBlockAt($this->pos->x + 1, $this->pos->y + 1, $this->pos->z)) !$this->canFlowInto($this->pos->getWorldNonNull()->getBlockAt($this->pos->x + 1, $this->pos->y + 1, $this->pos->z))
){ ){
$vector = $vector->normalize()->add(0, -6, 0); $vector = $vector->normalize()->add(0, -6, 0);
} }
@ -252,7 +252,7 @@ abstract class Liquid extends Transparent{
public function onNearbyBlockChange() : void{ public function onNearbyBlockChange() : void{
$this->checkForHarden(); $this->checkForHarden();
$this->pos->getWorld()->scheduleDelayedBlockUpdate($this->pos, $this->tickRate()); $this->pos->getWorldNonNull()->scheduleDelayedBlockUpdate($this->pos, $this->tickRate());
} }
public function onScheduledUpdate() : void{ public function onScheduledUpdate() : void{
@ -261,10 +261,10 @@ abstract class Liquid extends Transparent{
if(!$this->isSource()){ if(!$this->isSource()){
$smallestFlowDecay = -100; $smallestFlowDecay = -100;
$this->adjacentSources = 0; $this->adjacentSources = 0;
$smallestFlowDecay = $this->getSmallestFlowDecay($this->pos->getWorld()->getBlockAt($this->pos->x, $this->pos->y, $this->pos->z - 1), $smallestFlowDecay); $smallestFlowDecay = $this->getSmallestFlowDecay($this->pos->getWorldNonNull()->getBlockAt($this->pos->x, $this->pos->y, $this->pos->z - 1), $smallestFlowDecay);
$smallestFlowDecay = $this->getSmallestFlowDecay($this->pos->getWorld()->getBlockAt($this->pos->x, $this->pos->y, $this->pos->z + 1), $smallestFlowDecay); $smallestFlowDecay = $this->getSmallestFlowDecay($this->pos->getWorldNonNull()->getBlockAt($this->pos->x, $this->pos->y, $this->pos->z + 1), $smallestFlowDecay);
$smallestFlowDecay = $this->getSmallestFlowDecay($this->pos->getWorld()->getBlockAt($this->pos->x - 1, $this->pos->y, $this->pos->z), $smallestFlowDecay); $smallestFlowDecay = $this->getSmallestFlowDecay($this->pos->getWorldNonNull()->getBlockAt($this->pos->x - 1, $this->pos->y, $this->pos->z), $smallestFlowDecay);
$smallestFlowDecay = $this->getSmallestFlowDecay($this->pos->getWorld()->getBlockAt($this->pos->x + 1, $this->pos->y, $this->pos->z), $smallestFlowDecay); $smallestFlowDecay = $this->getSmallestFlowDecay($this->pos->getWorldNonNull()->getBlockAt($this->pos->x + 1, $this->pos->y, $this->pos->z), $smallestFlowDecay);
$newDecay = $smallestFlowDecay + $multiplier; $newDecay = $smallestFlowDecay + $multiplier;
$falling = false; $falling = false;
@ -273,12 +273,12 @@ abstract class Liquid extends Transparent{
$newDecay = -1; $newDecay = -1;
} }
if($this->getEffectiveFlowDecay($this->pos->getWorld()->getBlockAt($this->pos->x, $this->pos->y + 1, $this->pos->z)) >= 0){ if($this->getEffectiveFlowDecay($this->pos->getWorldNonNull()->getBlockAt($this->pos->x, $this->pos->y + 1, $this->pos->z)) >= 0){
$falling = true; $falling = true;
} }
if($this->adjacentSources >= 2 and $this instanceof Water){ if($this->adjacentSources >= 2 and $this instanceof Water){
$bottomBlock = $this->pos->getWorld()->getBlockAt($this->pos->x, $this->pos->y - 1, $this->pos->z); $bottomBlock = $this->pos->getWorldNonNull()->getBlockAt($this->pos->x, $this->pos->y - 1, $this->pos->z);
if($bottomBlock->isSolid() or ($bottomBlock instanceof Water and $bottomBlock->isSource())){ if($bottomBlock->isSolid() or ($bottomBlock instanceof Water and $bottomBlock->isSource())){
$newDecay = 0; $newDecay = 0;
$falling = false; $falling = false;
@ -287,17 +287,17 @@ abstract class Liquid extends Transparent{
if($falling !== $this->falling or (!$falling and $newDecay !== $this->decay)){ if($falling !== $this->falling or (!$falling and $newDecay !== $this->decay)){
if(!$falling and $newDecay < 0){ if(!$falling and $newDecay < 0){
$this->pos->getWorld()->setBlock($this->pos, VanillaBlocks::AIR()); $this->pos->getWorldNonNull()->setBlock($this->pos, VanillaBlocks::AIR());
return; return;
} }
$this->falling = $falling; $this->falling = $falling;
$this->decay = $falling ? 0 : $newDecay; $this->decay = $falling ? 0 : $newDecay;
$this->pos->getWorld()->setBlock($this->pos, $this); //local block update will cause an update to be scheduled $this->pos->getWorldNonNull()->setBlock($this->pos, $this); //local block update will cause an update to be scheduled
} }
} }
$bottomBlock = $this->pos->getWorld()->getBlockAt($this->pos->x, $this->pos->y - 1, $this->pos->z); $bottomBlock = $this->pos->getWorldNonNull()->getBlockAt($this->pos->x, $this->pos->y - 1, $this->pos->z);
$this->flowIntoBlock($bottomBlock, 0, true); $this->flowIntoBlock($bottomBlock, 0, true);
@ -312,19 +312,19 @@ abstract class Liquid extends Transparent{
$flags = $this->getOptimalFlowDirections(); $flags = $this->getOptimalFlowDirections();
if($flags[0]){ if($flags[0]){
$this->flowIntoBlock($this->pos->getWorld()->getBlockAt($this->pos->x - 1, $this->pos->y, $this->pos->z), $adjacentDecay, false); $this->flowIntoBlock($this->pos->getWorldNonNull()->getBlockAt($this->pos->x - 1, $this->pos->y, $this->pos->z), $adjacentDecay, false);
} }
if($flags[1]){ if($flags[1]){
$this->flowIntoBlock($this->pos->getWorld()->getBlockAt($this->pos->x + 1, $this->pos->y, $this->pos->z), $adjacentDecay, false); $this->flowIntoBlock($this->pos->getWorldNonNull()->getBlockAt($this->pos->x + 1, $this->pos->y, $this->pos->z), $adjacentDecay, false);
} }
if($flags[2]){ if($flags[2]){
$this->flowIntoBlock($this->pos->getWorld()->getBlockAt($this->pos->x, $this->pos->y, $this->pos->z - 1), $adjacentDecay, false); $this->flowIntoBlock($this->pos->getWorldNonNull()->getBlockAt($this->pos->x, $this->pos->y, $this->pos->z - 1), $adjacentDecay, false);
} }
if($flags[3]){ if($flags[3]){
$this->flowIntoBlock($this->pos->getWorld()->getBlockAt($this->pos->x, $this->pos->y, $this->pos->z + 1), $adjacentDecay, false); $this->flowIntoBlock($this->pos->getWorldNonNull()->getBlockAt($this->pos->x, $this->pos->y, $this->pos->z + 1), $adjacentDecay, false);
} }
} }
} }
@ -342,10 +342,10 @@ abstract class Liquid extends Transparent{
$ev->call(); $ev->call();
if(!$ev->isCancelled()){ if(!$ev->isCancelled()){
if($block->getId() > 0){ if($block->getId() > 0){
$this->pos->getWorld()->useBreakOn($block->pos); $this->pos->getWorldNonNull()->useBreakOn($block->pos);
} }
$this->pos->getWorld()->setBlock($block->pos, $ev->getNewState()); $this->pos->getWorldNonNull()->setBlock($block->pos, $ev->getNewState());
} }
} }
} }
@ -373,10 +373,10 @@ abstract class Liquid extends Transparent{
} }
if(!isset($this->flowCostVisited[$hash = World::blockHash($x, $y, $z)])){ if(!isset($this->flowCostVisited[$hash = World::blockHash($x, $y, $z)])){
$blockSide = $this->pos->getWorld()->getBlockAt($x, $y, $z); $blockSide = $this->pos->getWorldNonNull()->getBlockAt($x, $y, $z);
if(!$this->canFlowInto($blockSide)){ if(!$this->canFlowInto($blockSide)){
$this->flowCostVisited[$hash] = self::BLOCKED; $this->flowCostVisited[$hash] = self::BLOCKED;
}elseif($this->pos->getWorld()->getBlockAt($x, $y - 1, $z)->canBeFlowedInto()){ }elseif($this->pos->getWorldNonNull()->getBlockAt($x, $y - 1, $z)->canBeFlowedInto()){
$this->flowCostVisited[$hash] = self::CAN_FLOW_DOWN; $this->flowCostVisited[$hash] = self::CAN_FLOW_DOWN;
}else{ }else{
$this->flowCostVisited[$hash] = self::CAN_FLOW; $this->flowCostVisited[$hash] = self::CAN_FLOW;
@ -425,12 +425,12 @@ abstract class Liquid extends Transparent{
}elseif($j === 3){ }elseif($j === 3){
++$z; ++$z;
} }
$block = $this->pos->getWorld()->getBlockAt($x, $y, $z); $block = $this->pos->getWorldNonNull()->getBlockAt($x, $y, $z);
if(!$this->canFlowInto($block)){ if(!$this->canFlowInto($block)){
$this->flowCostVisited[World::blockHash($x, $y, $z)] = self::BLOCKED; $this->flowCostVisited[World::blockHash($x, $y, $z)] = self::BLOCKED;
continue; continue;
}elseif($this->pos->getWorld()->getBlockAt($x, $y - 1, $z)->canBeFlowedInto()){ }elseif($this->pos->getWorldNonNull()->getBlockAt($x, $y - 1, $z)->canBeFlowedInto()){
$this->flowCostVisited[World::blockHash($x, $y, $z)] = self::CAN_FLOW_DOWN; $this->flowCostVisited[World::blockHash($x, $y, $z)] = self::CAN_FLOW_DOWN;
$flowCost[$j] = $maxCost = 0; $flowCost[$j] = $maxCost = 0;
}elseif($maxCost > 0){ }elseif($maxCost > 0){
@ -477,13 +477,13 @@ abstract class Liquid extends Transparent{
$ev = new BlockFormEvent($this, $result); $ev = new BlockFormEvent($this, $result);
$ev->call(); $ev->call();
if(!$ev->isCancelled()){ if(!$ev->isCancelled()){
$this->pos->getWorld()->setBlock($this->pos, $ev->getNewState()); $this->pos->getWorldNonNull()->setBlock($this->pos, $ev->getNewState());
$this->pos->getWorld()->addSound($this->pos->add(0.5, 0.5, 0.5), new FizzSound(2.6 + (lcg_value() - lcg_value()) * 0.8)); $this->pos->getWorldNonNull()->addSound($this->pos->add(0.5, 0.5, 0.5), new FizzSound(2.6 + (lcg_value() - lcg_value()) * 0.8));
} }
return true; return true;
} }
protected function canFlowInto(Block $block) : bool{ protected function canFlowInto(Block $block) : bool{
return $this->pos->getWorld()->isInWorld($block->pos->x, $block->pos->y, $block->pos->z) and $block->canBeFlowedInto() and !($block instanceof Liquid and $block->isSource()); //TODO: I think this should only be liquids of the same type return $this->pos->getWorldNonNull()->isInWorld($block->pos->x, $block->pos->y, $block->pos->z) and $block->canBeFlowedInto() and !($block instanceof Liquid and $block->isSource()); //TODO: I think this should only be liquids of the same type
} }
} }

View File

@ -49,13 +49,13 @@ class Mycelium extends Opaque{
$x = mt_rand($this->pos->x - 1, $this->pos->x + 1); $x = mt_rand($this->pos->x - 1, $this->pos->x + 1);
$y = mt_rand($this->pos->y - 2, $this->pos->y + 2); $y = mt_rand($this->pos->y - 2, $this->pos->y + 2);
$z = mt_rand($this->pos->z - 1, $this->pos->z + 1); $z = mt_rand($this->pos->z - 1, $this->pos->z + 1);
$block = $this->pos->getWorld()->getBlockAt($x, $y, $z); $block = $this->pos->getWorldNonNull()->getBlockAt($x, $y, $z);
if($block->getId() === BlockLegacyIds::DIRT){ if($block->getId() === BlockLegacyIds::DIRT){
if($block->getSide(Facing::UP) instanceof Transparent){ if($block->getSide(Facing::UP) instanceof Transparent){
$ev = new BlockSpreadEvent($block, $this, VanillaBlocks::MYCELIUM()); $ev = new BlockSpreadEvent($block, $this, VanillaBlocks::MYCELIUM());
$ev->call(); $ev->call();
if(!$ev->isCancelled()){ if(!$ev->isCancelled()){
$this->pos->getWorld()->setBlock($block->pos, $ev->getNewState()); $this->pos->getWorldNonNull()->setBlock($block->pos, $ev->getNewState());
} }
} }
} }

View File

@ -64,7 +64,7 @@ class NetherWartPlant extends Flowable{
public function onNearbyBlockChange() : void{ public function onNearbyBlockChange() : void{
if($this->getSide(Facing::DOWN)->getId() !== BlockLegacyIds::SOUL_SAND){ if($this->getSide(Facing::DOWN)->getId() !== BlockLegacyIds::SOUL_SAND){
$this->pos->getWorld()->useBreakOn($this->pos); $this->pos->getWorldNonNull()->useBreakOn($this->pos);
} }
} }
@ -79,7 +79,7 @@ class NetherWartPlant extends Flowable{
$ev = new BlockGrowEvent($this, $block); $ev = new BlockGrowEvent($this, $block);
$ev->call(); $ev->call();
if(!$ev->isCancelled()){ if(!$ev->isCancelled()){
$this->pos->getWorld()->setBlock($this->pos, $ev->getNewState()); $this->pos->getWorldNonNull()->setBlock($this->pos, $ev->getNewState());
} }
} }
} }

View File

@ -39,7 +39,7 @@ class Note extends Opaque{
public function readStateFromWorld() : void{ public function readStateFromWorld() : void{
parent::readStateFromWorld(); parent::readStateFromWorld();
$tile = $this->pos->getWorld()->getTile($this->pos); $tile = $this->pos->getWorldNonNull()->getTile($this->pos);
if($tile instanceof TileNote){ if($tile instanceof TileNote){
$this->pitch = $tile->getPitch(); $this->pitch = $tile->getPitch();
}else{ }else{
@ -49,7 +49,7 @@ class Note extends Opaque{
public function writeStateToWorld() : void{ public function writeStateToWorld() : void{
parent::writeStateToWorld(); parent::writeStateToWorld();
$tile = $this->pos->getWorld()->getTile($this->pos); $tile = $this->pos->getWorldNonNull()->getTile($this->pos);
assert($tile instanceof TileNote); assert($tile instanceof TileNote);
$tile->setPitch($this->pitch); $tile->setPitch($this->pitch);
} }

View File

@ -41,7 +41,7 @@ class RedMushroom extends Flowable{
public function onNearbyBlockChange() : void{ public function onNearbyBlockChange() : void{
if($this->getSide(Facing::DOWN)->isTransparent()){ if($this->getSide(Facing::DOWN)->isTransparent()){
$this->pos->getWorld()->useBreakOn($this->pos); $this->pos->getWorldNonNull()->useBreakOn($this->pos);
} }
} }

View File

@ -72,7 +72,7 @@ class RedstoneComparator extends Flowable{
public function readStateFromWorld() : void{ public function readStateFromWorld() : void{
parent::readStateFromWorld(); parent::readStateFromWorld();
$tile = $this->pos->getWorld()->getTile($this->pos); $tile = $this->pos->getWorldNonNull()->getTile($this->pos);
if($tile instanceof Comparator){ if($tile instanceof Comparator){
$this->signalStrength = $tile->getSignalStrength(); $this->signalStrength = $tile->getSignalStrength();
} }
@ -80,7 +80,7 @@ class RedstoneComparator extends Flowable{
public function writeStateToWorld() : void{ public function writeStateToWorld() : void{
parent::writeStateToWorld(); parent::writeStateToWorld();
$tile = $this->pos->getWorld()->getTile($this->pos); $tile = $this->pos->getWorldNonNull()->getTile($this->pos);
assert($tile instanceof Comparator); assert($tile instanceof Comparator);
$tile->setSignalStrength($this->signalStrength); $tile->setSignalStrength($this->signalStrength);
} }
@ -143,13 +143,13 @@ class RedstoneComparator extends Flowable{
public function onInteract(Item $item, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ public function onInteract(Item $item, int $face, Vector3 $clickVector, ?Player $player = null) : bool{
$this->isSubtractMode = !$this->isSubtractMode; $this->isSubtractMode = !$this->isSubtractMode;
$this->pos->getWorld()->setBlock($this->pos, $this); $this->pos->getWorldNonNull()->setBlock($this->pos, $this);
return true; return true;
} }
public function onNearbyBlockChange() : void{ public function onNearbyBlockChange() : void{
if($this->getSide(Facing::DOWN)->isTransparent()){ if($this->getSide(Facing::DOWN)->isTransparent()){
$this->pos->getWorld()->useBreakOn($this->pos); $this->pos->getWorldNonNull()->useBreakOn($this->pos);
} }
} }

View File

@ -68,7 +68,7 @@ class RedstoneOre extends Opaque{
public function onInteract(Item $item, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ public function onInteract(Item $item, int $face, Vector3 $clickVector, ?Player $player = null) : bool{
if(!$this->lit){ if(!$this->lit){
$this->lit = true; $this->lit = true;
$this->pos->getWorld()->setBlock($this->pos, $this); //no return here - this shouldn't prevent block placement $this->pos->getWorldNonNull()->setBlock($this->pos, $this); //no return here - this shouldn't prevent block placement
} }
return false; return false;
} }
@ -76,7 +76,7 @@ class RedstoneOre extends Opaque{
public function onNearbyBlockChange() : void{ public function onNearbyBlockChange() : void{
if(!$this->lit){ if(!$this->lit){
$this->lit = true; $this->lit = true;
$this->pos->getWorld()->setBlock($this->pos, $this); $this->pos->getWorldNonNull()->setBlock($this->pos, $this);
} }
} }
@ -87,7 +87,7 @@ class RedstoneOre extends Opaque{
public function onRandomTick() : void{ public function onRandomTick() : void{
if($this->lit){ if($this->lit){
$this->lit = false; $this->lit = false;
$this->pos->getWorld()->setBlock($this->pos, $this); $this->pos->getWorldNonNull()->setBlock($this->pos, $this);
} }
} }

View File

@ -99,13 +99,13 @@ class RedstoneRepeater extends Flowable{
if(++$this->delay > 4){ if(++$this->delay > 4){
$this->delay = 1; $this->delay = 1;
} }
$this->pos->getWorld()->setBlock($this->pos, $this); $this->pos->getWorldNonNull()->setBlock($this->pos, $this);
return true; return true;
} }
public function onNearbyBlockChange() : void{ public function onNearbyBlockChange() : void{
if($this->getSide(Facing::DOWN)->isTransparent()){ if($this->getSide(Facing::DOWN)->isTransparent()){
$this->pos->getWorld()->useBreakOn($this->pos); $this->pos->getWorldNonNull()->useBreakOn($this->pos);
} }
} }

View File

@ -69,7 +69,7 @@ class Sapling extends Flowable{
public function onInteract(Item $item, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ public function onInteract(Item $item, int $face, Vector3 $clickVector, ?Player $player = null) : bool{
if($item instanceof Fertilizer){ if($item instanceof Fertilizer){
Tree::growTree($this->pos->getWorld(), $this->pos->x, $this->pos->y, $this->pos->z, new Random(mt_rand()), $this->treeType); Tree::growTree($this->pos->getWorldNonNull(), $this->pos->x, $this->pos->y, $this->pos->z, new Random(mt_rand()), $this->treeType);
$item->pop(); $item->pop();
@ -81,7 +81,7 @@ class Sapling extends Flowable{
public function onNearbyBlockChange() : void{ public function onNearbyBlockChange() : void{
if($this->getSide(Facing::DOWN)->isTransparent()){ if($this->getSide(Facing::DOWN)->isTransparent()){
$this->pos->getWorld()->useBreakOn($this->pos); $this->pos->getWorldNonNull()->useBreakOn($this->pos);
} }
} }
@ -90,12 +90,12 @@ class Sapling extends Flowable{
} }
public function onRandomTick() : void{ public function onRandomTick() : void{
if($this->pos->getWorld()->getFullLightAt($this->pos->x, $this->pos->y, $this->pos->z) >= 8 and mt_rand(1, 7) === 1){ if($this->pos->getWorldNonNull()->getFullLightAt($this->pos->x, $this->pos->y, $this->pos->z) >= 8 and mt_rand(1, 7) === 1){
if($this->ready){ if($this->ready){
Tree::growTree($this->pos->getWorld(), $this->pos->x, $this->pos->y, $this->pos->z, new Random(mt_rand()), $this->treeType); Tree::growTree($this->pos->getWorldNonNull(), $this->pos->x, $this->pos->y, $this->pos->z, new Random(mt_rand()), $this->treeType);
}else{ }else{
$this->ready = true; $this->ready = true;
$this->pos->getWorld()->setBlock($this->pos, $this); $this->pos->getWorldNonNull()->setBlock($this->pos, $this);
} }
} }
} }

View File

@ -86,7 +86,7 @@ class Sign extends Transparent{
public function readStateFromWorld() : void{ public function readStateFromWorld() : void{
parent::readStateFromWorld(); parent::readStateFromWorld();
$tile = $this->pos->getWorld()->getTile($this->pos); $tile = $this->pos->getWorldNonNull()->getTile($this->pos);
if($tile instanceof TileSign){ if($tile instanceof TileSign){
$this->text = $tile->getText(); $this->text = $tile->getText();
} }
@ -94,7 +94,7 @@ class Sign extends Transparent{
public function writeStateToWorld() : void{ public function writeStateToWorld() : void{
parent::writeStateToWorld(); parent::writeStateToWorld();
$tile = $this->pos->getWorld()->getTile($this->pos); $tile = $this->pos->getWorldNonNull()->getTile($this->pos);
assert($tile instanceof TileSign); assert($tile instanceof TileSign);
$tile->setText($this->text); $tile->setText($this->text);
} }
@ -129,7 +129,7 @@ class Sign extends Transparent{
public function onNearbyBlockChange() : void{ public function onNearbyBlockChange() : void{
if($this->getSide(Facing::opposite($this->facing))->getId() === BlockLegacyIds::AIR){ if($this->getSide(Facing::opposite($this->facing))->getId() === BlockLegacyIds::AIR){
$this->pos->getWorld()->useBreakOn($this->pos); $this->pos->getWorldNonNull()->useBreakOn($this->pos);
} }
} }
@ -161,7 +161,7 @@ class Sign extends Transparent{
$ev->call(); $ev->call();
if(!$ev->isCancelled()){ if(!$ev->isCancelled()){
$this->text = clone $ev->getNewText(); $this->text = clone $ev->getNewText();
$this->pos->getWorld()->setBlock($this->pos, $this); $this->pos->getWorldNonNull()->setBlock($this->pos, $this);
return true; return true;
} }

View File

@ -67,7 +67,7 @@ class Skull extends Flowable{
public function readStateFromWorld() : void{ public function readStateFromWorld() : void{
parent::readStateFromWorld(); parent::readStateFromWorld();
$tile = $this->pos->getWorld()->getTile($this->pos); $tile = $this->pos->getWorldNonNull()->getTile($this->pos);
if($tile instanceof TileSkull){ if($tile instanceof TileSkull){
$this->skullType = $tile->getSkullType(); $this->skullType = $tile->getSkullType();
$this->rotation = $tile->getRotation(); $this->rotation = $tile->getRotation();
@ -77,7 +77,7 @@ class Skull extends Flowable{
public function writeStateToWorld() : void{ public function writeStateToWorld() : void{
parent::writeStateToWorld(); parent::writeStateToWorld();
//extra block properties storage hack //extra block properties storage hack
$tile = $this->pos->getWorld()->getTile($this->pos); $tile = $this->pos->getWorldNonNull()->getTile($this->pos);
assert($tile instanceof TileSkull); assert($tile instanceof TileSkull);
$tile->setRotation($this->rotation); $tile->setRotation($this->rotation);
$tile->setSkullType($this->skullType); $tile->setSkullType($this->skullType);

View File

@ -91,8 +91,8 @@ class SnowLayer extends Flowable implements Fallable{
} }
public function onRandomTick() : void{ public function onRandomTick() : void{
if($this->pos->getWorld()->getBlockLightAt($this->pos->x, $this->pos->y, $this->pos->z) >= 12){ if($this->pos->getWorldNonNull()->getBlockLightAt($this->pos->x, $this->pos->y, $this->pos->z) >= 12){
$this->pos->getWorld()->setBlock($this->pos, VanillaBlocks::AIR(), false); $this->pos->getWorldNonNull()->setBlock($this->pos, VanillaBlocks::AIR(), false);
} }
} }

View File

@ -45,7 +45,7 @@ abstract class Stem extends Crops{
$ev = new BlockGrowEvent($this, $block); $ev = new BlockGrowEvent($this, $block);
$ev->call(); $ev->call();
if(!$ev->isCancelled()){ if(!$ev->isCancelled()){
$this->pos->getWorld()->setBlock($this->pos, $ev->getNewState()); $this->pos->getWorldNonNull()->setBlock($this->pos, $ev->getNewState());
} }
}else{ }else{
$grow = $this->getPlant(); $grow = $this->getPlant();
@ -61,7 +61,7 @@ abstract class Stem extends Crops{
$ev = new BlockGrowEvent($side, $grow); $ev = new BlockGrowEvent($side, $grow);
$ev->call(); $ev->call();
if(!$ev->isCancelled()){ if(!$ev->isCancelled()){
$this->pos->getWorld()->setBlock($side->pos, $ev->getNewState()); $this->pos->getWorldNonNull()->setBlock($side->pos, $ev->getNewState());
} }
} }
} }

View File

@ -57,20 +57,20 @@ class Sugarcane extends Flowable{
if($item instanceof Fertilizer){ if($item instanceof Fertilizer){
if(!$this->getSide(Facing::DOWN)->isSameType($this)){ if(!$this->getSide(Facing::DOWN)->isSameType($this)){
for($y = 1; $y < 3; ++$y){ for($y = 1; $y < 3; ++$y){
$b = $this->pos->getWorld()->getBlockAt($this->pos->x, $this->pos->y + $y, $this->pos->z); $b = $this->pos->getWorldNonNull()->getBlockAt($this->pos->x, $this->pos->y + $y, $this->pos->z);
if($b->getId() === BlockLegacyIds::AIR){ if($b->getId() === BlockLegacyIds::AIR){
$ev = new BlockGrowEvent($b, VanillaBlocks::SUGARCANE()); $ev = new BlockGrowEvent($b, VanillaBlocks::SUGARCANE());
$ev->call(); $ev->call();
if($ev->isCancelled()){ if($ev->isCancelled()){
break; break;
} }
$this->pos->getWorld()->setBlock($b->pos, $ev->getNewState()); $this->pos->getWorldNonNull()->setBlock($b->pos, $ev->getNewState());
}else{ }else{
break; break;
} }
} }
$this->age = 0; $this->age = 0;
$this->pos->getWorld()->setBlock($this->pos, $this); $this->pos->getWorldNonNull()->setBlock($this->pos, $this);
} }
$item->pop(); $item->pop();
@ -84,7 +84,7 @@ class Sugarcane extends Flowable{
public function onNearbyBlockChange() : void{ public function onNearbyBlockChange() : void{
$down = $this->getSide(Facing::DOWN); $down = $this->getSide(Facing::DOWN);
if($down->isTransparent() and !$down->isSameType($this)){ if($down->isTransparent() and !$down->isSameType($this)){
$this->pos->getWorld()->useBreakOn($this->pos); $this->pos->getWorldNonNull()->useBreakOn($this->pos);
} }
} }
@ -96,17 +96,17 @@ class Sugarcane extends Flowable{
if(!$this->getSide(Facing::DOWN)->isSameType($this)){ if(!$this->getSide(Facing::DOWN)->isSameType($this)){
if($this->age === 15){ if($this->age === 15){
for($y = 1; $y < 3; ++$y){ for($y = 1; $y < 3; ++$y){
$b = $this->pos->getWorld()->getBlockAt($this->pos->x, $this->pos->y + $y, $this->pos->z); $b = $this->pos->getWorldNonNull()->getBlockAt($this->pos->x, $this->pos->y + $y, $this->pos->z);
if($b->getId() === BlockLegacyIds::AIR){ if($b->getId() === BlockLegacyIds::AIR){
$this->pos->getWorld()->setBlock($b->pos, VanillaBlocks::SUGARCANE()); $this->pos->getWorldNonNull()->setBlock($b->pos, VanillaBlocks::SUGARCANE());
break; break;
} }
} }
$this->age = 0; $this->age = 0;
$this->pos->getWorld()->setBlock($this->pos, $this); $this->pos->getWorldNonNull()->setBlock($this->pos, $this);
}else{ }else{
++$this->age; ++$this->age;
$this->pos->getWorld()->setBlock($this->pos, $this); $this->pos->getWorldNonNull()->setBlock($this->pos, $this);
} }
} }
} }

View File

@ -90,14 +90,14 @@ class TNT extends Opaque{
} }
public function ignite(int $fuse = 80) : void{ public function ignite(int $fuse = 80) : void{
$this->pos->getWorld()->setBlock($this->pos, VanillaBlocks::AIR()); $this->pos->getWorldNonNull()->setBlock($this->pos, VanillaBlocks::AIR());
$mot = (new Random())->nextSignedFloat() * M_PI * 2; $mot = (new Random())->nextSignedFloat() * M_PI * 2;
$nbt = EntityFactory::createBaseNBT($this->pos->add(0.5, 0, 0.5), new Vector3(-sin($mot) * 0.02, 0.2, -cos($mot) * 0.02)); $nbt = EntityFactory::createBaseNBT($this->pos->add(0.5, 0, 0.5), new Vector3(-sin($mot) * 0.02, 0.2, -cos($mot) * 0.02));
$nbt->setShort("Fuse", $fuse); $nbt->setShort("Fuse", $fuse);
/** @var PrimedTNT $tnt */ /** @var PrimedTNT $tnt */
$tnt = EntityFactory::create(PrimedTNT::class, $this->pos->getWorld(), $nbt); $tnt = EntityFactory::create(PrimedTNT::class, $this->pos->getWorldNonNull(), $nbt);
$tnt->spawnToAll(); $tnt->spawnToAll();
} }

View File

@ -52,7 +52,7 @@ class TallGrass extends Flowable{
public function onNearbyBlockChange() : void{ public function onNearbyBlockChange() : void{
if($this->getSide(Facing::DOWN)->isTransparent()){ //Replace with common break method if($this->getSide(Facing::DOWN)->isTransparent()){ //Replace with common break method
$this->pos->getWorld()->useBreakOn($this->pos); $this->pos->getWorldNonNull()->useBreakOn($this->pos);
} }
} }

View File

@ -60,7 +60,7 @@ class Torch extends Flowable{
$face = Facing::opposite($this->facing); $face = Facing::opposite($this->facing);
if($this->getSide($face)->isTransparent() and !($face === Facing::DOWN and ($below->getId() === BlockLegacyIds::FENCE or $below->getId() === BlockLegacyIds::COBBLESTONE_WALL))){ if($this->getSide($face)->isTransparent() and !($face === Facing::DOWN and ($below->getId() === BlockLegacyIds::FENCE or $below->getId() === BlockLegacyIds::COBBLESTONE_WALL))){
$this->pos->getWorld()->useBreakOn($this->pos); $this->pos->getWorldNonNull()->useBreakOn($this->pos);
} }
} }

View File

@ -77,8 +77,8 @@ class Trapdoor extends Transparent{
public function onInteract(Item $item, int $face, Vector3 $clickVector, ?Player $player = null) : bool{ public function onInteract(Item $item, int $face, Vector3 $clickVector, ?Player $player = null) : bool{
$this->open = !$this->open; $this->open = !$this->open;
$this->pos->getWorld()->setBlock($this->pos, $this); $this->pos->getWorldNonNull()->setBlock($this->pos, $this);
$this->pos->getWorld()->addSound($this->pos, new DoorSound()); $this->pos->getWorldNonNull()->addSound($this->pos, new DoorSound());
return true; return true;
} }
} }

View File

@ -115,9 +115,9 @@ class Vine extends Flowable{
if($changed){ if($changed){
if(count($this->faces) === 0){ if(count($this->faces) === 0){
$this->pos->getWorld()->useBreakOn($this->pos); $this->pos->getWorldNonNull()->useBreakOn($this->pos);
}else{ }else{
$this->pos->getWorld()->setBlock($this->pos, $this); $this->pos->getWorldNonNull()->setBlock($this->pos, $this);
} }
} }
} }

View File

@ -56,7 +56,7 @@ class WaterLily extends Flowable{
public function onNearbyBlockChange() : void{ public function onNearbyBlockChange() : void{
if(!($this->getSide(Facing::DOWN) instanceof Water)){ if(!($this->getSide(Facing::DOWN) instanceof Water)){
$this->pos->getWorld()->useBreakOn($this->pos); $this->pos->getWorldNonNull()->useBreakOn($this->pos);
} }
} }
} }

View File

@ -55,7 +55,7 @@ class BrewingStand extends Spawnable implements Container, Nameable{
parent::__construct($world, $pos); parent::__construct($world, $pos);
$this->inventory = new BrewingStandInventory($this->pos); $this->inventory = new BrewingStandInventory($this->pos);
$this->inventory->addChangeListeners(CallbackInventoryChangeListener::onAnyChange(function(Inventory $unused) : void{ $this->inventory->addChangeListeners(CallbackInventoryChangeListener::onAnyChange(function(Inventory $unused) : void{
$this->pos->getWorld()->scheduleDelayedBlockUpdate($this->pos, 1); $this->pos->getWorldNonNull()->scheduleDelayedBlockUpdate($this->pos, 1);
})); }));
} }

View File

@ -99,7 +99,7 @@ class Chest extends Spawnable implements Container, Nameable{
$this->inventory->removeAllViewers(); $this->inventory->removeAllViewers();
if($this->doubleInventory !== null){ if($this->doubleInventory !== null){
if($this->isPaired() and $this->pos->getWorld()->isChunkLoaded($this->pairX >> 4, $this->pairZ >> 4)){ if($this->isPaired() and $this->pos->getWorldNonNull()->isChunkLoaded($this->pairX >> 4, $this->pairZ >> 4)){
$this->doubleInventory->removeAllViewers(); $this->doubleInventory->removeAllViewers();
if(($pair = $this->getPair()) !== null){ if(($pair = $this->getPair()) !== null){
$pair->doubleInventory = null; $pair->doubleInventory = null;
@ -137,7 +137,7 @@ class Chest extends Spawnable implements Container, Nameable{
} }
protected function checkPairing() : void{ protected function checkPairing() : void{
if($this->isPaired() and !$this->pos->getWorld()->isInLoadedTerrain(new Vector3($this->pairX, $this->pos->y, $this->pairZ))){ if($this->isPaired() and !$this->pos->getWorldNonNull()->isInLoadedTerrain(new Vector3($this->pairX, $this->pos->y, $this->pairZ))){
//paired to a tile in an unloaded chunk //paired to a tile in an unloaded chunk
$this->doubleInventory = null; $this->doubleInventory = null;
@ -173,7 +173,7 @@ class Chest extends Spawnable implements Container, Nameable{
public function getPair() : ?Chest{ public function getPair() : ?Chest{
if($this->isPaired()){ if($this->isPaired()){
$tile = $this->pos->getWorld()->getTileAt($this->pairX, $this->pos->y, $this->pairZ); $tile = $this->pos->getWorldNonNull()->getTileAt($this->pairX, $this->pos->y, $this->pairZ);
if($tile instanceof Chest){ if($tile instanceof Chest){
return $tile; return $tile;
} }

View File

@ -60,7 +60,7 @@ class Furnace extends Spawnable implements Container, Nameable{
$this->inventory = new FurnaceInventory($this->pos); $this->inventory = new FurnaceInventory($this->pos);
$this->inventory->addChangeListeners(CallbackInventoryChangeListener::onAnyChange( $this->inventory->addChangeListeners(CallbackInventoryChangeListener::onAnyChange(
function(Inventory $unused) : void{ function(Inventory $unused) : void{
$this->pos->getWorld()->scheduleDelayedBlockUpdate($this->pos, 1); $this->pos->getWorldNonNull()->scheduleDelayedBlockUpdate($this->pos, 1);
}) })
); );
} }
@ -129,7 +129,7 @@ class Furnace extends Spawnable implements Container, Nameable{
$block = $this->getBlock(); $block = $this->getBlock();
if($block instanceof BlockFurnace and !$block->isLit()){ if($block instanceof BlockFurnace and !$block->isLit()){
$block->setLit(true); $block->setLit(true);
$this->pos->getWorld()->setBlock($block->getPos(), $block); $this->pos->getWorldNonNull()->setBlock($block->getPos(), $block);
} }
if($this->remainingFuelTime > 0 and $ev->isBurning()){ if($this->remainingFuelTime > 0 and $ev->isBurning()){
@ -155,7 +155,7 @@ class Furnace extends Spawnable implements Container, Nameable{
$fuel = $this->inventory->getFuel(); $fuel = $this->inventory->getFuel();
$raw = $this->inventory->getSmelting(); $raw = $this->inventory->getSmelting();
$product = $this->inventory->getResult(); $product = $this->inventory->getResult();
$smelt = $this->pos->getWorld()->getServer()->getCraftingManager()->matchFurnaceRecipe($raw); $smelt = $this->pos->getWorldNonNull()->getServer()->getCraftingManager()->matchFurnaceRecipe($raw);
$canSmelt = ($smelt instanceof FurnaceRecipe and $raw->getCount() > 0 and (($smelt->getResult()->equals($product) and $product->getCount() < $product->getMaxStackSize()) or $product->isNull())); $canSmelt = ($smelt instanceof FurnaceRecipe and $raw->getCount() > 0 and (($smelt->getResult()->equals($product) and $product->getCount() < $product->getMaxStackSize()) or $product->isNull()));
if($this->remainingFuelTime <= 0 and $canSmelt and $fuel->getFuelTime() > 0 and $fuel->getCount() > 0){ if($this->remainingFuelTime <= 0 and $canSmelt and $fuel->getFuelTime() > 0 and $fuel->getCount() > 0){
@ -192,7 +192,7 @@ class Furnace extends Spawnable implements Container, Nameable{
$block = $this->getBlock(); $block = $this->getBlock();
if($block instanceof BlockFurnace and $block->isLit()){ if($block instanceof BlockFurnace and $block->isLit()){
$block->setLit(false); $block->setLit(false);
$this->pos->getWorld()->setBlock($block->getPos(), $block); $this->pos->getWorldNonNull()->setBlock($block->getPos(), $block);
} }
$this->remainingFuelTime = $this->cookTime = $this->maxFuelTime = 0; $this->remainingFuelTime = $this->cookTime = $this->maxFuelTime = 0;
} }

View File

@ -95,7 +95,7 @@ abstract class Tile{
} }
public function getBlock() : Block{ public function getBlock() : Block{
return $this->pos->getWorld()->getBlock($this->pos); return $this->pos->getWorldNonNull()->getBlock($this->pos);
} }
public function getPos() : Position{ public function getPos() : Position{
@ -130,7 +130,7 @@ abstract class Tile{
$this->closed = true; $this->closed = true;
if($this->pos->isValid()){ if($this->pos->isValid()){
$this->pos->getWorld()->removeTile($this); $this->pos->getWorldNonNull()->removeTile($this);
$this->pos->setWorld(null); $this->pos->setWorld(null);
} }
} }

View File

@ -56,7 +56,7 @@ trait FallableTrait{
$nbt->setByte("Data", $this->getMeta()); $nbt->setByte("Data", $this->getMeta());
/** @var FallingBlock $fall */ /** @var FallingBlock $fall */
$fall = EntityFactory::create(FallingBlock::class, $pos->getWorld(), $nbt); $fall = EntityFactory::create(FallingBlock::class, $pos->getWorldNonNull(), $nbt);
$fall->spawnToAll(); $fall->spawnToAll();
} }
} }

View File

@ -44,7 +44,7 @@ class SeedCommand extends VanillaCommand{
} }
if($sender instanceof Player){ if($sender instanceof Player){
$seed = $sender->getPosition()->getWorld()->getSeed(); $seed = $sender->getPosition()->getWorldNonNull()->getSeed();
}else{ }else{
$seed = $sender->getServer()->getWorldManager()->getDefaultWorld()->getSeed(); $seed = $sender->getServer()->getWorldManager()->getDefaultWorld()->getSeed();
} }

View File

@ -1342,7 +1342,7 @@ abstract class Entity{
} }
if($pos instanceof Position and $pos->world !== null and $pos->world !== $this->getWorld()){ if($pos instanceof Position and $pos->world !== null and $pos->world !== $this->getWorld()){
if(!$this->switchWorld($pos->getWorld())){ if(!$this->switchWorld($pos->getWorldNonNull())){
return false; return false;
} }
} }
@ -1456,7 +1456,7 @@ abstract class Entity{
$pitch = $pitch ?? $pos->pitch; $pitch = $pitch ?? $pos->pitch;
} }
$from = $this->location->asPosition(); $from = $this->location->asPosition();
$to = Position::fromObject($pos, $pos instanceof Position ? $pos->getWorld() : $this->getWorld()); $to = Position::fromObject($pos, $pos instanceof Position ? $pos->getWorldNonNull() : $this->getWorld());
$ev = new EntityTeleportEvent($this, $from, $to); $ev = new EntityTeleportEvent($this, $from, $to);
$ev->call(); $ev->call();
if($ev->isCancelled()){ if($ev->isCancelled()){

View File

@ -206,7 +206,7 @@ abstract class Living extends Entity{
public function hasLineOfSight(Entity $entity) : bool{ public function hasLineOfSight(Entity $entity) : bool{
//TODO: head height //TODO: head height
return true; return true;
//return $this->getLevel()->rayTraceBlocks(Vector3::createVector($this->x, $this->y + $this->height, $this->z), Vector3::createVector($entity->x, $entity->y + $entity->height, $entity->z)) === null; //return $this->getLevelNonNull()->rayTraceBlocks(Vector3::createVector($this->x, $this->y + $this->height, $this->z), Vector3::createVector($entity->x, $entity->y + $entity->height, $entity->z)) === null;
} }
public function getEffects() : EffectManager{ public function getEffects() : EffectManager{

View File

@ -68,7 +68,7 @@ class Location extends Position{
} }
public function __toString(){ public function __toString(){
return "Location (world=" . ($this->isValid() ? $this->getWorld()->getDisplayName() : "null") . ", x=$this->x, y=$this->y, z=$this->z, yaw=$this->yaw, pitch=$this->pitch)"; return "Location (world=" . ($this->isValid() ? $this->getWorldNonNull()->getDisplayName() : "null") . ", x=$this->x, y=$this->y, z=$this->z, yaw=$this->yaw, pitch=$this->pitch)";
} }
public function equals(Vector3 $v) : bool{ public function equals(Vector3 $v) : bool{

View File

@ -51,7 +51,7 @@ class ChestInventory extends BlockInventory{
if(count($this->getViewers()) === 1 and $this->getHolder()->isValid()){ if(count($this->getViewers()) === 1 and $this->getHolder()->isValid()){
//TODO: this crap really shouldn't be managed by the inventory //TODO: this crap really shouldn't be managed by the inventory
$this->broadcastBlockEventPacket(true); $this->broadcastBlockEventPacket(true);
$this->getHolder()->getWorld()->addSound($this->getHolder()->add(0.5, 0.5, 0.5), $this->getOpenSound()); $this->getHolder()->getWorldNonNull()->addSound($this->getHolder()->add(0.5, 0.5, 0.5), $this->getOpenSound());
} }
} }
@ -59,7 +59,7 @@ class ChestInventory extends BlockInventory{
if(count($this->getViewers()) === 1 and $this->getHolder()->isValid()){ if(count($this->getViewers()) === 1 and $this->getHolder()->isValid()){
//TODO: this crap really shouldn't be managed by the inventory //TODO: this crap really shouldn't be managed by the inventory
$this->broadcastBlockEventPacket(false); $this->broadcastBlockEventPacket(false);
$this->getHolder()->getWorld()->addSound($this->getHolder()->add(0.5, 0.5, 0.5), $this->getCloseSound()); $this->getHolder()->getWorldNonNull()->addSound($this->getHolder()->add(0.5, 0.5, 0.5), $this->getCloseSound());
} }
parent::onClose($who); parent::onClose($who);
} }
@ -68,6 +68,6 @@ class ChestInventory extends 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(1, $isOpen ? 1 : 0, $holder->asVector3())); $holder->getWorldNonNull()->broadcastPacketToViewers($holder, BlockEventPacket::create(1, $isOpen ? 1 : 0, $holder->asVector3()));
} }
} }

View File

@ -105,7 +105,7 @@ class Bow extends Tool{
} }
$ev->getProjectile()->spawnToAll(); $ev->getProjectile()->spawnToAll();
$location->getWorld()->addSound($location, new BowShootSound()); $location->getWorldNonNull()->addSound($location, new BowShootSound());
}else{ }else{
$entity->spawnToAll(); $entity->spawnToAll();
} }

View File

@ -94,7 +94,7 @@ class PaintingItem extends Item{
$nbt->setInt("TileZ", $clickedPos->getFloorZ()); $nbt->setInt("TileZ", $clickedPos->getFloorZ());
/** @var Painting $entity */ /** @var Painting $entity */
$entity = EntityFactory::create(Painting::class, $replacePos->getWorld(), $nbt); $entity = EntityFactory::create(Painting::class, $replacePos->getWorldNonNull(), $nbt);
$this->pop(); $this->pop();
$entity->spawnToAll(); $entity->spawnToAll();

View File

@ -72,7 +72,7 @@ abstract class ProjectileItem extends Item{
$projectile->spawnToAll(); $projectile->spawnToAll();
$location->getWorld()->addSound($location, new ThrowSound()); $location->getWorldNonNull()->addSound($location, new ThrowSound());
$this->pop(); $this->pop();

View File

@ -346,7 +346,7 @@ class InGamePacketHandler extends PacketHandler{
}else{ }else{
$blocks[] = $blockPos; $blocks[] = $blockPos;
} }
$this->player->getLocation()->getWorld()->sendBlocks([$this->player], $blocks); $this->player->getLocation()->getWorldNonNull()->sendBlocks([$this->player], $blocks);
} }
} }
@ -539,7 +539,7 @@ class InGamePacketHandler extends PacketHandler{
return false; return false;
} }
$block = $this->player->getLocation()->getWorld()->getBlock($pos); $block = $this->player->getLocation()->getWorldNonNull()->getBlock($pos);
try{ try{
$offset = 0; $offset = 0;
$nbt = (new NetworkNbtSerializer())->read($packet->namedtag, $offset, 512)->mustGetCompoundTag(); $nbt = (new NetworkNbtSerializer())->read($packet->namedtag, $offset, 512)->mustGetCompoundTag();

View File

@ -65,12 +65,12 @@ class PreSpawnPacketHandler extends PacketHandler{
$pk->seed = -1; $pk->seed = -1;
$pk->dimension = DimensionIds::OVERWORLD; //TODO: implement this properly $pk->dimension = DimensionIds::OVERWORLD; //TODO: implement this properly
$pk->worldGamemode = NetworkSession::getClientFriendlyGamemode($this->server->getGamemode()); $pk->worldGamemode = NetworkSession::getClientFriendlyGamemode($this->server->getGamemode());
$pk->difficulty = $location->getWorld()->getDifficulty(); $pk->difficulty = $location->getWorldNonNull()->getDifficulty();
$pk->spawnX = $spawnPosition->getFloorX(); $pk->spawnX = $spawnPosition->getFloorX();
$pk->spawnY = $spawnPosition->getFloorY(); $pk->spawnY = $spawnPosition->getFloorY();
$pk->spawnZ = $spawnPosition->getFloorZ(); $pk->spawnZ = $spawnPosition->getFloorZ();
$pk->hasAchievementsDisabled = true; $pk->hasAchievementsDisabled = true;
$pk->time = $location->getWorld()->getTime(); $pk->time = $location->getWorldNonNull()->getTime();
$pk->eduEditionOffer = 0; $pk->eduEditionOffer = 0;
$pk->rainLevel = 0; //TODO: implement these properly $pk->rainLevel = 0; //TODO: implement these properly
$pk->lightningLevel = 0; $pk->lightningLevel = 0;

View File

@ -949,7 +949,7 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener,
if(!($pos instanceof Position)){ if(!($pos instanceof Position)){
$world = $this->getWorld(); $world = $this->getWorld();
}else{ }else{
$world = $pos->getWorld(); $world = $pos->getWorldNonNull();
} }
$this->spawnPosition = new Position($pos->x, $pos->y, $pos->z, $world); $this->spawnPosition = new Position($pos->x, $pos->y, $pos->z, $world);
$this->networkSession->syncPlayerSpawnPoint($this->spawnPosition); $this->networkSession->syncPlayerSpawnPoint($this->spawnPosition);
@ -2044,7 +2044,7 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener,
} }
if($this->hasValidSpawnPosition()){ if($this->hasValidSpawnPosition()){
$nbt->setString("SpawnLevel", $this->spawnPosition->getWorld()->getFolderName()); $nbt->setString("SpawnLevel", $this->spawnPosition->getWorldNonNull()->getFolderName());
$nbt->setInt("SpawnX", $this->spawnPosition->getFloorX()); $nbt->setInt("SpawnX", $this->spawnPosition->getFloorX());
$nbt->setInt("SpawnY", $this->spawnPosition->getFloorY()); $nbt->setInt("SpawnY", $this->spawnPosition->getFloorY());
$nbt->setInt("SpawnZ", $this->spawnPosition->getFloorZ()); $nbt->setInt("SpawnZ", $this->spawnPosition->getFloorZ());
@ -2117,7 +2117,7 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener,
$ev = new PlayerRespawnEvent($this, $this->getSpawn()); $ev = new PlayerRespawnEvent($this, $this->getSpawn());
$ev->call(); $ev->call();
$realSpawn = Position::fromObject($ev->getRespawnPosition()->add(0.5, 0, 0.5), $ev->getRespawnPosition()->getWorld()); $realSpawn = Position::fromObject($ev->getRespawnPosition()->add(0.5, 0, 0.5), $ev->getRespawnPosition()->getWorldNonNull());
$this->teleport($realSpawn); $this->teleport($realSpawn);
$this->setSprinting(false); $this->setSprinting(false);

View File

@ -0,0 +1,33 @@
<?php
/*
*
* ____ _ _ __ __ _ __ __ ____
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* @author PocketMine Team
* @link http://www.pocketmine.net/
*
*
*/
declare(strict_types=1);
namespace pocketmine\utils;
/**
* This exception should be thrown in places where something is assumed to be true, but the type system does not provide
* a guarantee. This makes static analysers happy and makes sure that the server will crash properly if any assumption
* does not hold.
*/
final class AssumptionFailedError extends \Error{
}

View File

@ -72,7 +72,7 @@ class Explosion{
throw new \InvalidArgumentException("Position does not have a valid world"); throw new \InvalidArgumentException("Position does not have a valid world");
} }
$this->source = $center; $this->source = $center;
$this->world = $center->getWorld(); $this->world = $center->getWorldNonNull();
if($size <= 0){ if($size <= 0){
throw new \InvalidArgumentException("Explosion radius must be greater than 0, got $size"); throw new \InvalidArgumentException("Explosion radius must be greater than 0, got $size");

View File

@ -24,6 +24,7 @@ declare(strict_types=1);
namespace pocketmine\world; namespace pocketmine\world;
use pocketmine\math\Vector3; use pocketmine\math\Vector3;
use pocketmine\utils\AssumptionFailedError;
use function assert; use function assert;
class Position extends Vector3{ class Position extends Vector3{
@ -70,6 +71,20 @@ class Position extends Vector3{
return $this->world; return $this->world;
} }
/**
* Returns the position's world if valid. Throws an error if the world is unexpectedly null.
*
* @throws AssumptionFailedError
*/
public function getWorldNonNull() : World{
$world = $this->getWorld();
if($world === null){
throw new AssumptionFailedError("Position world is null");
}
return $world;
}
/** /**
* Sets the target world of the position. * Sets the target world of the position.
* *
@ -111,7 +126,7 @@ class Position extends Vector3{
} }
public function __toString(){ public function __toString(){
return "Position(world=" . ($this->isValid() ? $this->getWorld()->getDisplayName() : "null") . ",x=" . $this->x . ",y=" . $this->y . ",z=" . $this->z . ")"; return "Position(level=" . ($this->isValid() ? $this->getWorldNonNull()->getDisplayName() : "null") . ",x=" . $this->x . ",y=" . $this->y . ",z=" . $this->z . ")";
} }
public function equals(Vector3 $v) : bool{ public function equals(Vector3 $v) : bool{