Skip to content

Commit

Permalink
Prevent exception from accessing tile entities from ChunkCache
Browse files Browse the repository at this point in the history
  • Loading branch information
mezz committed Jan 9, 2017
1 parent 0b491f2 commit 81dd20b
Show file tree
Hide file tree
Showing 5 changed files with 32 additions and 16 deletions.
17 changes: 6 additions & 11 deletions src/main/java/forestry/arboriculture/blocks/BlockSapling.java
Expand Up @@ -51,11 +51,6 @@ public class BlockSapling extends BlockTreeContainer implements IGrowable, IStat
/* PROPERTYS */
public static final PropertyTree TREE = new PropertyTree("tree");

@Nullable
public static TileSapling getSaplingTile(IBlockAccess world, BlockPos pos) {
return TileUtil.getTile(world, pos, TileSapling.class);
}

public BlockSapling() {
super(Material.PLANTS);
setSoundType(SoundType.PLANT);
Expand Down Expand Up @@ -104,7 +99,7 @@ public int getMetaFromState(IBlockState state) {

@Override
public IBlockState getActualState(IBlockState state, IBlockAccess world, BlockPos pos) {
TileSapling sapling = getSaplingTile(world, pos);
TileSapling sapling = TileUtil.getTile(world, pos, TileSapling.class);
if (sapling != null && sapling.getTree() != null) {
state = state.withProperty(TREE, sapling.getTree().getGenome().getPrimary());
} else {
Expand Down Expand Up @@ -134,7 +129,7 @@ public void registerModel(Item item, IModelManager manager) {

/* PLANTING */
public static boolean canBlockStay(IBlockAccess world, BlockPos pos) {
TileSapling tile = getSaplingTile(world, pos);
TileSapling tile = TileUtil.getTile(world, pos, TileSapling.class);
if (tile == null) {
return false;
}
Expand All @@ -160,7 +155,7 @@ public List<ItemStack> getDrops(IBlockAccess world, BlockPos pos, IBlockState st

@Override
public ItemStack getPickBlock(IBlockState state, RayTraceResult target, World world, BlockPos pos, EntityPlayer player) {
TileSapling sapling = getSaplingTile(world, pos);
TileSapling sapling = TileUtil.getTile(world, pos, TileSapling.class);
if (sapling == null || sapling.getTree() == null) {
return ItemStack.EMPTY;
}
Expand All @@ -183,7 +178,7 @@ private static void dropAsSapling(World world, BlockPos pos) {
return;
}

TileSapling sapling = getSaplingTile(world, pos);
TileSapling sapling = TileUtil.getTile(world, pos, TileSapling.class);
if (sapling != null && sapling.getTree() != null) {
ItemStack saplingStack = TreeManager.treeRoot.getMemberStack(sapling.getTree(), EnumGermlingType.SAPLING);
ItemStackUtil.dropItemStackAsEntity(saplingStack, world, pos);
Expand All @@ -197,7 +192,7 @@ public boolean canUseBonemeal(World world, Random rand, BlockPos pos, IBlockStat
if (world.rand.nextFloat() >= 0.45F) {
return false;
}
TileSapling saplingTile = getSaplingTile(world, pos);
TileSapling saplingTile = TileUtil.getTile(world, pos, TileSapling.class);
return saplingTile == null || saplingTile.canAcceptBoneMeal(rand);
}

Expand All @@ -208,7 +203,7 @@ public boolean canGrow(World world, BlockPos pos, IBlockState state, boolean isC

@Override
public void grow(World world, Random rand, BlockPos pos, IBlockState state) {
TileSapling saplingTile = getSaplingTile(world, pos);
TileSapling saplingTile = TileUtil.getTile(world, pos, TileSapling.class);
if (saplingTile != null) {
saplingTile.tryGrow(rand, true);
}
Expand Down
19 changes: 18 additions & 1 deletion src/main/java/forestry/core/tiles/TileUtil.java
Expand Up @@ -12,14 +12,18 @@

import javax.annotation.Nullable;

import net.minecraft.block.BlockFlowerPot;
import net.minecraft.block.state.IBlockState;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.inventory.IInventory;
import net.minecraft.inventory.ISidedInventory;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.EnumFacing;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.ChunkCache;
import net.minecraft.world.IBlockAccess;
import net.minecraft.world.World;
import net.minecraft.world.chunk.Chunk;
import net.minecraftforge.items.CapabilityItemHandler;
import net.minecraftforge.items.IItemHandler;
import net.minecraftforge.items.wrapper.InvWrapper;
Expand All @@ -36,9 +40,22 @@ public static boolean isUsableByPlayer(EntityPlayer player, TileEntity tile) {
player.getDistanceSq(pos.getX() + 0.5D, pos.getY() + 0.5D, pos.getZ() + 0.5D) <= 64.0D;
}

/**
* Returns the tile of the specified class, returns null if it is the wrong type or does not exist.
* Avoids creating new tile entities when using a ChunkCache (off the main thread).
* see {@link BlockFlowerPot#getActualState(IBlockState, IBlockAccess, BlockPos)}
*/
@Nullable
public static <T extends TileEntity> T getTile(IBlockAccess world, BlockPos pos, Class<T> tileClass) {
TileEntity tileEntity = world.getTileEntity(pos);
TileEntity tileEntity;

if (world instanceof ChunkCache) {
ChunkCache chunkCache = (ChunkCache) world;
tileEntity = chunkCache.getTileEntity(pos, Chunk.EnumCreateEntityType.CHECK);
} else {
tileEntity = world.getTileEntity(pos);
}

if (tileClass.isInstance(tileEntity)) {
return tileClass.cast(tileEntity);
} else {
Expand Down
5 changes: 3 additions & 2 deletions src/main/java/forestry/core/utils/CamouflageUtil.java
Expand Up @@ -18,6 +18,7 @@
import forestry.api.multiblock.IMultiblockComponent;
import forestry.api.multiblock.IMultiblockController;
import forestry.core.network.PacketBufferForestry;
import forestry.core.tiles.TileUtil;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.tileentity.TileEntity;
Expand Down Expand Up @@ -60,7 +61,7 @@ public static void readCamouflageBlockFromData(PacketBufferForestry data, ICamou

@Nullable
public static ICamouflageHandler getCamouflageHandler(IBlockAccess world, BlockPos pos) {
TileEntity tile = world.getTileEntity(pos);
TileEntity tile = TileUtil.getTile(world, pos, TileEntity.class);
if (tile instanceof ICamouflagedTile) {
ICamouflagedTile block = (ICamouflagedTile) tile;
String type = block.getCamouflageType();
Expand All @@ -81,7 +82,7 @@ public static ICamouflageHandler getCamouflageHandler(IBlockAccess world, BlockP
}

public static ItemStack getCamouflageBlock(IBlockAccess world, BlockPos pos) {
TileEntity tile = world.getTileEntity(pos);
TileEntity tile = TileUtil.getTile(world, pos, TileEntity.class);
if (tile instanceof ICamouflagedTile) {
ICamouflagedTile block = (ICamouflagedTile) tile;
String type = block.getCamouflageType();
Expand Down
Expand Up @@ -31,6 +31,7 @@
import forestry.core.blocks.properties.UnlistedBlockPos;
import forestry.core.multiblock.MultiblockTileEntityForestry;
import forestry.core.tiles.IActivatable;
import forestry.core.tiles.TileUtil;
import forestry.core.utils.CamouflageUtil;
import forestry.core.utils.ItemStackUtil;
import forestry.core.utils.Log;
Expand Down Expand Up @@ -242,7 +243,7 @@ protected BlockStateContainer createBlockState() {

@Override
public IBlockState getActualState(IBlockState state, IBlockAccess worldIn, BlockPos pos) {
TileEntity tile = worldIn.getTileEntity(pos);
TileEntity tile = TileUtil.getTile(worldIn, pos, TileEntity.class);
if (tile instanceof IActivatable) {
state = state.withProperty(STATE, ((IActivatable) tile).isActive() ? State.ON : State.OFF);
}
Expand Down
Expand Up @@ -20,13 +20,15 @@
import forestry.core.blocks.properties.UnlistedBlockAccess;
import forestry.core.blocks.properties.UnlistedBlockPos;
import forestry.core.models.ModelBlockDefault;
import forestry.core.tiles.TileUtil;
import forestry.core.utils.CamouflageUtil;
import forestry.greenhouse.blocks.BlockGreenhouse;
import forestry.greenhouse.blocks.BlockGreenhouseType;
import net.minecraft.block.state.IBlockState;
import net.minecraft.client.renderer.block.model.IBakedModel;
import net.minecraft.client.renderer.texture.TextureAtlasSprite;
import net.minecraft.item.ItemStack;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.EnumFacing;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.IBlockAccess;
Expand Down Expand Up @@ -75,7 +77,7 @@ protected void bakeBlock(BlockGreenhouse block, Key key, IModelBaker baker, bool

if (!camouflageStack.isEmpty()) {
ICamouflageHandler camouflageHandler = CamouflageUtil.getCamouflageHandler(world, pos);
ICamouflagedTile camouflageTile = (ICamouflagedTile) world.getTileEntity(pos);
ICamouflagedTile camouflageTile = (ICamouflagedTile) TileUtil.getTile(world, pos, TileEntity.class);
ICamouflageItemHandler itemHandler = CamouflageManager.camouflageAccess.getHandlerFromItem(camouflageStack);
if (itemHandler != null && camouflageHandler != null && camouflageTile != null) {
Pair<IBlockState, IBakedModel> model = itemHandler.getModel(camouflageStack, camouflageHandler, camouflageTile);
Expand Down

0 comments on commit 81dd20b

Please sign in to comment.