diff --git a/patches/minecraft/net/minecraft/world/biome/BiomeDecorator.java.patch b/patches/minecraft/net/minecraft/world/biome/BiomeDecorator.java.patch new file mode 100644 index 000000000..c0e91d25d --- /dev/null +++ b/patches/minecraft/net/minecraft/world/biome/BiomeDecorator.java.patch @@ -0,0 +1,169 @@ +--- ../src-base/minecraft/net/minecraft/world/biome/BiomeDecorator.java ++++ ../src-work/minecraft/net/minecraft/world/biome/BiomeDecorator.java +@@ -106,8 +106,10 @@ + + protected void genDecorations(BiomeGenBase p_150513_1_) + { ++ net.minecraftforge.common.MinecraftForge.EVENT_BUS.post(new net.minecraftforge.event.terraingen.DecorateBiomeEvent.Pre(currentWorld, randomGenerator, field_180294_c)); + this.generateOres(); + ++ if(net.minecraftforge.event.terraingen.TerrainGen.decorate(currentWorld, randomGenerator, field_180294_c, net.minecraftforge.event.terraingen.DecorateBiomeEvent.Decorate.EventType.SAND)) + for (int i = 0; i < this.sandPerChunk2; ++i) + { + int j = this.randomGenerator.nextInt(16) + 8; +@@ -115,6 +117,7 @@ + this.sandGen.generate(this.currentWorld, this.randomGenerator, this.currentWorld.getTopSolidOrLiquidBlock(this.field_180294_c.add(j, 0, k))); + } + ++ if(net.minecraftforge.event.terraingen.TerrainGen.decorate(currentWorld, randomGenerator, field_180294_c, net.minecraftforge.event.terraingen.DecorateBiomeEvent.Decorate.EventType.CLAY)) + for (int i1 = 0; i1 < this.clayPerChunk; ++i1) + { + int l1 = this.randomGenerator.nextInt(16) + 8; +@@ -122,6 +125,7 @@ + this.clayGen.generate(this.currentWorld, this.randomGenerator, this.currentWorld.getTopSolidOrLiquidBlock(this.field_180294_c.add(l1, 0, i6))); + } + ++ if(net.minecraftforge.event.terraingen.TerrainGen.decorate(currentWorld, randomGenerator, field_180294_c, net.minecraftforge.event.terraingen.DecorateBiomeEvent.Decorate.EventType.SAND_PASS2)) + for (int j1 = 0; j1 < this.sandPerChunk; ++j1) + { + int i2 = this.randomGenerator.nextInt(16) + 8; +@@ -136,6 +140,7 @@ + ++k1; + } + ++ if(net.minecraftforge.event.terraingen.TerrainGen.decorate(currentWorld, randomGenerator, field_180294_c, net.minecraftforge.event.terraingen.DecorateBiomeEvent.Decorate.EventType.TREE)) + for (int j2 = 0; j2 < k1; ++j2) + { + int k6 = this.randomGenerator.nextInt(16) + 8; +@@ -150,6 +155,7 @@ + } + } + ++ if(net.minecraftforge.event.terraingen.TerrainGen.decorate(currentWorld, randomGenerator, field_180294_c, net.minecraftforge.event.terraingen.DecorateBiomeEvent.Decorate.EventType.BIG_SHROOM)) + for (int k2 = 0; k2 < this.bigMushroomsPerChunk; ++k2) + { + int l6 = this.randomGenerator.nextInt(16) + 8; +@@ -157,6 +163,7 @@ + this.bigMushroomGen.generate(this.currentWorld, this.randomGenerator, this.currentWorld.getHorizon(this.field_180294_c.add(l6, 0, k10))); + } + ++ if(net.minecraftforge.event.terraingen.TerrainGen.decorate(currentWorld, randomGenerator, field_180294_c, net.minecraftforge.event.terraingen.DecorateBiomeEvent.Decorate.EventType.FLOWERS)) + for (int l2 = 0; l2 < this.flowersPerChunk; ++l2) + { + int i7 = this.randomGenerator.nextInt(16) + 8; +@@ -178,6 +185,7 @@ + } + } + ++ if(net.minecraftforge.event.terraingen.TerrainGen.decorate(currentWorld, randomGenerator, field_180294_c, net.minecraftforge.event.terraingen.DecorateBiomeEvent.Decorate.EventType.GRASS)) + for (int i3 = 0; i3 < this.grassPerChunk; ++i3) + { + int j7 = this.randomGenerator.nextInt(16) + 8; +@@ -191,6 +199,7 @@ + } + } + ++ if(net.minecraftforge.event.terraingen.TerrainGen.decorate(currentWorld, randomGenerator, field_180294_c, net.minecraftforge.event.terraingen.DecorateBiomeEvent.Decorate.EventType.DEAD_BUSH)) + for (int j3 = 0; j3 < this.deadBushPerChunk; ++j3) + { + int k7 = this.randomGenerator.nextInt(16) + 8; +@@ -204,6 +213,7 @@ + } + } + ++ if(net.minecraftforge.event.terraingen.TerrainGen.decorate(currentWorld, randomGenerator, field_180294_c, net.minecraftforge.event.terraingen.DecorateBiomeEvent.Decorate.EventType.LILYPAD)) + for (int k3 = 0; k3 < this.waterlilyPerChunk; ++k3) + { + int l7 = this.randomGenerator.nextInt(16) + 8; +@@ -230,6 +240,8 @@ + } + } + ++ if(net.minecraftforge.event.terraingen.TerrainGen.decorate(currentWorld, randomGenerator, field_180294_c, net.minecraftforge.event.terraingen.DecorateBiomeEvent.Decorate.EventType.SHROOM)) ++ { + for (int l3 = 0; l3 < this.mushroomsPerChunk; ++l3) + { + if (this.randomGenerator.nextInt(4) == 0) +@@ -280,7 +292,9 @@ + this.mushroomRedGen.generate(this.currentWorld, this.randomGenerator, this.field_180294_c.add(j4, l15, l8)); + } + } +- ++ } // End of Mushroom generation ++ if(net.minecraftforge.event.terraingen.TerrainGen.decorate(currentWorld, randomGenerator, field_180294_c, net.minecraftforge.event.terraingen.DecorateBiomeEvent.Decorate.EventType.REED)) ++ { + for (int k4 = 0; k4 < this.reedsPerChunk; ++k4) + { + int i9 = this.randomGenerator.nextInt(16) + 8; +@@ -306,7 +320,8 @@ + this.reedGen.generate(this.currentWorld, this.randomGenerator, this.field_180294_c.add(j9, i19, i13)); + } + } +- ++ } // End of Reed generation ++ if(net.minecraftforge.event.terraingen.TerrainGen.decorate(currentWorld, randomGenerator, field_180294_c, net.minecraftforge.event.terraingen.DecorateBiomeEvent.Decorate.EventType.PUMPKIN)) + if (this.randomGenerator.nextInt(32) == 0) + { + int i5 = this.randomGenerator.nextInt(16) + 8; +@@ -320,6 +335,7 @@ + } + } + ++ if(net.minecraftforge.event.terraingen.TerrainGen.decorate(currentWorld, randomGenerator, field_180294_c, net.minecraftforge.event.terraingen.DecorateBiomeEvent.Decorate.EventType.CACTUS)) + for (int j5 = 0; j5 < this.cactiPerChunk; ++j5) + { + int l9 = this.randomGenerator.nextInt(16) + 8; +@@ -335,6 +351,7 @@ + + if (this.generateLakes) + { ++ if(net.minecraftforge.event.terraingen.TerrainGen.decorate(currentWorld, randomGenerator, field_180294_c, net.minecraftforge.event.terraingen.DecorateBiomeEvent.Decorate.EventType.LAKE_WATER)) + for (int k5 = 0; k5 < 50; ++k5) + { + int i10 = this.randomGenerator.nextInt(16) + 8; +@@ -349,6 +366,7 @@ + } + } + ++ if(net.minecraftforge.event.terraingen.TerrainGen.decorate(currentWorld, randomGenerator, field_180294_c, net.minecraftforge.event.terraingen.DecorateBiomeEvent.Decorate.EventType.LAKE_LAVA)) + for (int l5 = 0; l5 < 20; ++l5) + { + int j10 = this.randomGenerator.nextInt(16) + 8; +@@ -358,6 +376,7 @@ + (new WorldGenLiquids(Blocks.flowing_lava)).generate(this.currentWorld, this.randomGenerator, blockpos3); + } + } ++ net.minecraftforge.common.MinecraftForge.EVENT_BUS.post(new net.minecraftforge.event.terraingen.DecorateBiomeEvent.Post(currentWorld, randomGenerator, field_180294_c)); + } + + protected void genStandardOre1(int p_76795_1_, WorldGenerator p_76795_2_, int p_76795_3_, int p_76795_4_) +@@ -398,16 +417,29 @@ + + protected void generateOres() + { ++ net.minecraftforge.common.MinecraftForge.ORE_GEN_BUS.post(new net.minecraftforge.event.terraingen.OreGenEvent.Pre(currentWorld, randomGenerator, field_180294_c)); ++ if (net.minecraftforge.event.terraingen.TerrainGen.generateOre(currentWorld, randomGenerator, dirtGen, field_180294_c, net.minecraftforge.event.terraingen.OreGenEvent.GenerateMinable.EventType.DIRT)) + this.genStandardOre1(this.chunkProviderSettings.dirtCount, this.dirtGen, this.chunkProviderSettings.dirtMinHeight, this.chunkProviderSettings.dirtMaxHeight); ++ if (net.minecraftforge.event.terraingen.TerrainGen.generateOre(currentWorld, randomGenerator, gravelGen, field_180294_c, net.minecraftforge.event.terraingen.OreGenEvent.GenerateMinable.EventType.GRAVEL)) + this.genStandardOre1(this.chunkProviderSettings.gravelCount, this.gravelGen, this.chunkProviderSettings.gravelMinHeight, this.chunkProviderSettings.gravelMaxHeight); ++ if (net.minecraftforge.event.terraingen.TerrainGen.generateOre(currentWorld, randomGenerator, dioriteGen, field_180294_c, net.minecraftforge.event.terraingen.OreGenEvent.GenerateMinable.EventType.DIORITE)) + this.genStandardOre1(this.chunkProviderSettings.dioriteCount, this.dioriteGen, this.chunkProviderSettings.dioriteMinHeight, this.chunkProviderSettings.dioriteMaxHeight); ++ if (net.minecraftforge.event.terraingen.TerrainGen.generateOre(currentWorld, randomGenerator, graniteGen, field_180294_c, net.minecraftforge.event.terraingen.OreGenEvent.GenerateMinable.EventType.GRANITE)) + this.genStandardOre1(this.chunkProviderSettings.graniteCount, this.graniteGen, this.chunkProviderSettings.graniteMinHeight, this.chunkProviderSettings.graniteMaxHeight); ++ if (net.minecraftforge.event.terraingen.TerrainGen.generateOre(currentWorld, randomGenerator, andesiteGen, field_180294_c, net.minecraftforge.event.terraingen.OreGenEvent.GenerateMinable.EventType.ANDESITE)) + this.genStandardOre1(this.chunkProviderSettings.andesiteCount, this.andesiteGen, this.chunkProviderSettings.andesiteMinHeight, this.chunkProviderSettings.andesiteMaxHeight); ++ if (net.minecraftforge.event.terraingen.TerrainGen.generateOre(currentWorld, randomGenerator, coalGen, field_180294_c, net.minecraftforge.event.terraingen.OreGenEvent.GenerateMinable.EventType.COAL)) + this.genStandardOre1(this.chunkProviderSettings.coalCount, this.coalGen, this.chunkProviderSettings.coalMinHeight, this.chunkProviderSettings.coalMaxHeight); ++ if (net.minecraftforge.event.terraingen.TerrainGen.generateOre(currentWorld, randomGenerator, ironGen, field_180294_c, net.minecraftforge.event.terraingen.OreGenEvent.GenerateMinable.EventType.IRON)) + this.genStandardOre1(this.chunkProviderSettings.ironCount, this.ironGen, this.chunkProviderSettings.ironMinHeight, this.chunkProviderSettings.ironMaxHeight); ++ if (net.minecraftforge.event.terraingen.TerrainGen.generateOre(currentWorld, randomGenerator, goldGen, field_180294_c, net.minecraftforge.event.terraingen.OreGenEvent.GenerateMinable.EventType.GOLD)) + this.genStandardOre1(this.chunkProviderSettings.goldCount, this.goldGen, this.chunkProviderSettings.goldMinHeight, this.chunkProviderSettings.goldMaxHeight); ++ if (net.minecraftforge.event.terraingen.TerrainGen.generateOre(currentWorld, randomGenerator, redstoneGen, field_180294_c, net.minecraftforge.event.terraingen.OreGenEvent.GenerateMinable.EventType.REDSTONE)) + this.genStandardOre1(this.chunkProviderSettings.redstoneCount, this.redstoneGen, this.chunkProviderSettings.redstoneMinHeight, this.chunkProviderSettings.redstoneMaxHeight); ++ if (net.minecraftforge.event.terraingen.TerrainGen.generateOre(currentWorld, randomGenerator, diamondGen, field_180294_c, net.minecraftforge.event.terraingen.OreGenEvent.GenerateMinable.EventType.DIAMOND)) + this.genStandardOre1(this.chunkProviderSettings.diamondCount, this.diamondGen, this.chunkProviderSettings.diamondMinHeight, this.chunkProviderSettings.diamondMaxHeight); ++ if (net.minecraftforge.event.terraingen.TerrainGen.generateOre(currentWorld, randomGenerator, lapisGen, field_180294_c, net.minecraftforge.event.terraingen.OreGenEvent.GenerateMinable.EventType.LAPIS)) + this.genStandardOre2(this.chunkProviderSettings.lapisCount, this.lapisGen, this.chunkProviderSettings.lapisCenterHeight, this.chunkProviderSettings.lapisSpread); ++ net.minecraftforge.common.MinecraftForge.ORE_GEN_BUS.post(new net.minecraftforge.event.terraingen.OreGenEvent.Post(currentWorld, randomGenerator, field_180294_c)); + } + } diff --git a/patches/minecraft/net/minecraft/world/biome/WorldChunkManager.java.patch b/patches/minecraft/net/minecraft/world/biome/WorldChunkManager.java.patch new file mode 100644 index 000000000..6ce27c9c8 --- /dev/null +++ b/patches/minecraft/net/minecraft/world/biome/WorldChunkManager.java.patch @@ -0,0 +1,45 @@ +--- ../src-base/minecraft/net/minecraft/world/biome/WorldChunkManager.java ++++ ../src-work/minecraft/net/minecraft/world/biome/WorldChunkManager.java +@@ -16,6 +16,7 @@ + + public class WorldChunkManager + { ++ public static List allowedBiomes = Lists.newArrayList(BiomeGenBase.forest, BiomeGenBase.plains, BiomeGenBase.taiga, BiomeGenBase.taigaHills, BiomeGenBase.forestHills, BiomeGenBase.jungle, BiomeGenBase.jungleHills); + private GenLayer genBiomes; + private GenLayer biomeIndexLayer; + private BiomeCache biomeCache; +@@ -28,13 +29,7 @@ + this.biomeCache = new BiomeCache(this); + this.field_180301_f = ""; + this.biomesToSpawnIn = Lists.newArrayList(); +- this.biomesToSpawnIn.add(BiomeGenBase.forest); +- this.biomesToSpawnIn.add(BiomeGenBase.plains); +- this.biomesToSpawnIn.add(BiomeGenBase.taiga); +- this.biomesToSpawnIn.add(BiomeGenBase.taigaHills); +- this.biomesToSpawnIn.add(BiomeGenBase.forestHills); +- this.biomesToSpawnIn.add(BiomeGenBase.jungle); +- this.biomesToSpawnIn.add(BiomeGenBase.jungleHills); ++ this.biomesToSpawnIn.addAll(allowedBiomes); + } + + public WorldChunkManager(long p_i45744_1_, WorldType p_i45744_3_, String p_i45744_4_) +@@ -42,6 +37,7 @@ + this(); + this.field_180301_f = p_i45744_4_; + GenLayer[] agenlayer = GenLayer.initializeAllBiomeGenerators(p_i45744_1_, p_i45744_3_, p_i45744_4_); ++ agenlayer = getModdedBiomeGenerators(p_i45744_3_, p_i45744_1_, agenlayer); + this.genBiomes = agenlayer[0]; + this.biomeIndexLayer = agenlayer[1]; + } +@@ -250,4 +246,11 @@ + { + this.biomeCache.cleanupCache(); + } ++ ++ public GenLayer[] getModdedBiomeGenerators(WorldType worldType, long seed, GenLayer[] original) ++ { ++ net.minecraftforge.event.terraingen.WorldTypeEvent.InitBiomeGens event = new net.minecraftforge.event.terraingen.WorldTypeEvent.InitBiomeGens(worldType, seed, original); ++ net.minecraftforge.common.MinecraftForge.TERRAIN_GEN_BUS.post(event); ++ return event.newBiomeGens; ++ } + } diff --git a/patches/minecraft/net/minecraft/world/chunk/Chunk.java.patch b/patches/minecraft/net/minecraft/world/chunk/Chunk.java.patch new file mode 100644 index 000000000..51f17e070 --- /dev/null +++ b/patches/minecraft/net/minecraft/world/chunk/Chunk.java.patch @@ -0,0 +1,246 @@ +--- ../src-base/minecraft/net/minecraft/world/chunk/Chunk.java ++++ ../src-work/minecraft/net/minecraft/world/chunk/Chunk.java +@@ -168,7 +168,7 @@ + { + Block block = this.getBlock0(j, l - 1, k); + +- if (block.getLightOpacity() != 0) ++ if (getBlockLightOpacity(j, l - 1, k) != 0) + { + this.heightMap[k << 4 | j] = l; + +@@ -441,12 +441,12 @@ + + public int getBlockLightOpacity(BlockPos pos) + { +- return this.getBlock(pos).getLightOpacity(); ++ return this.getBlock(pos).getLightOpacity(worldObj, pos); + } + + private int getBlockLightOpacity(int x, int y, int z) + { +- return this.getBlock0(x, y, z).getLightOpacity(); ++ return getBlockLightOpacity(new BlockPos((xPosition << 4) + x, y, (zPosition << 4) + z)); + } + + private Block getBlock0(int x, int y, int z) +@@ -627,14 +627,19 @@ + + extendedblockstorage.set(i, j & 15, k, state); + +- if (block1 != block) ++ //if (block1 != block) + { + if (!this.worldObj.isRemote) + { ++ if (block1 != block) //Only fire block breaks when the block changes. + block1.breakBlock(this.worldObj, pos, iblockstate); ++ TileEntity te = this.getTileEntity(pos, Chunk.EnumCreateEntityType.CHECK); ++ if (te != null && te.shouldRefresh(this.worldObj, pos, iblockstate, state)) this.worldObj.removeTileEntity(pos); + } +- else if (block1 instanceof ITileEntityProvider) ++ else if (block1.hasTileEntity(iblockstate)) + { ++ TileEntity te = this.getTileEntity(pos, Chunk.EnumCreateEntityType.CHECK); ++ if (te != null && te.shouldRefresh(this.worldObj, pos, iblockstate, state)) + this.worldObj.removeTileEntity(pos); + } + } +@@ -651,8 +656,8 @@ + } + else + { +- int j1 = block.getLightOpacity(); +- int k1 = block1.getLightOpacity(); ++ int j1 = block.getLightOpacity(this.worldObj, pos); ++ int k1 = block1.getLightOpacity(this.worldObj, pos); + + if (j1 > 0) + { +@@ -672,28 +677,18 @@ + } + } + +- if (block1 instanceof ITileEntityProvider) +- { +- TileEntity tileentity = this.getTileEntity(pos, Chunk.EnumCreateEntityType.CHECK); +- +- if (tileentity != null) +- { +- tileentity.updateContainingBlockInfo(); +- } +- } +- + if (!this.worldObj.isRemote && block1 != block) + { + block.onBlockAdded(this.worldObj, pos, state); + } + +- if (block instanceof ITileEntityProvider) ++ if (block.hasTileEntity(state)) + { + TileEntity tileentity1 = this.getTileEntity(pos, Chunk.EnumCreateEntityType.CHECK); + + if (tileentity1 == null) + { +- tileentity1 = ((ITileEntityProvider)block).createNewTileEntity(this.worldObj, block.getMetaFromState(state)); ++ tileentity1 = block.createTileEntity(this.worldObj, state); + this.worldObj.setTileEntity(pos, tileentity1); + } + +@@ -796,6 +791,7 @@ + k = this.entityLists.length - 1; + } + ++ net.minecraftforge.common.MinecraftForge.EVENT_BUS.post(new net.minecraftforge.event.entity.EntityEvent.EnteringChunk(entityIn, this.xPosition, this.zPosition, entityIn.chunkCoordX, entityIn.chunkCoordZ)); + entityIn.addedToChunk = true; + entityIn.chunkCoordX = this.xPosition; + entityIn.chunkCoordY = k; +@@ -834,13 +830,20 @@ + private TileEntity createNewTileEntity(BlockPos pos) + { + Block block = this.getBlock(pos); +- return !block.hasTileEntity() ? null : ((ITileEntityProvider)block).createNewTileEntity(this.worldObj, this.getBlockMetadata(pos)); ++ IBlockState state = block.getStateFromMeta(this.getBlockMetadata(pos)); ++ return !block.hasTileEntity(state) ? null : block.createTileEntity(this.worldObj, state); + } + + public TileEntity getTileEntity(BlockPos pos, Chunk.EnumCreateEntityType p_177424_2_) + { + TileEntity tileentity = (TileEntity)this.chunkTileEntityMap.get(pos); + ++ if (tileentity != null && tileentity.isInvalid()) ++ { ++ chunkTileEntityMap.remove(pos); ++ tileentity = null; ++ } ++ + if (tileentity == null) + { + if (p_177424_2_ == Chunk.EnumCreateEntityType.IMMEDIATE) +@@ -853,11 +856,6 @@ + this.field_177447_w.add(pos); + } + } +- else if (tileentity.isInvalid()) +- { +- this.chunkTileEntityMap.remove(pos); +- return null; +- } + + return tileentity; + } +@@ -877,7 +875,7 @@ + tileEntityIn.setWorldObj(this.worldObj); + tileEntityIn.setPos(pos); + +- if (this.getBlock(pos) instanceof ITileEntityProvider) ++ if (this.getBlock(pos).hasTileEntity(getBlock(pos).getStateFromMeta(this.getBlockMetadata(pos)))) + { + if (this.chunkTileEntityMap.containsKey(pos)) + { +@@ -914,8 +912,9 @@ + entity.onChunkLoad(); + } + +- this.worldObj.loadEntities(this.entityLists[i]); ++ this.worldObj.loadEntities(com.google.common.collect.ImmutableList.copyOf(this.entityLists[i])); + } ++ net.minecraftforge.common.MinecraftForge.EVENT_BUS.post(new net.minecraftforge.event.world.ChunkEvent.Load(this)); + } + + public void onChunkUnload() +@@ -931,6 +930,7 @@ + { + this.worldObj.unloadEntities(this.entityLists[i]); + } ++ net.minecraftforge.common.MinecraftForge.EVENT_BUS.post(new net.minecraftforge.event.world.ChunkEvent.Unload(this)); + } + + public void setChunkModified() +@@ -940,8 +940,8 @@ + + public void getEntitiesWithinAABBForEntity(Entity entityIn, AxisAlignedBB aabb, List listToFill, Predicate p_177414_4_) + { +- int i = MathHelper.floor_double((aabb.minY - 2.0D) / 16.0D); +- int j = MathHelper.floor_double((aabb.maxY + 2.0D) / 16.0D); ++ int i = MathHelper.floor_double((aabb.minY - World.MAX_ENTITY_RADIUS) / 16.0D); ++ int j = MathHelper.floor_double((aabb.maxY + World.MAX_ENTITY_RADIUS) / 16.0D); + i = MathHelper.clamp_int(i, 0, this.entityLists.length - 1); + j = MathHelper.clamp_int(j, 0, this.entityLists.length - 1); + +@@ -980,8 +980,8 @@ + + public void getEntitiesOfTypeWithinAAAB(Class entityClass, AxisAlignedBB aabb, List listToFill, Predicate p_177430_4_) + { +- int i = MathHelper.floor_double((aabb.minY - 2.0D) / 16.0D); +- int j = MathHelper.floor_double((aabb.maxY + 2.0D) / 16.0D); ++ int i = MathHelper.floor_double((aabb.minY - World.MAX_ENTITY_RADIUS) / 16.0D); ++ int j = MathHelper.floor_double((aabb.maxY + World.MAX_ENTITY_RADIUS) / 16.0D); + i = MathHelper.clamp_int(i, 0, this.entityLists.length - 1); + j = MathHelper.clamp_int(j, 0, this.entityLists.length - 1); + +@@ -1141,8 +1141,10 @@ + while (!this.field_177447_w.isEmpty()) + { + BlockPos blockpos = (BlockPos)this.field_177447_w.poll(); ++ Block block = this.getBlock(blockpos); ++ IBlockState state = block.getStateFromMeta(this.getBlockMetadata(blockpos)); + +- if (this.getTileEntity(blockpos, Chunk.EnumCreateEntityType.CHECK) == null && this.getBlock(blockpos).hasTileEntity()) ++ if (this.getTileEntity(blockpos, Chunk.EnumCreateEntityType.CHECK) == null && block.hasTileEntity(state)) + { + TileEntity tileentity = this.createNewTileEntity(blockpos); + this.worldObj.setTileEntity(blockpos, tileentity); +@@ -1204,6 +1206,13 @@ + @SideOnly(Side.CLIENT) + public void fillChunk(byte[] p_177439_1_, int p_177439_2_, boolean p_177439_3_) + { ++ for(TileEntity tileEntity : chunkTileEntityMap.values()) ++ { ++ tileEntity.updateContainingBlockInfo(); ++ tileEntity.getBlockMetadata(); ++ tileEntity.getBlockType(); ++ } ++ + int i = 0; + boolean flag = !this.worldObj.provider.getHasNoSky(); + +@@ -1271,10 +1280,16 @@ + this.isTerrainPopulated = true; + this.generateHeightMap(); + ++ List invalidList = new java.util.ArrayList(); ++ + for (TileEntity tileentity : this.chunkTileEntityMap.values()) + { ++ if (tileentity.shouldRefresh(this.worldObj, tileentity.getPos(), tileentity.getBlockType().getStateFromMeta(tileentity.getBlockMetadata()), getBlockState(tileentity.getPos()))) ++ invalidList.add(tileentity); + tileentity.updateContainingBlockInfo(); + } ++ ++ for (TileEntity te : invalidList) te.invalidate(); + } + + public BiomeGenBase getBiome(BlockPos pos, WorldChunkManager chunkManager) +@@ -1589,4 +1604,20 @@ + + private static final String __OBFID = "CL_00002009"; + } ++ ++ /** ++ * Removes the tile entity at the specified position, only if it's ++ * marked as invalid. ++ */ ++ public void removeInvalidTileEntity(BlockPos pos) ++ { ++ if (isChunkLoaded) ++ { ++ TileEntity entity = (TileEntity)chunkTileEntityMap.get(pos); ++ if (entity != null && entity.isInvalid()) ++ { ++ chunkTileEntityMap.remove(pos); ++ } ++ } ++ } + }