mirror of
https://github.com/pmmp/PocketMine-MP.git
synced 2025-06-06 11:57:10 +00:00
Position: add getLevelNonNull()
this allows assuming that a position has a valid world in places where it's never expected to not be valid. Since this is the vast majority of usages, it eliminates a lot of possible null-pointer warnings given by static analysers. TODO: Consider whether we can make Position->getLevel/World use this behaviour out of the box in the next major version.
This commit is contained in:
parent
6e08b622b3
commit
a2543ff80d
@ -1207,7 +1207,7 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{
|
||||
if(!($pos instanceof Position)){
|
||||
$level = $this->level;
|
||||
}else{
|
||||
$level = $pos->getLevel();
|
||||
$level = $pos->getLevelNonNull();
|
||||
}
|
||||
$this->spawnPosition = new Position($pos->x, $pos->y, $pos->z, $level);
|
||||
$pk = new SetSpawnPositionPacket();
|
||||
@ -2244,7 +2244,7 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{
|
||||
|
||||
public function handleLevelSoundEvent(LevelSoundEventPacket $packet) : bool{
|
||||
//TODO: add events so plugins can change this
|
||||
$this->getLevel()->broadcastPacketToViewers($this, $packet);
|
||||
$this->getLevelNonNull()->broadcastPacketToViewers($this, $packet);
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -2706,7 +2706,7 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{
|
||||
|
||||
$item = $block->getPickedItem();
|
||||
if($packet->addUserData){
|
||||
$tile = $this->getLevel()->getTile($block);
|
||||
$tile = $this->getLevelNonNull()->getTile($block);
|
||||
if($tile instanceof Tile){
|
||||
$nbt = $tile->getCleanedNBT();
|
||||
if($nbt instanceof CompoundTag){
|
||||
@ -3583,7 +3583,7 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{
|
||||
}
|
||||
|
||||
if($this->hasValidSpawnPosition()){
|
||||
$this->namedtag->setString("SpawnLevel", $this->spawnPosition->getLevel()->getFolderName());
|
||||
$this->namedtag->setString("SpawnLevel", $this->spawnPosition->getLevelNonNull()->getFolderName());
|
||||
$this->namedtag->setInt("SpawnX", $this->spawnPosition->getFloorX());
|
||||
$this->namedtag->setInt("SpawnY", $this->spawnPosition->getFloorY());
|
||||
$this->namedtag->setInt("SpawnZ", $this->spawnPosition->getFloorZ());
|
||||
@ -3666,7 +3666,7 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{
|
||||
$ev = new PlayerRespawnEvent($this, $this->getSpawn());
|
||||
$ev->call();
|
||||
|
||||
$realSpawn = Position::fromObject($ev->getRespawnPosition()->add(0.5, 0, 0.5), $ev->getRespawnPosition()->getLevel());
|
||||
$realSpawn = Position::fromObject($ev->getRespawnPosition()->add(0.5, 0, 0.5), $ev->getRespawnPosition()->getLevelNonNull());
|
||||
$this->teleport($realSpawn);
|
||||
|
||||
$this->setSprinting(false);
|
||||
|
@ -110,6 +110,6 @@ class Anvil extends Fallable{
|
||||
public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, Player $player = null) : bool{
|
||||
$direction = ($player !== null ? $player->getDirection() : 0) & 0x03;
|
||||
$this->meta = $this->getVariant() | $direction;
|
||||
return $this->getLevel()->setBlock($blockReplace, $this, true, true);
|
||||
return $this->getLevelNonNull()->setBlock($blockReplace, $this, true, true);
|
||||
}
|
||||
}
|
||||
|
@ -91,7 +91,7 @@ abstract class BaseRail extends Flowable{
|
||||
}
|
||||
|
||||
public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, Player $player = null) : bool{
|
||||
if(!$blockReplace->getSide(Vector3::SIDE_DOWN)->isTransparent() and $this->getLevel()->setBlock($blockReplace, $this, true, true)){
|
||||
if(!$blockReplace->getSide(Vector3::SIDE_DOWN)->isTransparent() and $this->getLevelNonNull()->setBlock($blockReplace, $this, true, true)){
|
||||
$this->tryReconnect();
|
||||
return true;
|
||||
}
|
||||
@ -279,7 +279,7 @@ abstract class BaseRail extends Flowable{
|
||||
isset(self::ASCENDING_SIDES[$this->meta & 0x07]) and
|
||||
$this->getSide(self::ASCENDING_SIDES[$this->meta & 0x07])->isTransparent()
|
||||
)){
|
||||
$this->getLevel()->useBreakOn($this);
|
||||
$this->getLevelNonNull()->useBreakOn($this);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -83,7 +83,7 @@ class Bed extends Transparent{
|
||||
$this->meta &= ~self::BITFLAG_OCCUPIED;
|
||||
}
|
||||
|
||||
$this->getLevel()->setBlock($this, $this, false, false);
|
||||
$this->getLevelNonNull()->setBlock($this, $this, false, false);
|
||||
|
||||
if(($other = $this->getOtherHalf()) !== null and $other->isOccupied() !== $occupied){
|
||||
$other->setOccupied($occupied);
|
||||
@ -137,7 +137,7 @@ class Bed extends Transparent{
|
||||
return true;
|
||||
}
|
||||
|
||||
$time = $this->getLevel()->getTimeOfDay();
|
||||
$time = $this->getLevelNonNull()->getTimeOfDay();
|
||||
|
||||
$isNight = ($time >= Level::TIME_NIGHT and $time < Level::TIME_SUNRISE);
|
||||
|
||||
@ -168,11 +168,11 @@ class Bed extends Transparent{
|
||||
$meta = (($player instanceof Player ? $player->getDirection() : 0) - 1) & 0x03;
|
||||
$next = $this->getSide(self::getOtherHalfSide($meta));
|
||||
if($next->canBeReplaced() and !$next->getSide(Vector3::SIDE_DOWN)->isTransparent()){
|
||||
$this->getLevel()->setBlock($blockReplace, BlockFactory::get($this->id, $meta), true, true);
|
||||
$this->getLevel()->setBlock($next, BlockFactory::get($this->id, $meta | self::BITFLAG_HEAD), true, true);
|
||||
$this->getLevelNonNull()->setBlock($blockReplace, BlockFactory::get($this->id, $meta), true, true);
|
||||
$this->getLevelNonNull()->setBlock($next, BlockFactory::get($this->id, $meta | self::BITFLAG_HEAD), true, true);
|
||||
|
||||
Tile::createTile(Tile::BED, $this->getLevel(), TileBed::createNBT($this, $face, $item, $player));
|
||||
Tile::createTile(Tile::BED, $this->getLevel(), TileBed::createNBT($next, $face, $item, $player));
|
||||
Tile::createTile(Tile::BED, $this->getLevelNonNull(), TileBed::createNBT($this, $face, $item, $player));
|
||||
Tile::createTile(Tile::BED, $this->getLevelNonNull(), TileBed::createNBT($next, $face, $item, $player));
|
||||
|
||||
return true;
|
||||
}
|
||||
@ -194,7 +194,7 @@ class Bed extends Transparent{
|
||||
}
|
||||
|
||||
private function getItem() : Item{
|
||||
$tile = $this->getLevel()->getTile($this);
|
||||
$tile = $this->getLevelNonNull()->getTile($this);
|
||||
if($tile instanceof TileBed){
|
||||
return ItemFactory::get($this->getItemId(), $tile->getColor());
|
||||
}
|
||||
|
@ -154,7 +154,7 @@ class Block extends Position implements BlockIds, Metadatable{
|
||||
* Places the Block, using block space and block target, and side. Returns if the block has been placed.
|
||||
*/
|
||||
public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, Player $player = null) : bool{
|
||||
return $this->getLevel()->setBlock($this, $this, true, true);
|
||||
return $this->getLevelNonNull()->setBlock($this, $this, true, true);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -204,7 +204,7 @@ class Block extends Position implements BlockIds, Metadatable{
|
||||
* Do the actions needed so the block is broken with the Item
|
||||
*/
|
||||
public function onBreak(Item $item, Player $player = null) : bool{
|
||||
return $this->getLevel()->setBlock($this, BlockFactory::get(Block::AIR), true, true);
|
||||
return $this->getLevelNonNull()->setBlock($this, BlockFactory::get(Block::AIR), true, true);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -479,7 +479,7 @@ class Block extends Position implements BlockIds, Metadatable{
|
||||
*/
|
||||
public function getSide(int $side, int $step = 1){
|
||||
if($this->isValid()){
|
||||
return $this->getLevel()->getBlock(Vector3::getSide($side, $step));
|
||||
return $this->getLevelNonNull()->getBlock(Vector3::getSide($side, $step));
|
||||
}
|
||||
|
||||
return BlockFactory::get(Block::AIR, 0, Position::fromObject(Vector3::getSide($side, $step)));
|
||||
|
@ -55,7 +55,7 @@ class BoneBlock extends Solid{
|
||||
|
||||
public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, Player $player = null) : bool{
|
||||
$this->meta = PillarRotationHelper::getMetaFromFace($this->meta, $face);
|
||||
return $this->getLevel()->setBlock($blockReplace, $this, true, true);
|
||||
return $this->getLevelNonNull()->setBlock($blockReplace, $this, true, true);
|
||||
}
|
||||
|
||||
public function getVariantBitmask() : int{
|
||||
|
@ -68,18 +68,18 @@ class BurningFurnace extends Solid{
|
||||
3 => 3
|
||||
];
|
||||
$this->meta = $faces[$player instanceof Player ? $player->getDirection() : 0];
|
||||
$this->getLevel()->setBlock($blockReplace, $this, true, true);
|
||||
$this->getLevelNonNull()->setBlock($blockReplace, $this, true, true);
|
||||
|
||||
Tile::createTile(Tile::FURNACE, $this->getLevel(), TileFurnace::createNBT($this, $face, $item, $player));
|
||||
Tile::createTile(Tile::FURNACE, $this->getLevelNonNull(), TileFurnace::createNBT($this, $face, $item, $player));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public function onActivate(Item $item, Player $player = null) : bool{
|
||||
if($player instanceof Player){
|
||||
$furnace = $this->getLevel()->getTile($this);
|
||||
$furnace = $this->getLevelNonNull()->getTile($this);
|
||||
if(!($furnace instanceof TileFurnace)){
|
||||
$furnace = Tile::createTile(Tile::FURNACE, $this->getLevel(), TileFurnace::createNBT($this));
|
||||
$furnace = Tile::createTile(Tile::FURNACE, $this->getLevelNonNull(), TileFurnace::createNBT($this));
|
||||
if(!($furnace instanceof TileFurnace)){
|
||||
return true;
|
||||
}
|
||||
|
@ -72,12 +72,12 @@ class Cactus extends Transparent{
|
||||
public function onNearbyBlockChange() : void{
|
||||
$down = $this->getSide(Vector3::SIDE_DOWN);
|
||||
if($down->getId() !== self::SAND and $down->getId() !== self::CACTUS){
|
||||
$this->getLevel()->useBreakOn($this);
|
||||
$this->getLevelNonNull()->useBreakOn($this);
|
||||
}else{
|
||||
for($side = 2; $side <= 5; ++$side){
|
||||
$b = $this->getSide($side);
|
||||
if($b->isSolid()){
|
||||
$this->getLevel()->useBreakOn($this);
|
||||
$this->getLevelNonNull()->useBreakOn($this);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -92,23 +92,23 @@ class Cactus extends Transparent{
|
||||
if($this->getSide(Vector3::SIDE_DOWN)->getId() !== self::CACTUS){
|
||||
if($this->meta === 0x0f){
|
||||
for($y = 1; $y < 3; ++$y){
|
||||
$b = $this->getLevel()->getBlockAt($this->x, $this->y + $y, $this->z);
|
||||
$b = $this->getLevelNonNull()->getBlockAt($this->x, $this->y + $y, $this->z);
|
||||
if($b->getId() === self::AIR){
|
||||
$ev = new BlockGrowEvent($b, BlockFactory::get(Block::CACTUS));
|
||||
$ev->call();
|
||||
if($ev->isCancelled()){
|
||||
break;
|
||||
}
|
||||
$this->getLevel()->setBlock($b, $ev->getNewState(), true);
|
||||
$this->getLevelNonNull()->setBlock($b, $ev->getNewState(), true);
|
||||
}else{
|
||||
break;
|
||||
}
|
||||
}
|
||||
$this->meta = 0;
|
||||
$this->getLevel()->setBlock($this, $this);
|
||||
$this->getLevelNonNull()->setBlock($this, $this);
|
||||
}else{
|
||||
++$this->meta;
|
||||
$this->getLevel()->setBlock($this, $this);
|
||||
$this->getLevelNonNull()->setBlock($this, $this);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -121,7 +121,7 @@ class Cactus extends Transparent{
|
||||
$block2 = $this->getSide(Vector3::SIDE_WEST);
|
||||
$block3 = $this->getSide(Vector3::SIDE_EAST);
|
||||
if(!$block0->isSolid() and !$block1->isSolid() and !$block2->isSolid() and !$block3->isSolid()){
|
||||
$this->getLevel()->setBlock($this, $this, true);
|
||||
$this->getLevelNonNull()->setBlock($this, $this, true);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -66,7 +66,7 @@ class Cake extends Transparent implements FoodSource{
|
||||
public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, Player $player = null) : bool{
|
||||
$down = $this->getSide(Vector3::SIDE_DOWN);
|
||||
if($down->getId() !== self::AIR){
|
||||
$this->getLevel()->setBlock($blockReplace, $this, true, true);
|
||||
$this->getLevelNonNull()->setBlock($blockReplace, $this, true, true);
|
||||
|
||||
return true;
|
||||
}
|
||||
@ -76,7 +76,7 @@ class Cake extends Transparent implements FoodSource{
|
||||
|
||||
public function onNearbyBlockChange() : void{
|
||||
if($this->getSide(Vector3::SIDE_DOWN)->getId() === self::AIR){ //Replace with common break method
|
||||
$this->getLevel()->setBlock($this, BlockFactory::get(Block::AIR), true);
|
||||
$this->getLevelNonNull()->setBlock($this, BlockFactory::get(Block::AIR), true);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -64,7 +64,7 @@ class Carpet extends Flowable{
|
||||
public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, Player $player = null) : bool{
|
||||
$down = $this->getSide(Vector3::SIDE_DOWN);
|
||||
if($down->getId() !== self::AIR){
|
||||
$this->getLevel()->setBlock($blockReplace, $this, true, true);
|
||||
$this->getLevelNonNull()->setBlock($blockReplace, $this, true, true);
|
||||
|
||||
return true;
|
||||
}
|
||||
@ -74,7 +74,7 @@ class Carpet extends Flowable{
|
||||
|
||||
public function onNearbyBlockChange() : void{
|
||||
if($this->getSide(Vector3::SIDE_DOWN)->getId() === self::AIR){
|
||||
$this->getLevel()->useBreakOn($this);
|
||||
$this->getLevelNonNull()->useBreakOn($this);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -81,7 +81,7 @@ class Chest extends Transparent{
|
||||
}
|
||||
$c = $this->getSide($side);
|
||||
if($c->getId() === $this->id and $c->getDamage() === $this->meta){
|
||||
$tile = $this->getLevel()->getTile($c);
|
||||
$tile = $this->getLevelNonNull()->getTile($c);
|
||||
if($tile instanceof TileChest and !$tile->isPaired()){
|
||||
$chest = $tile;
|
||||
break;
|
||||
@ -89,8 +89,8 @@ class Chest extends Transparent{
|
||||
}
|
||||
}
|
||||
|
||||
$this->getLevel()->setBlock($blockReplace, $this, true, true);
|
||||
$tile = Tile::createTile(Tile::CHEST, $this->getLevel(), TileChest::createNBT($this, $face, $item, $player));
|
||||
$this->getLevelNonNull()->setBlock($blockReplace, $this, true, true);
|
||||
$tile = Tile::createTile(Tile::CHEST, $this->getLevelNonNull(), TileChest::createNBT($this, $face, $item, $player));
|
||||
|
||||
if($chest instanceof TileChest and $tile instanceof TileChest){
|
||||
$chest->pairWith($tile);
|
||||
@ -103,12 +103,12 @@ class Chest extends Transparent{
|
||||
public function onActivate(Item $item, Player $player = null) : bool{
|
||||
if($player instanceof Player){
|
||||
|
||||
$t = $this->getLevel()->getTile($this);
|
||||
$t = $this->getLevelNonNull()->getTile($this);
|
||||
$chest = null;
|
||||
if($t instanceof TileChest){
|
||||
$chest = $t;
|
||||
}else{
|
||||
$chest = Tile::createTile(Tile::CHEST, $this->getLevel(), TileChest::createNBT($this));
|
||||
$chest = Tile::createTile(Tile::CHEST, $this->getLevelNonNull(), TileChest::createNBT($this));
|
||||
if(!($chest instanceof TileChest)){
|
||||
return true;
|
||||
}
|
||||
|
@ -33,7 +33,7 @@ abstract class Crops extends Flowable{
|
||||
|
||||
public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, Player $player = null) : bool{
|
||||
if($blockReplace->getSide(Vector3::SIDE_DOWN)->getId() === Block::FARMLAND){
|
||||
$this->getLevel()->setBlock($blockReplace, $this, true, true);
|
||||
$this->getLevelNonNull()->setBlock($blockReplace, $this, true, true);
|
||||
|
||||
return true;
|
||||
}
|
||||
@ -52,7 +52,7 @@ abstract class Crops extends Flowable{
|
||||
$ev = new BlockGrowEvent($this, $block);
|
||||
$ev->call();
|
||||
if(!$ev->isCancelled()){
|
||||
$this->getLevel()->setBlock($this, $ev->getNewState(), true, true);
|
||||
$this->getLevelNonNull()->setBlock($this, $ev->getNewState(), true, true);
|
||||
}
|
||||
|
||||
$item->pop();
|
||||
@ -65,7 +65,7 @@ abstract class Crops extends Flowable{
|
||||
|
||||
public function onNearbyBlockChange() : void{
|
||||
if($this->getSide(Vector3::SIDE_DOWN)->getId() !== Block::FARMLAND){
|
||||
$this->getLevel()->useBreakOn($this);
|
||||
$this->getLevelNonNull()->useBreakOn($this);
|
||||
}
|
||||
}
|
||||
|
||||
@ -81,7 +81,7 @@ abstract class Crops extends Flowable{
|
||||
$ev = new BlockGrowEvent($this, $block);
|
||||
$ev->call();
|
||||
if(!$ev->isCancelled()){
|
||||
$this->getLevel()->setBlock($this, $ev->getNewState(), true, true);
|
||||
$this->getLevelNonNull()->setBlock($this, $ev->getNewState(), true, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -42,7 +42,7 @@ class Dandelion extends Flowable{
|
||||
public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, Player $player = null) : bool{
|
||||
$down = $this->getSide(Vector3::SIDE_DOWN);
|
||||
if($down->getId() === Block::GRASS or $down->getId() === Block::DIRT or $down->getId() === Block::FARMLAND){
|
||||
$this->getLevel()->setBlock($blockReplace, $this, true, true);
|
||||
$this->getLevelNonNull()->setBlock($blockReplace, $this, true, true);
|
||||
|
||||
return true;
|
||||
}
|
||||
@ -52,7 +52,7 @@ class Dandelion extends Flowable{
|
||||
|
||||
public function onNearbyBlockChange() : void{
|
||||
if($this->getSide(Vector3::SIDE_DOWN)->isTransparent()){
|
||||
$this->getLevel()->useBreakOn($this);
|
||||
$this->getLevelNonNull()->useBreakOn($this);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -51,7 +51,7 @@ class DeadBush extends Flowable{
|
||||
|
||||
public function onNearbyBlockChange() : void{
|
||||
if($this->getSide(Vector3::SIDE_DOWN)->isTransparent()){
|
||||
$this->getLevel()->useBreakOn($this);
|
||||
$this->getLevelNonNull()->useBreakOn($this);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -54,9 +54,9 @@ class Dirt extends Solid{
|
||||
if($item instanceof Hoe){
|
||||
$item->applyDamage(1);
|
||||
if($this->meta === 1){
|
||||
$this->getLevel()->setBlock($this, BlockFactory::get(Block::DIRT), true);
|
||||
$this->getLevelNonNull()->setBlock($this, BlockFactory::get(Block::DIRT), true);
|
||||
}else{
|
||||
$this->getLevel()->setBlock($this, BlockFactory::get(Block::FARMLAND), true);
|
||||
$this->getLevelNonNull()->setBlock($this, BlockFactory::get(Block::FARMLAND), true);
|
||||
}
|
||||
|
||||
return true;
|
||||
|
@ -201,9 +201,9 @@ abstract class Door extends Transparent{
|
||||
|
||||
public function onNearbyBlockChange() : void{
|
||||
if($this->getSide(Vector3::SIDE_DOWN)->getId() === self::AIR){ //Replace with common break method
|
||||
$this->getLevel()->setBlock($this, BlockFactory::get(Block::AIR), false);
|
||||
$this->getLevelNonNull()->setBlock($this, BlockFactory::get(Block::AIR), false);
|
||||
if($this->getSide(Vector3::SIDE_UP) instanceof Door){
|
||||
$this->getLevel()->setBlock($this->getSide(Vector3::SIDE_UP), BlockFactory::get(Block::AIR), false);
|
||||
$this->getLevelNonNull()->setBlock($this->getSide(Vector3::SIDE_UP), BlockFactory::get(Block::AIR), false);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -230,8 +230,8 @@ abstract class Door extends Transparent{
|
||||
}
|
||||
|
||||
$this->setDamage($player->getDirection() & 0x03);
|
||||
$this->getLevel()->setBlock($blockReplace, $this, true, true); //Bottom
|
||||
$this->getLevel()->setBlock($blockUp, BlockFactory::get($this->getId(), $metaUp), true); //Top
|
||||
$this->getLevelNonNull()->setBlock($blockReplace, $this, true, true); //Bottom
|
||||
$this->getLevelNonNull()->setBlock($blockUp, BlockFactory::get($this->getId(), $metaUp), true); //Top
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -57,8 +57,8 @@ class DoublePlant extends Flowable{
|
||||
public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, Player $player = null) : bool{
|
||||
$id = $blockReplace->getSide(Vector3::SIDE_DOWN)->getId();
|
||||
if(($id === Block::GRASS or $id === Block::DIRT) and $blockReplace->getSide(Vector3::SIDE_UP)->canBeReplaced()){
|
||||
$this->getLevel()->setBlock($blockReplace, $this, false, false);
|
||||
$this->getLevel()->setBlock($blockReplace->getSide(Vector3::SIDE_UP), BlockFactory::get($this->id, $this->meta | self::BITFLAG_TOP), false, false);
|
||||
$this->getLevelNonNull()->setBlock($blockReplace, $this, false, false);
|
||||
$this->getLevelNonNull()->setBlock($blockReplace->getSide(Vector3::SIDE_UP), BlockFactory::get($this->id, $this->meta | self::BITFLAG_TOP), false, false);
|
||||
|
||||
return true;
|
||||
}
|
||||
@ -85,7 +85,7 @@ class DoublePlant extends Flowable{
|
||||
|
||||
public function onNearbyBlockChange() : void{
|
||||
if(!$this->isValidHalfPlant() or (($this->meta & self::BITFLAG_TOP) === 0 and $this->getSide(Vector3::SIDE_DOWN)->isTransparent())){
|
||||
$this->getLevel()->useBreakOn($this);
|
||||
$this->getLevelNonNull()->useBreakOn($this);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -40,9 +40,9 @@ class EnchantingTable extends Transparent{
|
||||
}
|
||||
|
||||
public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, Player $player = null) : bool{
|
||||
$this->getLevel()->setBlock($blockReplace, $this, true, true);
|
||||
$this->getLevelNonNull()->setBlock($blockReplace, $this, true, true);
|
||||
|
||||
Tile::createTile(Tile::ENCHANT_TABLE, $this->getLevel(), TileEnchantTable::createNBT($this, $face, $item, $player));
|
||||
Tile::createTile(Tile::ENCHANT_TABLE, $this->getLevelNonNull(), TileEnchantTable::createNBT($this, $face, $item, $player));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -69,8 +69,8 @@ class EnderChest extends Chest{
|
||||
|
||||
$this->meta = $faces[$player instanceof Player ? $player->getDirection() : 0];
|
||||
|
||||
$this->getLevel()->setBlock($blockReplace, $this, true, true);
|
||||
Tile::createTile(Tile::ENDER_CHEST, $this->getLevel(), TileEnderChest::createNBT($this, $face, $item, $player));
|
||||
$this->getLevelNonNull()->setBlock($blockReplace, $this, true, true);
|
||||
Tile::createTile(Tile::ENDER_CHEST, $this->getLevelNonNull(), TileEnderChest::createNBT($this, $face, $item, $player));
|
||||
|
||||
return true;
|
||||
}
|
||||
@ -78,12 +78,12 @@ class EnderChest extends Chest{
|
||||
public function onActivate(Item $item, Player $player = null) : bool{
|
||||
if($player instanceof Player){
|
||||
|
||||
$t = $this->getLevel()->getTile($this);
|
||||
$t = $this->getLevelNonNull()->getTile($this);
|
||||
$enderChest = null;
|
||||
if($t instanceof TileEnderChest){
|
||||
$enderChest = $t;
|
||||
}else{
|
||||
$enderChest = Tile::createTile(Tile::ENDER_CHEST, $this->getLevel(), TileEnderChest::createNBT($this));
|
||||
$enderChest = Tile::createTile(Tile::ENDER_CHEST, $this->getLevelNonNull(), TileEnderChest::createNBT($this));
|
||||
if(!($enderChest instanceof TileEnderChest)){
|
||||
return true;
|
||||
}
|
||||
|
@ -37,7 +37,7 @@ abstract class Fallable extends Solid{
|
||||
$nbt->setInt("TileID", $this->getId());
|
||||
$nbt->setByte("Data", $this->getDamage());
|
||||
|
||||
$fall = Entity::createEntity("FallingSand", $this->getLevel(), $nbt);
|
||||
$fall = Entity::createEntity("FallingSand", $this->getLevelNonNull(), $nbt);
|
||||
|
||||
if($fall !== null){
|
||||
$fall->spawnToAll();
|
||||
|
@ -69,7 +69,7 @@ class FenceGate extends Transparent{
|
||||
|
||||
public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, Player $player = null) : bool{
|
||||
$this->meta = ($player instanceof Player ? ($player->getDirection() - 1) & 0x03 : 0);
|
||||
$this->getLevel()->setBlock($blockReplace, $this, true, true);
|
||||
$this->getLevelNonNull()->setBlock($blockReplace, $this, true, true);
|
||||
|
||||
return true;
|
||||
}
|
||||
@ -85,7 +85,7 @@ class FenceGate extends Transparent{
|
||||
$this->meta |= (($player->getDirection() - 1) & 0x02);
|
||||
}
|
||||
|
||||
$this->getLevel()->setBlock($this, $this, true);
|
||||
$this->getLevelNonNull()->setBlock($this, $this, true);
|
||||
$this->level->addSound(new DoorSound($this));
|
||||
return true;
|
||||
}
|
||||
|
@ -82,7 +82,7 @@ class Fire extends Flowable{
|
||||
|
||||
public function onNearbyBlockChange() : void{
|
||||
if(!$this->getSide(Vector3::SIDE_DOWN)->isSolid() and !$this->hasAdjacentFlammableBlocks()){
|
||||
$this->getLevel()->setBlock($this, BlockFactory::get(Block::AIR), true);
|
||||
$this->getLevelNonNull()->setBlock($this, BlockFactory::get(Block::AIR), true);
|
||||
}else{
|
||||
$this->level->scheduleDelayedBlockUpdate($this, mt_rand(30, 40));
|
||||
}
|
||||
|
@ -62,7 +62,7 @@ class Flower extends Flowable{
|
||||
public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, Player $player = null) : bool{
|
||||
$down = $this->getSide(Vector3::SIDE_DOWN);
|
||||
if($down->getId() === Block::GRASS or $down->getId() === Block::DIRT or $down->getId() === Block::FARMLAND){
|
||||
$this->getLevel()->setBlock($blockReplace, $this, true);
|
||||
$this->getLevelNonNull()->setBlock($blockReplace, $this, true);
|
||||
|
||||
return true;
|
||||
}
|
||||
@ -72,7 +72,7 @@ class Flower extends Flowable{
|
||||
|
||||
public function onNearbyBlockChange() : void{
|
||||
if($this->getSide(Vector3::SIDE_DOWN)->isTransparent()){
|
||||
$this->getLevel()->useBreakOn($this);
|
||||
$this->getLevelNonNull()->useBreakOn($this);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -62,19 +62,19 @@ class FlowerPot extends Flowable{
|
||||
return false;
|
||||
}
|
||||
|
||||
$this->getLevel()->setBlock($blockReplace, $this, true, true);
|
||||
Tile::createTile(Tile::FLOWER_POT, $this->getLevel(), TileFlowerPot::createNBT($this, $face, $item, $player));
|
||||
$this->getLevelNonNull()->setBlock($blockReplace, $this, true, true);
|
||||
Tile::createTile(Tile::FLOWER_POT, $this->getLevelNonNull(), TileFlowerPot::createNBT($this, $face, $item, $player));
|
||||
return true;
|
||||
}
|
||||
|
||||
public function onNearbyBlockChange() : void{
|
||||
if($this->getSide(Vector3::SIDE_DOWN)->isTransparent()){
|
||||
$this->getLevel()->useBreakOn($this);
|
||||
$this->getLevelNonNull()->useBreakOn($this);
|
||||
}
|
||||
}
|
||||
|
||||
public function onActivate(Item $item, Player $player = null) : bool{
|
||||
$pot = $this->getLevel()->getTile($this);
|
||||
$pot = $this->getLevelNonNull()->getTile($this);
|
||||
if(!($pot instanceof TileFlowerPot)){
|
||||
return false;
|
||||
}
|
||||
@ -83,7 +83,7 @@ class FlowerPot extends Flowable{
|
||||
}
|
||||
|
||||
$this->setDamage(self::STATE_FULL); //specific damage value is unnecessary, it just needs to be non-zero to show an item.
|
||||
$this->getLevel()->setBlock($this, $this, true, false);
|
||||
$this->getLevelNonNull()->setBlock($this, $this, true, false);
|
||||
$pot->setItem($item->pop());
|
||||
|
||||
return true;
|
||||
@ -96,7 +96,7 @@ class FlowerPot extends Flowable{
|
||||
public function getDropsForCompatibleTool(Item $item) : array{
|
||||
$items = parent::getDropsForCompatibleTool($item);
|
||||
|
||||
$tile = $this->getLevel()->getTile($this);
|
||||
$tile = $this->getLevelNonNull()->getTile($this);
|
||||
if($tile instanceof TileFlowerPot){
|
||||
$item = $tile->getItem();
|
||||
if($item->getId() !== Item::AIR){
|
||||
|
@ -53,7 +53,7 @@ class GlazedTerracotta extends Solid{
|
||||
$this->meta = $faces[(~($player->getDirection() - 1)) & 0x03];
|
||||
}
|
||||
|
||||
return $this->getLevel()->setBlock($blockReplace, $this, true, true);
|
||||
return $this->getLevelNonNull()->setBlock($blockReplace, $this, true, true);
|
||||
}
|
||||
|
||||
public function getVariantBitmask() : int{
|
||||
|
@ -53,6 +53,6 @@ class GlowingRedstoneOre extends RedstoneOre{
|
||||
}
|
||||
|
||||
public function onRandomTick() : void{
|
||||
$this->getLevel()->setBlock($this, BlockFactory::get(Block::REDSTONE_ORE, $this->meta), false, false);
|
||||
$this->getLevelNonNull()->setBlock($this, BlockFactory::get(Block::REDSTONE_ORE, $this->meta), false, false);
|
||||
}
|
||||
}
|
||||
|
@ -100,17 +100,17 @@ class Grass extends Solid{
|
||||
public function onActivate(Item $item, Player $player = null) : bool{
|
||||
if($item->getId() === Item::DYE and $item->getDamage() === 0x0F){
|
||||
$item->pop();
|
||||
TallGrassObject::growGrass($this->getLevel(), $this, new Random(mt_rand()), 8, 2);
|
||||
TallGrassObject::growGrass($this->getLevelNonNull(), $this, new Random(mt_rand()), 8, 2);
|
||||
|
||||
return true;
|
||||
}elseif($item instanceof Hoe){
|
||||
$item->applyDamage(1);
|
||||
$this->getLevel()->setBlock($this, BlockFactory::get(Block::FARMLAND));
|
||||
$this->getLevelNonNull()->setBlock($this, BlockFactory::get(Block::FARMLAND));
|
||||
|
||||
return true;
|
||||
}elseif($item instanceof Shovel and $this->getSide(Vector3::SIDE_UP)->getId() === Block::AIR){
|
||||
$item->applyDamage(1);
|
||||
$this->getLevel()->setBlock($this, BlockFactory::get(Block::GRASS_PATH));
|
||||
$this->getLevelNonNull()->setBlock($this, BlockFactory::get(Block::GRASS_PATH));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -46,7 +46,7 @@ class HayBale extends Solid{
|
||||
|
||||
public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, Player $player = null) : bool{
|
||||
$this->meta = PillarRotationHelper::getMetaFromFace($this->meta, $face);
|
||||
$this->getLevel()->setBlock($blockReplace, $this, true, true);
|
||||
$this->getLevelNonNull()->setBlock($blockReplace, $this, true, true);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -57,7 +57,7 @@ class Ice extends Transparent{
|
||||
|
||||
public function onBreak(Item $item, Player $player = null) : bool{
|
||||
if(($player === null or $player->isSurvival()) and !$item->hasEnchantment(Enchantment::SILK_TOUCH)){
|
||||
return $this->getLevel()->setBlock($this, BlockFactory::get(Block::WATER), true);
|
||||
return $this->getLevelNonNull()->setBlock($this, BlockFactory::get(Block::WATER), true);
|
||||
}
|
||||
return parent::onBreak($item, $player);
|
||||
}
|
||||
|
@ -46,7 +46,7 @@ class ItemFrame extends Flowable{
|
||||
public function onActivate(Item $item, Player $player = null) : bool{
|
||||
$tile = $this->level->getTile($this);
|
||||
if(!($tile instanceof TileItemFrame)){
|
||||
$tile = Tile::createTile(Tile::ITEM_FRAME, $this->getLevel(), TileItemFrame::createNBT($this));
|
||||
$tile = Tile::createTile(Tile::ITEM_FRAME, $this->getLevelNonNull(), TileItemFrame::createNBT($this));
|
||||
if(!($tile instanceof TileItemFrame)){
|
||||
return true;
|
||||
}
|
||||
@ -88,7 +88,7 @@ class ItemFrame extends Flowable{
|
||||
$this->meta = $faces[$face];
|
||||
$this->level->setBlock($blockReplace, $this, true, true);
|
||||
|
||||
Tile::createTile(Tile::ITEM_FRAME, $this->getLevel(), TileItemFrame::createNBT($this, $face, $item, $player));
|
||||
Tile::createTile(Tile::ITEM_FRAME, $this->getLevelNonNull(), TileItemFrame::createNBT($this, $face, $item, $player));
|
||||
|
||||
return true;
|
||||
|
||||
|
@ -100,7 +100,7 @@ class Ladder extends Transparent{
|
||||
];
|
||||
if(isset($faces[$face])){
|
||||
$this->meta = $faces[$face];
|
||||
$this->getLevel()->setBlock($blockReplace, $this, true, true);
|
||||
$this->getLevelNonNull()->setBlock($blockReplace, $this, true, true);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -115,8 +115,8 @@ class Lava extends Liquid{
|
||||
}
|
||||
|
||||
public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, Player $player = null) : bool{
|
||||
$ret = $this->getLevel()->setBlock($this, $this, true, false);
|
||||
$this->getLevel()->scheduleDelayedBlockUpdate($this, $this->tickRate());
|
||||
$ret = $this->getLevelNonNull()->setBlock($this, $this, true, false);
|
||||
$this->getLevelNonNull()->scheduleDelayedBlockUpdate($this, $this->tickRate());
|
||||
|
||||
return $ret;
|
||||
}
|
||||
|
@ -139,7 +139,7 @@ class Leaves extends Transparent{
|
||||
public function onNearbyBlockChange() : void{
|
||||
if(($this->meta & 0b00001100) === 0){
|
||||
$this->meta |= 0x08;
|
||||
$this->getLevel()->setBlock($this, $this, true, false);
|
||||
$this->getLevelNonNull()->setBlock($this, $this, true, false);
|
||||
}
|
||||
}
|
||||
|
||||
@ -155,16 +155,16 @@ class Leaves extends Transparent{
|
||||
$ev = new LeavesDecayEvent($this);
|
||||
$ev->call();
|
||||
if($ev->isCancelled() or $this->findLog($this, $visited, 0)){
|
||||
$this->getLevel()->setBlock($this, $this, false, false);
|
||||
$this->getLevelNonNull()->setBlock($this, $this, false, false);
|
||||
}else{
|
||||
$this->getLevel()->useBreakOn($this);
|
||||
$this->getLevelNonNull()->useBreakOn($this);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, Player $player = null) : bool{
|
||||
$this->meta |= 0x04;
|
||||
return $this->getLevel()->setBlock($this, $this, true);
|
||||
return $this->getLevelNonNull()->setBlock($this, $this, true);
|
||||
}
|
||||
|
||||
public function getVariantBitmask() : int{
|
||||
|
@ -49,7 +49,7 @@ class MelonStem extends Crops{
|
||||
$ev = new BlockGrowEvent($this, $block);
|
||||
$ev->call();
|
||||
if(!$ev->isCancelled()){
|
||||
$this->getLevel()->setBlock($this, $ev->getNewState(), true);
|
||||
$this->getLevelNonNull()->setBlock($this, $ev->getNewState(), true);
|
||||
}
|
||||
}else{
|
||||
for($side = 2; $side <= 5; ++$side){
|
||||
@ -64,7 +64,7 @@ class MelonStem extends Crops{
|
||||
$ev = new BlockGrowEvent($side, BlockFactory::get(Block::MELON_BLOCK));
|
||||
$ev->call();
|
||||
if(!$ev->isCancelled()){
|
||||
$this->getLevel()->setBlock($side, $ev->getNewState(), true);
|
||||
$this->getLevelNonNull()->setBlock($side, $ev->getNewState(), true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -64,13 +64,13 @@ class Mycelium extends Solid{
|
||||
$x = mt_rand($this->x - 1, $this->x + 1);
|
||||
$y = mt_rand($this->y - 2, $this->y + 2);
|
||||
$z = mt_rand($this->z - 1, $this->z + 1);
|
||||
$block = $this->getLevel()->getBlockAt($x, $y, $z);
|
||||
$block = $this->getLevelNonNull()->getBlockAt($x, $y, $z);
|
||||
if($block->getId() === Block::DIRT){
|
||||
if($block->getSide(Vector3::SIDE_UP) instanceof Transparent){
|
||||
$ev = new BlockSpreadEvent($block, $this, BlockFactory::get(Block::MYCELIUM));
|
||||
$ev->call();
|
||||
if(!$ev->isCancelled()){
|
||||
$this->getLevel()->setBlock($block, $ev->getNewState());
|
||||
$this->getLevelNonNull()->setBlock($block, $ev->getNewState());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -46,7 +46,7 @@ class NetherWartPlant extends Flowable{
|
||||
public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, Player $player = null) : bool{
|
||||
$down = $this->getSide(Vector3::SIDE_DOWN);
|
||||
if($down->getId() === Block::SOUL_SAND){
|
||||
$this->getLevel()->setBlock($blockReplace, $this, false, true);
|
||||
$this->getLevelNonNull()->setBlock($blockReplace, $this, false, true);
|
||||
|
||||
return true;
|
||||
}
|
||||
@ -56,7 +56,7 @@ class NetherWartPlant extends Flowable{
|
||||
|
||||
public function onNearbyBlockChange() : void{
|
||||
if($this->getSide(Vector3::SIDE_DOWN)->getId() !== Block::SOUL_SAND){
|
||||
$this->getLevel()->useBreakOn($this);
|
||||
$this->getLevelNonNull()->useBreakOn($this);
|
||||
}
|
||||
}
|
||||
|
||||
@ -71,7 +71,7 @@ class NetherWartPlant extends Flowable{
|
||||
$ev = new BlockGrowEvent($this, $block);
|
||||
$ev->call();
|
||||
if(!$ev->isCancelled()){
|
||||
$this->getLevel()->setBlock($this, $ev->getNewState(), false, true);
|
||||
$this->getLevelNonNull()->setBlock($this, $ev->getNewState(), false, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -51,7 +51,7 @@ class Pumpkin extends Solid{
|
||||
if($player instanceof Player){
|
||||
$this->meta = ((int) $player->getDirection() + 1) % 4;
|
||||
}
|
||||
$this->getLevel()->setBlock($blockReplace, $this, true, true);
|
||||
$this->getLevelNonNull()->setBlock($blockReplace, $this, true, true);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -49,7 +49,7 @@ class PumpkinStem extends Crops{
|
||||
$ev = new BlockGrowEvent($this, $block);
|
||||
$ev->call();
|
||||
if(!$ev->isCancelled()){
|
||||
$this->getLevel()->setBlock($this, $ev->getNewState(), true);
|
||||
$this->getLevelNonNull()->setBlock($this, $ev->getNewState(), true);
|
||||
}
|
||||
}else{
|
||||
for($side = 2; $side <= 5; ++$side){
|
||||
@ -64,7 +64,7 @@ class PumpkinStem extends Crops{
|
||||
$ev = new BlockGrowEvent($side, BlockFactory::get(Block::PUMPKIN));
|
||||
$ev->call();
|
||||
if(!$ev->isCancelled()){
|
||||
$this->getLevel()->setBlock($side, $ev->getNewState(), true);
|
||||
$this->getLevelNonNull()->setBlock($side, $ev->getNewState(), true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -58,7 +58,7 @@ class Quartz extends Solid{
|
||||
if($this->getVariant() !== self::NORMAL){
|
||||
$this->meta = PillarRotationHelper::getMetaFromFace($this->meta, $face);
|
||||
}
|
||||
return $this->getLevel()->setBlock($blockReplace, $this, true, true);
|
||||
return $this->getLevelNonNull()->setBlock($blockReplace, $this, true, true);
|
||||
}
|
||||
|
||||
public function getToolType() : int{
|
||||
|
@ -45,14 +45,14 @@ class RedMushroom extends Flowable{
|
||||
|
||||
public function onNearbyBlockChange() : void{
|
||||
if($this->getSide(Vector3::SIDE_DOWN)->isTransparent()){
|
||||
$this->getLevel()->useBreakOn($this);
|
||||
$this->getLevelNonNull()->useBreakOn($this);
|
||||
}
|
||||
}
|
||||
|
||||
public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, Player $player = null) : bool{
|
||||
$down = $this->getSide(Vector3::SIDE_DOWN);
|
||||
if(!$down->isTransparent()){
|
||||
$this->getLevel()->setBlock($blockReplace, $this, true, true);
|
||||
$this->getLevelNonNull()->setBlock($blockReplace, $this, true, true);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -47,16 +47,16 @@ class RedstoneOre extends Solid{
|
||||
}
|
||||
|
||||
public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, Player $player = null) : bool{
|
||||
return $this->getLevel()->setBlock($this, $this, true, false);
|
||||
return $this->getLevelNonNull()->setBlock($this, $this, true, false);
|
||||
}
|
||||
|
||||
public function onActivate(Item $item, Player $player = null) : bool{
|
||||
$this->getLevel()->setBlock($this, BlockFactory::get(Block::GLOWING_REDSTONE_ORE, $this->meta));
|
||||
$this->getLevelNonNull()->setBlock($this, BlockFactory::get(Block::GLOWING_REDSTONE_ORE, $this->meta));
|
||||
return false; //this shouldn't prevent block placement
|
||||
}
|
||||
|
||||
public function onNearbyBlockChange() : void{
|
||||
$this->getLevel()->setBlock($this, BlockFactory::get(Block::GLOWING_REDSTONE_ORE, $this->meta));
|
||||
$this->getLevelNonNull()->setBlock($this, BlockFactory::get(Block::GLOWING_REDSTONE_ORE, $this->meta));
|
||||
}
|
||||
|
||||
public function getToolType() : int{
|
||||
|
@ -59,7 +59,7 @@ class Sapling extends Flowable{
|
||||
public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, Player $player = null) : bool{
|
||||
$down = $this->getSide(Vector3::SIDE_DOWN);
|
||||
if($down->getId() === self::GRASS or $down->getId() === self::DIRT or $down->getId() === self::FARMLAND){
|
||||
$this->getLevel()->setBlock($blockReplace, $this, true, true);
|
||||
$this->getLevelNonNull()->setBlock($blockReplace, $this, true, true);
|
||||
|
||||
return true;
|
||||
}
|
||||
@ -70,7 +70,7 @@ class Sapling extends Flowable{
|
||||
public function onActivate(Item $item, Player $player = null) : bool{
|
||||
if($item->getId() === Item::DYE and $item->getDamage() === 0x0F){ //Bonemeal
|
||||
//TODO: change log type
|
||||
Tree::growTree($this->getLevel(), $this->x, $this->y, $this->z, new Random(mt_rand()), $this->getVariant());
|
||||
Tree::growTree($this->getLevelNonNull(), $this->x, $this->y, $this->z, new Random(mt_rand()), $this->getVariant());
|
||||
|
||||
$item->pop();
|
||||
|
||||
@ -82,7 +82,7 @@ class Sapling extends Flowable{
|
||||
|
||||
public function onNearbyBlockChange() : void{
|
||||
if($this->getSide(Vector3::SIDE_DOWN)->isTransparent()){
|
||||
$this->getLevel()->useBreakOn($this);
|
||||
$this->getLevelNonNull()->useBreakOn($this);
|
||||
}
|
||||
}
|
||||
|
||||
@ -93,10 +93,10 @@ class Sapling extends Flowable{
|
||||
public function onRandomTick() : void{
|
||||
if($this->level->getFullLightAt($this->x, $this->y, $this->z) >= 8 and mt_rand(1, 7) === 1){
|
||||
if(($this->meta & 0x08) === 0x08){
|
||||
Tree::growTree($this->getLevel(), $this->x, $this->y, $this->z, new Random(mt_rand()), $this->getVariant());
|
||||
Tree::growTree($this->getLevelNonNull(), $this->x, $this->y, $this->z, new Random(mt_rand()), $this->getVariant());
|
||||
}else{
|
||||
$this->meta |= 0x08;
|
||||
$this->getLevel()->setBlock($this, $this, true);
|
||||
$this->getLevelNonNull()->setBlock($this, $this, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -62,13 +62,13 @@ class SignPost extends Transparent{
|
||||
|
||||
if($face === Vector3::SIDE_UP){
|
||||
$this->meta = $player !== null ? (floor((($player->yaw + 180) * 16 / 360) + 0.5) & 0x0f) : 0;
|
||||
$this->getLevel()->setBlock($blockReplace, $this, true);
|
||||
$this->getLevelNonNull()->setBlock($blockReplace, $this, true);
|
||||
}else{
|
||||
$this->meta = $face;
|
||||
$this->getLevel()->setBlock($blockReplace, BlockFactory::get(Block::WALL_SIGN, $this->meta), true);
|
||||
$this->getLevelNonNull()->setBlock($blockReplace, BlockFactory::get(Block::WALL_SIGN, $this->meta), true);
|
||||
}
|
||||
|
||||
Tile::createTile(Tile::SIGN, $this->getLevel(), TileSign::createNBT($this, $face, $item, $player));
|
||||
Tile::createTile(Tile::SIGN, $this->getLevelNonNull(), TileSign::createNBT($this, $face, $item, $player));
|
||||
|
||||
return true;
|
||||
}
|
||||
@ -78,7 +78,7 @@ class SignPost extends Transparent{
|
||||
|
||||
public function onNearbyBlockChange() : void{
|
||||
if($this->getSide(Vector3::SIDE_DOWN)->getId() === self::AIR){
|
||||
$this->getLevel()->useBreakOn($this);
|
||||
$this->getLevelNonNull()->useBreakOn($this);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -65,8 +65,8 @@ class Skull extends Flowable{
|
||||
}
|
||||
|
||||
$this->meta = $face;
|
||||
$this->getLevel()->setBlock($blockReplace, $this, true);
|
||||
Tile::createTile(Tile::SKULL, $this->getLevel(), TileSkull::createNBT($this, $face, $item, $player));
|
||||
$this->getLevelNonNull()->setBlock($blockReplace, $this, true);
|
||||
Tile::createTile(Tile::SKULL, $this->getLevelNonNull(), TileSkull::createNBT($this, $face, $item, $player));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -56,11 +56,11 @@ abstract class Slab extends Transparent{
|
||||
$this->meta &= 0x07;
|
||||
if($face === Vector3::SIDE_DOWN){
|
||||
if($blockClicked->getId() === $this->id and ($blockClicked->getDamage() & 0x08) === 0x08 and $blockClicked->getVariant() === $this->getVariant()){
|
||||
$this->getLevel()->setBlock($blockClicked, BlockFactory::get($this->getDoubleSlabId(), $this->getVariant()), true);
|
||||
$this->getLevelNonNull()->setBlock($blockClicked, BlockFactory::get($this->getDoubleSlabId(), $this->getVariant()), true);
|
||||
|
||||
return true;
|
||||
}elseif($blockReplace->getId() === $this->id and $blockReplace->getVariant() === $this->getVariant()){
|
||||
$this->getLevel()->setBlock($blockReplace, BlockFactory::get($this->getDoubleSlabId(), $this->getVariant()), true);
|
||||
$this->getLevelNonNull()->setBlock($blockReplace, BlockFactory::get($this->getDoubleSlabId(), $this->getVariant()), true);
|
||||
|
||||
return true;
|
||||
}else{
|
||||
@ -68,18 +68,18 @@ abstract class Slab extends Transparent{
|
||||
}
|
||||
}elseif($face === Vector3::SIDE_UP){
|
||||
if($blockClicked->getId() === $this->id and ($blockClicked->getDamage() & 0x08) === 0 and $blockClicked->getVariant() === $this->getVariant()){
|
||||
$this->getLevel()->setBlock($blockClicked, BlockFactory::get($this->getDoubleSlabId(), $this->getVariant()), true);
|
||||
$this->getLevelNonNull()->setBlock($blockClicked, BlockFactory::get($this->getDoubleSlabId(), $this->getVariant()), true);
|
||||
|
||||
return true;
|
||||
}elseif($blockReplace->getId() === $this->id and $blockReplace->getVariant() === $this->getVariant()){
|
||||
$this->getLevel()->setBlock($blockReplace, BlockFactory::get($this->getDoubleSlabId(), $this->getVariant()), true);
|
||||
$this->getLevelNonNull()->setBlock($blockReplace, BlockFactory::get($this->getDoubleSlabId(), $this->getVariant()), true);
|
||||
|
||||
return true;
|
||||
}
|
||||
}else{ //TODO: collision
|
||||
if($blockReplace->getId() === $this->id){
|
||||
if($blockReplace->getVariant() === $this->getVariant()){
|
||||
$this->getLevel()->setBlock($blockReplace, BlockFactory::get($this->getDoubleSlabId(), $this->getVariant()), true);
|
||||
$this->getLevelNonNull()->setBlock($blockReplace, BlockFactory::get($this->getDoubleSlabId(), $this->getVariant()), true);
|
||||
|
||||
return true;
|
||||
}
|
||||
@ -95,7 +95,7 @@ abstract class Slab extends Transparent{
|
||||
if($blockReplace->getId() === $this->id and $blockClicked->getVariant() !== $this->getVariant()){
|
||||
return false;
|
||||
}
|
||||
$this->getLevel()->setBlock($blockReplace, $this, true, true);
|
||||
$this->getLevelNonNull()->setBlock($blockReplace, $this, true, true);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -60,7 +60,7 @@ class SnowLayer extends Flowable{
|
||||
public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, Player $player = null) : bool{
|
||||
if($blockReplace->getSide(Vector3::SIDE_DOWN)->isSolid()){
|
||||
//TODO: fix placement
|
||||
$this->getLevel()->setBlock($blockReplace, $this, true);
|
||||
$this->getLevelNonNull()->setBlock($blockReplace, $this, true);
|
||||
|
||||
return true;
|
||||
}
|
||||
@ -70,7 +70,7 @@ class SnowLayer extends Flowable{
|
||||
|
||||
public function onNearbyBlockChange() : void{
|
||||
if(!$this->getSide(Vector3::SIDE_DOWN)->isSolid()){
|
||||
$this->getLevel()->setBlock($this, BlockFactory::get(Block::AIR), false, false);
|
||||
$this->getLevelNonNull()->setBlock($this, BlockFactory::get(Block::AIR), false, false);
|
||||
}
|
||||
}
|
||||
|
||||
@ -80,7 +80,7 @@ class SnowLayer extends Flowable{
|
||||
|
||||
public function onRandomTick() : void{
|
||||
if($this->level->getBlockLightAt($this->x, $this->y, $this->z) >= 12){
|
||||
$this->getLevel()->setBlock($this, BlockFactory::get(Block::AIR), false, false);
|
||||
$this->getLevelNonNull()->setBlock($this, BlockFactory::get(Block::AIR), false, false);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -93,7 +93,7 @@ abstract class Stair extends Transparent{
|
||||
if(($clickVector->y > 0.5 and $face !== Vector3::SIDE_UP) or $face === Vector3::SIDE_DOWN){
|
||||
$this->meta |= 0x04; //Upside-down stairs
|
||||
}
|
||||
$this->getLevel()->setBlock($blockReplace, $this, true, true);
|
||||
$this->getLevelNonNull()->setBlock($blockReplace, $this, true, true);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -62,13 +62,13 @@ class StandingBanner extends Transparent{
|
||||
if($face !== Vector3::SIDE_DOWN){
|
||||
if($face === Vector3::SIDE_UP and $player !== null){
|
||||
$this->meta = floor((($player->yaw + 180) * 16 / 360) + 0.5) & 0x0f;
|
||||
$this->getLevel()->setBlock($blockReplace, $this, true);
|
||||
$this->getLevelNonNull()->setBlock($blockReplace, $this, true);
|
||||
}else{
|
||||
$this->meta = $face;
|
||||
$this->getLevel()->setBlock($blockReplace, BlockFactory::get(Block::WALL_BANNER, $this->meta), true);
|
||||
$this->getLevelNonNull()->setBlock($blockReplace, BlockFactory::get(Block::WALL_BANNER, $this->meta), true);
|
||||
}
|
||||
|
||||
Tile::createTile(Tile::BANNER, $this->getLevel(), TileBanner::createNBT($this, $face, $item, $player));
|
||||
Tile::createTile(Tile::BANNER, $this->getLevelNonNull(), TileBanner::createNBT($this, $face, $item, $player));
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -77,7 +77,7 @@ class StandingBanner extends Transparent{
|
||||
|
||||
public function onNearbyBlockChange() : void{
|
||||
if($this->getSide(Vector3::SIDE_DOWN)->getId() === self::AIR){
|
||||
$this->getLevel()->useBreakOn($this);
|
||||
$this->getLevelNonNull()->useBreakOn($this);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -46,20 +46,20 @@ class Sugarcane extends Flowable{
|
||||
if($item->getId() === Item::DYE and $item->getDamage() === 0x0F){ //Bonemeal
|
||||
if($this->getSide(Vector3::SIDE_DOWN)->getId() !== self::SUGARCANE_BLOCK){
|
||||
for($y = 1; $y < 3; ++$y){
|
||||
$b = $this->getLevel()->getBlockAt($this->x, $this->y + $y, $this->z);
|
||||
$b = $this->getLevelNonNull()->getBlockAt($this->x, $this->y + $y, $this->z);
|
||||
if($b->getId() === self::AIR){
|
||||
$ev = new BlockGrowEvent($b, BlockFactory::get(Block::SUGARCANE_BLOCK));
|
||||
$ev->call();
|
||||
if($ev->isCancelled()){
|
||||
break;
|
||||
}
|
||||
$this->getLevel()->setBlock($b, $ev->getNewState(), true);
|
||||
$this->getLevelNonNull()->setBlock($b, $ev->getNewState(), true);
|
||||
}else{
|
||||
break;
|
||||
}
|
||||
}
|
||||
$this->meta = 0;
|
||||
$this->getLevel()->setBlock($this, $this, true);
|
||||
$this->getLevelNonNull()->setBlock($this, $this, true);
|
||||
}
|
||||
|
||||
$item->pop();
|
||||
@ -73,7 +73,7 @@ class Sugarcane extends Flowable{
|
||||
public function onNearbyBlockChange() : void{
|
||||
$down = $this->getSide(Vector3::SIDE_DOWN);
|
||||
if($down->isTransparent() and $down->getId() !== self::SUGARCANE_BLOCK){
|
||||
$this->getLevel()->useBreakOn($this);
|
||||
$this->getLevelNonNull()->useBreakOn($this);
|
||||
}
|
||||
}
|
||||
|
||||
@ -85,17 +85,17 @@ class Sugarcane extends Flowable{
|
||||
if($this->getSide(Vector3::SIDE_DOWN)->getId() !== self::SUGARCANE_BLOCK){
|
||||
if($this->meta === 0x0F){
|
||||
for($y = 1; $y < 3; ++$y){
|
||||
$b = $this->getLevel()->getBlockAt($this->x, $this->y + $y, $this->z);
|
||||
$b = $this->getLevelNonNull()->getBlockAt($this->x, $this->y + $y, $this->z);
|
||||
if($b->getId() === self::AIR){
|
||||
$this->getLevel()->setBlock($b, BlockFactory::get(Block::SUGARCANE_BLOCK), true);
|
||||
$this->getLevelNonNull()->setBlock($b, BlockFactory::get(Block::SUGARCANE_BLOCK), true);
|
||||
break;
|
||||
}
|
||||
}
|
||||
$this->meta = 0;
|
||||
$this->getLevel()->setBlock($this, $this, true);
|
||||
$this->getLevelNonNull()->setBlock($this, $this, true);
|
||||
}else{
|
||||
++$this->meta;
|
||||
$this->getLevel()->setBlock($this, $this, true);
|
||||
$this->getLevelNonNull()->setBlock($this, $this, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -103,7 +103,7 @@ class Sugarcane extends Flowable{
|
||||
public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, Player $player = null) : bool{
|
||||
$down = $this->getSide(Vector3::SIDE_DOWN);
|
||||
if($down->getId() === self::SUGARCANE_BLOCK){
|
||||
$this->getLevel()->setBlock($blockReplace, BlockFactory::get(Block::SUGARCANE_BLOCK), true);
|
||||
$this->getLevelNonNull()->setBlock($blockReplace, BlockFactory::get(Block::SUGARCANE_BLOCK), true);
|
||||
|
||||
return true;
|
||||
}elseif($down->getId() === self::GRASS or $down->getId() === self::DIRT or $down->getId() === self::SAND){
|
||||
@ -112,7 +112,7 @@ class Sugarcane extends Flowable{
|
||||
$block2 = $down->getSide(Vector3::SIDE_WEST);
|
||||
$block3 = $down->getSide(Vector3::SIDE_EAST);
|
||||
if(($block0 instanceof Water) or ($block1 instanceof Water) or ($block2 instanceof Water) or ($block3 instanceof Water)){
|
||||
$this->getLevel()->setBlock($blockReplace, BlockFactory::get(Block::SUGARCANE_BLOCK), true);
|
||||
$this->getLevelNonNull()->setBlock($blockReplace, BlockFactory::get(Block::SUGARCANE_BLOCK), true);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -78,13 +78,13 @@ class TNT extends Solid{
|
||||
* @return void
|
||||
*/
|
||||
public function ignite(int $fuse = 80){
|
||||
$this->getLevel()->setBlock($this, BlockFactory::get(Block::AIR), true);
|
||||
$this->getLevelNonNull()->setBlock($this, BlockFactory::get(Block::AIR), true);
|
||||
|
||||
$mot = (new Random())->nextSignedFloat() * M_PI * 2;
|
||||
$nbt = Entity::createBaseNBT($this->add(0.5, 0, 0.5), new Vector3(-sin($mot) * 0.02, 0.2, -cos($mot) * 0.02));
|
||||
$nbt->setShort("Fuse", $fuse);
|
||||
|
||||
$tnt = Entity::createEntity("PrimedTNT", $this->getLevel(), $nbt);
|
||||
$tnt = Entity::createEntity("PrimedTNT", $this->getLevelNonNull(), $nbt);
|
||||
|
||||
if($tnt !== null){
|
||||
$tnt->spawnToAll();
|
||||
|
@ -53,7 +53,7 @@ class TallGrass extends Flowable{
|
||||
public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, Player $player = null) : bool{
|
||||
$down = $this->getSide(Vector3::SIDE_DOWN)->getId();
|
||||
if($down === self::GRASS or $down === self::DIRT){
|
||||
$this->getLevel()->setBlock($blockReplace, $this, true);
|
||||
$this->getLevelNonNull()->setBlock($blockReplace, $this, true);
|
||||
|
||||
return true;
|
||||
}
|
||||
@ -63,7 +63,7 @@ class TallGrass extends Flowable{
|
||||
|
||||
public function onNearbyBlockChange() : void{
|
||||
if($this->getSide(Vector3::SIDE_DOWN)->isTransparent()){ //Replace with common break method
|
||||
$this->getLevel()->setBlock($this, BlockFactory::get(Block::AIR), true, true);
|
||||
$this->getLevelNonNull()->setBlock($this, BlockFactory::get(Block::AIR), true, true);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -57,7 +57,7 @@ class Torch extends Flowable{
|
||||
$face = $faces[$meta] ?? Vector3::SIDE_DOWN;
|
||||
|
||||
if($this->getSide($face)->isTransparent() and !($face === Vector3::SIDE_DOWN and ($below->getId() === self::FENCE or $below->getId() === self::COBBLESTONE_WALL))){
|
||||
$this->getLevel()->useBreakOn($this);
|
||||
$this->getLevelNonNull()->useBreakOn($this);
|
||||
}
|
||||
}
|
||||
|
||||
@ -73,12 +73,12 @@ class Torch extends Flowable{
|
||||
Vector3::SIDE_EAST => 1
|
||||
];
|
||||
$this->meta = $faces[$face];
|
||||
$this->getLevel()->setBlock($blockReplace, $this, true, true);
|
||||
$this->getLevelNonNull()->setBlock($blockReplace, $this, true, true);
|
||||
|
||||
return true;
|
||||
}elseif(!$below->isTransparent() or $below->getId() === self::FENCE or $below->getId() === self::COBBLESTONE_WALL){
|
||||
$this->meta = 0;
|
||||
$this->getLevel()->setBlock($blockReplace, $this, true, true);
|
||||
$this->getLevelNonNull()->setBlock($blockReplace, $this, true, true);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -136,7 +136,7 @@ class Trapdoor extends Transparent{
|
||||
if(($clickVector->y > 0.5 and $face !== self::SIDE_UP) or $face === self::SIDE_DOWN){
|
||||
$this->meta |= self::MASK_UPPER; //top half of block
|
||||
}
|
||||
$this->getLevel()->setBlock($blockReplace, $this, true, true);
|
||||
$this->getLevelNonNull()->setBlock($blockReplace, $this, true, true);
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -146,7 +146,7 @@ class Trapdoor extends Transparent{
|
||||
|
||||
public function onActivate(Item $item, Player $player = null) : bool{
|
||||
$this->meta ^= self::MASK_OPENED;
|
||||
$this->getLevel()->setBlock($this, $this, true);
|
||||
$this->getLevelNonNull()->setBlock($this, $this, true);
|
||||
$this->level->addSound(new DoorSound($this));
|
||||
return true;
|
||||
}
|
||||
|
@ -150,7 +150,7 @@ class Vine extends Flowable{
|
||||
$this->meta |= $blockReplace->meta;
|
||||
}
|
||||
|
||||
$this->getLevel()->setBlock($blockReplace, $this, true, true);
|
||||
$this->getLevelNonNull()->setBlock($blockReplace, $this, true, true);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -33,7 +33,7 @@ class WallBanner extends StandingBanner{
|
||||
|
||||
public function onNearbyBlockChange() : void{
|
||||
if($this->getSide($this->meta ^ 0x01)->getId() === self::AIR){
|
||||
$this->getLevel()->useBreakOn($this);
|
||||
$this->getLevelNonNull()->useBreakOn($this);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -33,7 +33,7 @@ class WallSign extends SignPost{
|
||||
|
||||
public function onNearbyBlockChange() : void{
|
||||
if($this->getSide($this->meta ^ 0x01)->getId() === self::AIR){
|
||||
$this->getLevel()->useBreakOn($this);
|
||||
$this->getLevelNonNull()->useBreakOn($this);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -75,8 +75,8 @@ class Water extends Liquid{
|
||||
}
|
||||
|
||||
public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, Player $player = null) : bool{
|
||||
$ret = $this->getLevel()->setBlock($this, $this, true, false);
|
||||
$this->getLevel()->scheduleDelayedBlockUpdate($this, $this->tickRate());
|
||||
$ret = $this->getLevelNonNull()->setBlock($this, $this, true, false);
|
||||
$this->getLevelNonNull()->scheduleDelayedBlockUpdate($this, $this->tickRate());
|
||||
|
||||
return $ret;
|
||||
}
|
||||
|
@ -59,7 +59,7 @@ class WaterLily extends Flowable{
|
||||
if($blockClicked instanceof Water){
|
||||
$up = $blockClicked->getSide(Vector3::SIDE_UP);
|
||||
if($up->getId() === Block::AIR){
|
||||
$this->getLevel()->setBlock($up, $this, true, true);
|
||||
$this->getLevelNonNull()->setBlock($up, $this, true, true);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@ -69,7 +69,7 @@ class WaterLily extends Flowable{
|
||||
|
||||
public function onNearbyBlockChange() : void{
|
||||
if(!($this->getSide(Vector3::SIDE_DOWN) instanceof Water)){
|
||||
$this->getLevel()->useBreakOn($this);
|
||||
$this->getLevelNonNull()->useBreakOn($this);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -56,7 +56,7 @@ class Wood extends Solid{
|
||||
|
||||
public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, Player $player = null) : bool{
|
||||
$this->meta = PillarRotationHelper::getMetaFromFace($this->meta, $face);
|
||||
return $this->getLevel()->setBlock($blockReplace, $this, true, true);
|
||||
return $this->getLevelNonNull()->setBlock($blockReplace, $this, true, true);
|
||||
}
|
||||
|
||||
public function getVariantBitmask() : int{
|
||||
|
@ -1743,7 +1743,7 @@ abstract class Entity extends Location implements Metadatable, EntityIds{
|
||||
}
|
||||
|
||||
if($pos instanceof Position and $pos->level !== null and $pos->level !== $this->level){
|
||||
if(!$this->switchLevel($pos->getLevel())){
|
||||
if(!$this->switchLevel($pos->getLevelNonNull())){
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@ -1849,7 +1849,7 @@ abstract class Entity extends Location implements Metadatable, EntityIds{
|
||||
$pitch = $pitch ?? $pos->pitch;
|
||||
}
|
||||
$from = Position::fromObject($this, $this->level);
|
||||
$to = Position::fromObject($pos, $pos instanceof Position ? $pos->getLevel() : $this->level);
|
||||
$to = Position::fromObject($pos, $pos instanceof Position ? $pos->getLevelNonNull() : $this->level);
|
||||
$ev = new EntityTeleportEvent($this, $from, $to);
|
||||
$ev->call();
|
||||
if($ev->isCancelled()){
|
||||
|
@ -191,7 +191,7 @@ abstract class Living extends Entity implements Damageable{
|
||||
public function hasLineOfSight(Entity $entity) : bool{
|
||||
//TODO: head height
|
||||
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;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -615,7 +615,7 @@ abstract class Living extends Entity implements Damageable{
|
||||
$ev = new EntityDeathEvent($this, $this->getDrops(), $this->getXpDropAmount());
|
||||
$ev->call();
|
||||
foreach($ev->getDrops() as $item){
|
||||
$this->getLevel()->dropItem($this, $item);
|
||||
$this->getLevelNonNull()->dropItem($this, $item);
|
||||
}
|
||||
|
||||
//TODO: check death conditions (must have been damaged by player < 5 seconds from death)
|
||||
|
@ -98,7 +98,7 @@ class FallingBlock extends Entity{
|
||||
$hasUpdate = parent::entityBaseTick($tickDiff);
|
||||
|
||||
if(!$this->isFlaggedForDespawn()){
|
||||
$pos = Position::fromObject($this->add(-$this->width / 2, $this->height, -$this->width / 2)->floor(), $this->getLevel());
|
||||
$pos = Position::fromObject($this->add(-$this->width / 2, $this->height, -$this->width / 2)->floor(), $this->getLevelNonNull());
|
||||
|
||||
$this->block->position($pos);
|
||||
|
||||
@ -113,12 +113,12 @@ class FallingBlock extends Entity{
|
||||
$block = $this->level->getBlock($pos);
|
||||
if(($block->isTransparent() and !$block->canBeReplaced()) or ($this->onGround and abs($this->y - $this->getFloorY()) > 0.001)){
|
||||
//FIXME: anvils are supposed to destroy torches
|
||||
$this->getLevel()->dropItem($this, ItemFactory::get($this->getBlock(), $this->getDamage()));
|
||||
$this->getLevelNonNull()->dropItem($this, ItemFactory::get($this->getBlock(), $this->getDamage()));
|
||||
}else{
|
||||
$ev = new EntityBlockChangeEvent($this, $block, $blockTarget ?? $this->block);
|
||||
$ev->call();
|
||||
if(!$ev->isCancelled()){
|
||||
$this->getLevel()->setBlock($pos, $ev->getTo(), true);
|
||||
$this->getLevelNonNull()->setBlock($pos, $ev->getTo(), true);
|
||||
}
|
||||
}
|
||||
$hasUpdate = true;
|
||||
|
@ -44,6 +44,6 @@ class EntityDamageByChildEntityEvent extends EntityDamageByEntityEvent{
|
||||
* Returns the entity which caused the damage, or null if the entity has been killed or closed.
|
||||
*/
|
||||
public function getChild() : ?Entity{
|
||||
return $this->getEntity()->getLevel()->getServer()->findEntity($this->childEntityEid);
|
||||
return $this->getEntity()->getLevelNonNull()->getServer()->findEntity($this->childEntityEid);
|
||||
}
|
||||
}
|
||||
|
@ -62,7 +62,7 @@ class EntityDamageByEntityEvent extends EntityDamageEvent{
|
||||
* Returns the attacking entity, or null if the attacker has been killed or closed.
|
||||
*/
|
||||
public function getDamager() : ?Entity{
|
||||
return $this->getEntity()->getLevel()->getServer()->findEntity($this->damagerEntityId);
|
||||
return $this->getEntity()->getLevelNonNull()->getServer()->findEntity($this->damagerEntityId);
|
||||
}
|
||||
|
||||
public function getKnockBack() : float{
|
||||
|
@ -74,7 +74,7 @@ class ChestInventory extends ContainerInventory{
|
||||
if(count($this->getViewers()) === 1 and $this->getHolder()->isValid()){
|
||||
//TODO: this crap really shouldn't be managed by the inventory
|
||||
$this->broadcastBlockEventPacket(true);
|
||||
$this->getHolder()->getLevel()->broadcastLevelSoundEvent($this->getHolder()->add(0.5, 0.5, 0.5), $this->getOpenSound());
|
||||
$this->getHolder()->getLevelNonNull()->broadcastLevelSoundEvent($this->getHolder()->add(0.5, 0.5, 0.5), $this->getOpenSound());
|
||||
}
|
||||
}
|
||||
|
||||
@ -82,7 +82,7 @@ class ChestInventory extends ContainerInventory{
|
||||
if(count($this->getViewers()) === 1 and $this->getHolder()->isValid()){
|
||||
//TODO: this crap really shouldn't be managed by the inventory
|
||||
$this->broadcastBlockEventPacket(false);
|
||||
$this->getHolder()->getLevel()->broadcastLevelSoundEvent($this->getHolder()->add(0.5, 0.5, 0.5), $this->getCloseSound());
|
||||
$this->getHolder()->getLevelNonNull()->broadcastLevelSoundEvent($this->getHolder()->add(0.5, 0.5, 0.5), $this->getCloseSound());
|
||||
}
|
||||
parent::onClose($who);
|
||||
}
|
||||
@ -96,6 +96,6 @@ class ChestInventory extends ContainerInventory{
|
||||
$pk->z = (int) $holder->z;
|
||||
$pk->eventType = 1; //it's always 1 for a chest
|
||||
$pk->eventData = $isOpen ? 1 : 0;
|
||||
$holder->getLevel()->broadcastPacketToViewers($holder, $pk);
|
||||
$holder->getLevelNonNull()->broadcastPacketToViewers($holder, $pk);
|
||||
}
|
||||
}
|
||||
|
@ -56,7 +56,7 @@ class EnderChestInventory extends ChestInventory{
|
||||
*/
|
||||
public function setHolderPosition(EnderChest $enderChest){
|
||||
$this->holder->setComponents($enderChest->getFloorX(), $enderChest->getFloorY(), $enderChest->getFloorZ());
|
||||
$this->holder->setLevel($enderChest->getLevel());
|
||||
$this->holder->setLevel($enderChest->getLevelNonNull());
|
||||
}
|
||||
|
||||
protected function getOpenSound() : int{
|
||||
|
@ -173,7 +173,7 @@ class PlayerInventory extends BaseInventory{
|
||||
$this->sendSlot($this->getHeldItemIndex(), $target);
|
||||
}
|
||||
}else{
|
||||
$this->getHolder()->getLevel()->getServer()->broadcastPacket($target, $pk);
|
||||
$this->getHolder()->getLevelNonNull()->getServer()->broadcastPacket($target, $pk);
|
||||
if(in_array($this->getHolder(), $target, true)){
|
||||
$this->sendSlot($this->getHeldItemIndex(), $this->getHolder());
|
||||
}
|
||||
|
@ -50,11 +50,10 @@ class ChorusFruit extends Food{
|
||||
}
|
||||
|
||||
public function onConsume(Living $consumer){
|
||||
$level = $consumer->getLevel();
|
||||
assert($level !== null);
|
||||
$level = $consumer->getLevelNonNull();
|
||||
|
||||
$minX = $consumer->getFloorX() - 8;
|
||||
$minY = min($consumer->getFloorY(), $consumer->getLevel()->getWorldHeight()) - 8;
|
||||
$minY = min($consumer->getFloorY(), $consumer->getLevelNonNull()->getWorldHeight()) - 8;
|
||||
$minZ = $consumer->getFloorZ() - 8;
|
||||
|
||||
$maxX = $minX + 16;
|
||||
|
@ -93,7 +93,7 @@ class PaintingItem extends Item{
|
||||
$nbt->setInt("TileY", $blockClicked->getFloorY());
|
||||
$nbt->setInt("TileZ", $blockClicked->getFloorZ());
|
||||
|
||||
$entity = Entity::createEntity("Painting", $blockReplace->getLevel(), $nbt);
|
||||
$entity = Entity::createEntity("Painting", $blockReplace->getLevelNonNull(), $nbt);
|
||||
|
||||
if($entity instanceof Entity){
|
||||
$this->pop();
|
||||
|
@ -74,7 +74,7 @@ class Explosion{
|
||||
throw new \InvalidArgumentException("Position does not have a valid world");
|
||||
}
|
||||
$this->source = $center;
|
||||
$this->level = $center->getLevel();
|
||||
$this->level = $center->getLevelNonNull();
|
||||
|
||||
if($size <= 0){
|
||||
throw new \InvalidArgumentException("Explosion radius must be greater than 0, got $size");
|
||||
|
@ -75,7 +75,7 @@ class Location extends Position{
|
||||
}
|
||||
|
||||
public function __toString(){
|
||||
return "Location (level=" . ($this->isValid() ? $this->getLevel()->getName() : "null") . ", x=$this->x, y=$this->y, z=$this->z, yaw=$this->yaw, pitch=$this->pitch)";
|
||||
return "Location (level=" . ($this->isValid() ? $this->getLevelNonNull()->getName() : "null") . ", x=$this->x, y=$this->y, z=$this->z, yaw=$this->yaw, pitch=$this->pitch)";
|
||||
}
|
||||
|
||||
public function equals(Vector3 $v) : bool{
|
||||
|
@ -25,6 +25,7 @@ namespace pocketmine\level;
|
||||
|
||||
use pocketmine\math\Vector3;
|
||||
use pocketmine\utils\MainLogger;
|
||||
use pocketmine\utils\AssumptionFailedError;
|
||||
use function assert;
|
||||
|
||||
class Position extends Vector3{
|
||||
@ -71,6 +72,19 @@ class Position extends Vector3{
|
||||
return $this->level;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the position's world if valid. Throws an error if the world is unexpectedly null.
|
||||
*
|
||||
* @throws AssumptionFailedError
|
||||
*/
|
||||
public function getLevelNonNull() : Level{
|
||||
$world = $this->getLevel();
|
||||
if($world === null){
|
||||
throw new AssumptionFailedError("Position world is null");
|
||||
}
|
||||
return $world;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the target Level of the position.
|
||||
*
|
||||
@ -112,7 +126,7 @@ class Position extends Vector3{
|
||||
}
|
||||
|
||||
public function __toString(){
|
||||
return "Position(level=" . ($this->isValid() ? $this->getLevel()->getName() : "null") . ",x=" . $this->x . ",y=" . $this->y . ",z=" . $this->z . ")";
|
||||
return "Position(level=" . ($this->isValid() ? $this->getLevelNonNull()->getName() : "null") . ",x=" . $this->x . ",y=" . $this->y . ",z=" . $this->z . ")";
|
||||
}
|
||||
|
||||
public function equals(Vector3 $v) : bool{
|
||||
|
@ -121,7 +121,7 @@ class Chest extends Spawnable implements InventoryHolder, Container, Nameable{
|
||||
* @return void
|
||||
*/
|
||||
protected function checkPairing(){
|
||||
if($this->isPaired() and !$this->getLevel()->isInLoadedTerrain(new Vector3($this->pairX, $this->y, $this->pairZ))){
|
||||
if($this->isPaired() and !$this->getLevelNonNull()->isInLoadedTerrain(new Vector3($this->pairX, $this->y, $this->pairZ))){
|
||||
//paired to a tile in an unloaded chunk
|
||||
$this->doubleInventory = null;
|
||||
|
||||
@ -160,7 +160,7 @@ class Chest extends Spawnable implements InventoryHolder, Container, Nameable{
|
||||
|
||||
public function getPair() : ?Chest{
|
||||
if($this->isPaired()){
|
||||
$tile = $this->getLevel()->getTileAt($this->pairX, $this->y, $this->pairZ);
|
||||
$tile = $this->getLevelNonNull()->getTileAt($this->pairX, $this->y, $this->pairZ);
|
||||
if($tile instanceof Chest){
|
||||
return $tile;
|
||||
}
|
||||
|
@ -148,7 +148,7 @@ class Furnace extends Spawnable implements InventoryHolder, Container, Nameable{
|
||||
$this->maxTime = $this->burnTime = $ev->getBurnTime();
|
||||
|
||||
if($this->getBlock()->getId() === Block::FURNACE){
|
||||
$this->getLevel()->setBlock($this, BlockFactory::get(Block::BURNING_FURNACE, $this->getBlock()->getDamage()), true);
|
||||
$this->getLevelNonNull()->setBlock($this, BlockFactory::get(Block::BURNING_FURNACE, $this->getBlock()->getDamage()), true);
|
||||
}
|
||||
|
||||
if($this->burnTime > 0 and $ev->isBurning()){
|
||||
@ -211,7 +211,7 @@ class Furnace extends Spawnable implements InventoryHolder, Container, Nameable{
|
||||
$ret = true;
|
||||
}else{
|
||||
if($this->getBlock()->getId() === Block::BURNING_FURNACE){
|
||||
$this->getLevel()->setBlock($this, BlockFactory::get(Block::FURNACE, $this->getBlock()->getDamage()), true);
|
||||
$this->getLevelNonNull()->setBlock($this, BlockFactory::get(Block::FURNACE, $this->getBlock()->getDamage()), true);
|
||||
}
|
||||
$this->burnTime = $this->cookTime = $this->maxTime = 0;
|
||||
}
|
||||
|
@ -168,7 +168,7 @@ abstract class Tile extends Position{
|
||||
parent::__construct($nbt->getInt(self::TAG_X), $nbt->getInt(self::TAG_Y), $nbt->getInt(self::TAG_Z), $level);
|
||||
$this->readSaveData($nbt);
|
||||
|
||||
$this->getLevel()->addTile($this);
|
||||
$this->getLevelNonNull()->addTile($this);
|
||||
}
|
||||
|
||||
public function getId() : int{
|
||||
|
33
src/pocketmine/utils/AssumptionFailedError.php
Normal file
33
src/pocketmine/utils/AssumptionFailedError.php
Normal 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{
|
||||
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user