#937: Fixes related to unplaced BlockStates and the recent world generation changes.
* CraftBlockState#getWorldHandle() would previously run into a NPE when being invoked for a non-placed BlockState. It now returns null in this case. * CraftChest#getInventory() would previously encounter this NPE when being called for a non-placed BlockState. It will now automatically forward the call to #getBlockInventory() when it is being called for either a non-placed BlockState, or during world generation. * CraftStructureBlock#applyTo was able to run into a NPE when being called for non-placed BlockStates (this is for example called by #getSnapshotNBT()). * Replaced all no-world-generation preconditions with a general 'ensureNoWorldGeneration' method. * Removed a few superfluous #isPlaced() calls. If getWorldHandle() reutrns a World, this already implies that the BlockState is placed.
This commit is contained in:
parent
4faf479e6c
commit
960f31098d
@ -23,7 +23,7 @@ public class CraftBeacon extends CraftBlockEntityState<TileEntityBeacon> impleme
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Collection<LivingEntity> getEntitiesInRange() {
|
public Collection<LivingEntity> getEntitiesInRange() {
|
||||||
Preconditions.checkState(getWorldHandle() instanceof net.minecraft.world.level.World, "Can't get entities during world generation");
|
ensureNoWorldGeneration();
|
||||||
|
|
||||||
TileEntity tileEntity = this.getTileEntityFromWorld();
|
TileEntity tileEntity = this.getTileEntityFromWorld();
|
||||||
if (tileEntity instanceof TileEntityBeacon) {
|
if (tileEntity instanceof TileEntityBeacon) {
|
||||||
|
@ -60,7 +60,7 @@ public class CraftBeehive extends CraftBlockEntityState<TileEntityBeehive> imple
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<Bee> releaseEntities() {
|
public List<Bee> releaseEntities() {
|
||||||
Preconditions.checkState(getWorldHandle() instanceof net.minecraft.world.level.World, "Can't release entities during world generation");
|
ensureNoWorldGeneration();
|
||||||
|
|
||||||
List<Bee> bees = new ArrayList<>();
|
List<Bee> bees = new ArrayList<>();
|
||||||
|
|
||||||
|
@ -57,20 +57,33 @@ public class CraftBlockState implements BlockState {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Returns null if weakWorld is not available and the BlockState is not placed.
|
||||||
|
// If this returns a World instead of only a GeneratorAccess, this implies that this BlockState is placed.
|
||||||
public GeneratorAccess getWorldHandle() {
|
public GeneratorAccess getWorldHandle() {
|
||||||
if (weakWorld == null) {
|
if (weakWorld == null) {
|
||||||
return world.getHandle();
|
return this.isPlaced() ? world.getHandle() : null;
|
||||||
}
|
}
|
||||||
|
|
||||||
GeneratorAccess access = weakWorld.get();
|
GeneratorAccess access = weakWorld.get();
|
||||||
if (access == null) {
|
if (access == null) {
|
||||||
weakWorld = null;
|
weakWorld = null;
|
||||||
return world.getHandle();
|
return this.isPlaced() ? world.getHandle() : null;
|
||||||
}
|
}
|
||||||
|
|
||||||
return access;
|
return access;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected final boolean isWorldGeneration() {
|
||||||
|
GeneratorAccess generatorAccess = this.getWorldHandle();
|
||||||
|
return generatorAccess != null && !(generatorAccess instanceof World);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected final void ensureNoWorldGeneration() {
|
||||||
|
if (isWorldGeneration()) {
|
||||||
|
throw new IllegalStateException("This operation is not supported during world generation!");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public World getWorld() {
|
public World getWorld() {
|
||||||
requirePlaced();
|
requirePlaced();
|
||||||
|
@ -37,10 +37,8 @@ public class CraftChest extends CraftLootable<TileEntityChest> implements Chest
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Inventory getInventory() {
|
public Inventory getInventory() {
|
||||||
Preconditions.checkState(getWorldHandle() instanceof net.minecraft.world.level.World, "Can't get inventory during world generation, use getBlockInventory() instead");
|
|
||||||
|
|
||||||
CraftInventory inventory = (CraftInventory) this.getBlockInventory();
|
CraftInventory inventory = (CraftInventory) this.getBlockInventory();
|
||||||
if (!isPlaced()) {
|
if (!isPlaced() || isWorldGeneration()) {
|
||||||
return inventory;
|
return inventory;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -47,10 +47,8 @@ public class CraftDispenser extends CraftLootable<TileEntityDispenser> implement
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean dispense() {
|
public boolean dispense() {
|
||||||
Preconditions.checkState(getWorldHandle() instanceof net.minecraft.world.level.World, "Can't dispense during world generation");
|
ensureNoWorldGeneration();
|
||||||
|
|
||||||
Block block = getBlock();
|
Block block = getBlock();
|
||||||
|
|
||||||
if (block.getType() == Material.DISPENSER) {
|
if (block.getType() == Material.DISPENSER) {
|
||||||
CraftWorld world = (CraftWorld) this.getWorld();
|
CraftWorld world = (CraftWorld) this.getWorld();
|
||||||
BlockDispenser dispense = (BlockDispenser) Blocks.DISPENSER;
|
BlockDispenser dispense = (BlockDispenser) Blocks.DISPENSER;
|
||||||
|
@ -34,10 +34,8 @@ public class CraftDropper extends CraftLootable<TileEntityDropper> implements Dr
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void drop() {
|
public void drop() {
|
||||||
Preconditions.checkState(getWorldHandle() instanceof net.minecraft.world.level.World, "Can't drop during world generation");
|
ensureNoWorldGeneration();
|
||||||
|
|
||||||
Block block = getBlock();
|
Block block = getBlock();
|
||||||
|
|
||||||
if (block.getType() == Material.DROPPER) {
|
if (block.getType() == Material.DROPPER) {
|
||||||
CraftWorld world = (CraftWorld) this.getWorld();
|
CraftWorld world = (CraftWorld) this.getWorld();
|
||||||
BlockDropper drop = (BlockDropper) Blocks.DROPPER;
|
BlockDropper drop = (BlockDropper) Blocks.DROPPER;
|
||||||
|
@ -81,9 +81,8 @@ public class CraftJukebox extends CraftBlockEntityState<TileEntityJukeBox> imple
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean eject() {
|
public boolean eject() {
|
||||||
Preconditions.checkState(getWorldHandle() instanceof net.minecraft.world.level.World, "Can't eject during world generation");
|
ensureNoWorldGeneration();
|
||||||
|
|
||||||
requirePlaced();
|
|
||||||
TileEntity tileEntity = this.getTileEntityFromWorld();
|
TileEntity tileEntity = this.getTileEntityFromWorld();
|
||||||
if (!(tileEntity instanceof TileEntityJukeBox)) return false;
|
if (!(tileEntity instanceof TileEntityJukeBox)) return false;
|
||||||
|
|
||||||
|
@ -42,7 +42,7 @@ public class CraftLectern extends CraftBlockEntityState<TileEntityLectern> imple
|
|||||||
public boolean update(boolean force, boolean applyPhysics) {
|
public boolean update(boolean force, boolean applyPhysics) {
|
||||||
boolean result = super.update(force, applyPhysics);
|
boolean result = super.update(force, applyPhysics);
|
||||||
|
|
||||||
if (result && this.isPlaced() && this.getType() == Material.LECTERN && getWorldHandle() instanceof net.minecraft.world.level.World) {
|
if (result && this.getType() == Material.LECTERN && getWorldHandle() instanceof net.minecraft.world.level.World) {
|
||||||
BlockLectern.a(this.world.getHandle(), this.getPosition(), this.getHandle());
|
BlockLectern.a(this.world.getHandle(), this.getPosition(), this.getHandle());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -180,7 +180,7 @@ public class CraftStructureBlock extends CraftBlockEntityState<TileEntityStructu
|
|||||||
// Ensure block type is correct
|
// Ensure block type is correct
|
||||||
if (access instanceof net.minecraft.world.level.World) {
|
if (access instanceof net.minecraft.world.level.World) {
|
||||||
tileEntity.setUsageMode(tileEntity.getUsageMode());
|
tileEntity.setUsageMode(tileEntity.getUsageMode());
|
||||||
} else {
|
} else if (access != null) {
|
||||||
// Custom handle during world generation
|
// Custom handle during world generation
|
||||||
// From TileEntityStructure#setUsageMode(BlockPropertyStructureMode)
|
// From TileEntityStructure#setUsageMode(BlockPropertyStructureMode)
|
||||||
net.minecraft.world.level.block.state.IBlockData data = access.getType(this.getPosition());
|
net.minecraft.world.level.block.state.IBlockData data = access.getType(this.getPosition());
|
||||||
|
Loading…
x
Reference in New Issue
Block a user