--- ../src_base/common/net/minecraft/src/World.java +++ ../src_work/common/net/minecraft/src/World.java @@ -10,8 +10,22 @@ import java.util.Random; import java.util.Set; +import net.minecraftforge.common.MinecraftForge; +import net.minecraftforge.common.ForgeDirection; +import net.minecraftforge.event.entity.EntityEvent; +import net.minecraftforge.event.entity.EntityJoinWorldEvent; +import net.minecraftforge.event.world.WorldEvent; +import net.minecraftforge.event.entity.PlaySoundAtEntityEvent; + public abstract class World implements IBlockAccess { + /** + * Used in the getEntitiesWithinAABB functions to expand the search area for entities. + * Modders should change this variable to a higher value if it is less then the radius + * of one of there entities. + */ + public static double MAX_ENTITY_RADIUS = 2.0D; + /** * boolean; if true updates scheduled by scheduleBlockUpdate happen immediately */ @@ -132,6 +146,11 @@ * Gets the biome for a given set of x/z coordinates */ public BiomeGenBase getBiomeGenForCoords(int par1, int par2) + { + return provider.getBiomeGenForCoords(par1, par2); + } + + public BiomeGenBase getBiomeGenForCoordsBody(int par1, int par2) { if (this.blockExists(par1, 0, par2)) { @@ -167,6 +186,7 @@ this.chunkProvider = this.createChunkProvider(); this.calculateInitialSkylight(); this.calculateInitialWeather(); + MinecraftForge.EVENT_BUS.post(new WorldEvent.Load(this)); } public World(ISaveHandler par1ISaveHandler, String par2Str, WorldSettings par3WorldSettings, WorldProvider par4WorldProvider, Profiler par5Profiler) @@ -213,6 +233,7 @@ this.calculateInitialSkylight(); this.calculateInitialWeather(); + MinecraftForge.EVENT_BUS.post(new WorldEvent.Load(this)); } /** @@ -269,7 +290,8 @@ */ public boolean isAirBlock(int par1, int par2, int par3) { - return this.getBlockId(par1, par2, par3) == 0; + int id = getBlockId(par1, par2, par3); + return id == 0 || Block.blocksList[id] == null || Block.blocksList[id].isAirBlock(this, par1, par2, par3); } /** @@ -278,7 +300,8 @@ public boolean blockHasTileEntity(int par1, int par2, int par3) { int var4 = this.getBlockId(par1, par2, par3); - return Block.blocksList[var4] != null && Block.blocksList[var4].hasTileEntity(); + int meta = this.getBlockMetadata(par1, par2, par3); + return Block.blocksList[var4] != null && Block.blocksList[var4].hasTileEntity(meta); } /** @@ -980,7 +1003,7 @@ */ public boolean isDaytime() { - return this.skylightSubtracted < 4; + return provider.isDaytime(); } /** @@ -1012,7 +1035,7 @@ int var12 = this.getBlockMetadata(var8, var9, var10); Block var13 = Block.blocksList[var11]; - if ((!par4 || var13 == null || var13.getCollisionBoundingBoxFromPool(this, var8, var9, var10) != null) && var11 > 0 && var13.canCollideCheck(var12, par3)) + if (var13 != null && (!par4 || var13 == null || var13.getCollisionBoundingBoxFromPool(this, var8, var9, var10) != null) && var11 > 0 && var13.canCollideCheck(var12, par3)) { MovingObjectPosition var14 = var13.collisionRayTrace(this, var8, var9, var10, par1Vec3, par2Vec3); @@ -1212,6 +1235,12 @@ */ public void playSoundAtEntity(Entity par1Entity, String par2Str, float par3, float par4) { + PlaySoundAtEntityEvent event = new PlaySoundAtEntityEvent(par1Entity, par2Str, par3, par4); + if (MinecraftForge.EVENT_BUS.post(event)) + { + return; + } + par2Str = event.name; if (par1Entity != null && par2Str != null) { Iterator var5 = this.worldAccesses.iterator(); @@ -1312,6 +1341,11 @@ EntityPlayer var5 = (EntityPlayer)par1Entity; this.playerEntities.add(var5); this.updateAllPlayersSleepingFlag(); + } + + if (!var4 && MinecraftForge.EVENT_BUS.post(new EntityJoinWorldEvent(par1Entity, this))) + { + return false; } this.getChunkFromChunkCoords(var2, var3).addEntity(par1Entity); @@ -1563,6 +1597,12 @@ * Calculates the color for the skybox */ public Vec3 getSkyColor(Entity par1Entity, float par2) + { + return provider.getSkyColor(par1Entity, par2); + } + + @SideOnly(Side.CLIENT) + public Vec3 getSkyColorBody(Entity par1Entity, float par2) { float var3 = this.getCelestialAngle(par2); float var4 = MathHelper.cos(var3 * (float)Math.PI * 2.0F) * 2.0F + 0.5F; @@ -1658,6 +1698,12 @@ @SideOnly(Side.CLIENT) public Vec3 drawClouds(float par1) { + return provider.drawClouds(par1); + } + + @SideOnly(Side.CLIENT) + public Vec3 drawCloudsBody(float par1) + { float var2 = this.getCelestialAngle(par1); float var3 = MathHelper.cos(var2 * (float)Math.PI * 2.0F) * 2.0F + 0.5F; @@ -1736,7 +1782,7 @@ { int var5 = var3.getBlockID(par1, var4, par2); - if (var5 != 0 && Block.blocksList[var5].blockMaterial.blocksMovement() && Block.blocksList[var5].blockMaterial != Material.leaves) + if (var5 != 0 && Block.blocksList[var5].blockMaterial.blocksMovement() && Block.blocksList[var5].blockMaterial != Material.leaves && !Block.blocksList[var5].isBlockFoliage(this, par1, var4, par2)) { return var4 + 1; } @@ -1751,6 +1797,12 @@ * How bright are stars in the sky */ public float getStarBrightness(float par1) + { + return provider.getStarBrightness(par1); + } + + @SideOnly(Side.CLIENT) + public float getStarBrightnessBody(float par1) { float var2 = this.getCelestialAngle(par1); float var3 = 1.0F - (MathHelper.cos(var2 * (float)Math.PI * 2.0F) * 2.0F + 0.25F); @@ -1893,7 +1945,7 @@ if (var8 != null) { - var8.removeChunkBlockTileEntity(var6.xCoord & 15, var6.yCoord, var6.zCoord & 15); + var8.cleanChunkBlockTileEntity(var6.xCoord & 15, var6.yCoord, var6.zCoord & 15); } } } @@ -1903,6 +1955,10 @@ if (!this.entityRemoval.isEmpty()) { + for (Object tile : entityRemoval) + { + ((TileEntity)tile).onChunkUnload(); + } this.loadedTileEntityList.removeAll(this.entityRemoval); this.entityRemoval.clear(); } @@ -1923,7 +1979,9 @@ { this.loadedTileEntityList.add(var9); } - + } + else + { if (this.chunkExists(var9.xCoord >> 4, var9.zCoord >> 4)) { Chunk var10 = this.getChunkFromChunkCoords(var9.xCoord >> 4, var9.zCoord >> 4); @@ -1933,8 +1991,6 @@ var10.setChunkBlockTileEntity(var9.xCoord & 15, var9.yCoord, var9.zCoord & 15, var9); } } - - this.markBlockNeedsUpdate(var9.xCoord, var9.yCoord, var9.zCoord); } } @@ -1947,13 +2003,13 @@ public void addTileEntity(Collection par1Collection) { - if (this.scanningTileEntities) - { - this.addedTileEntityList.addAll(par1Collection); - } - else - { - this.loadedTileEntityList.addAll(par1Collection); + List dest = scanningTileEntities ? addedTileEntityList : loadedTileEntityList; + for(Object entity : par1Collection) + { + if(((TileEntity)entity).canUpdate()) + { + dest.add(entity); + } } } @@ -1974,8 +2030,14 @@ int var3 = MathHelper.floor_double(par1Entity.posX); int var4 = MathHelper.floor_double(par1Entity.posZ); byte var5 = 32; - - if (!par2 || this.checkChunksExist(var3 - var5, 0, var4 - var5, var3 + var5, 0, var4 + var5)) + boolean canUpdate = !par2 || this.checkChunksExist(var3 - var5, 0, var4 - var5, var3 + var5, 0, var4 + var5); + if (!canUpdate) + { + EntityEvent.CanUpdate event = new EntityEvent.CanUpdate(par1Entity); + MinecraftForge.EVENT_BUS.post(event); + canUpdate = event.canUpdate; + } + if (canUpdate) { par1Entity.lastTickPosX = par1Entity.posX; par1Entity.lastTickPosY = par1Entity.posY; @@ -2210,6 +2272,14 @@ { return true; } + else + { + Block block = Block.blocksList[var11]; + if (block != null && block.isBlockBurning(this, var8, var9, var10)) + { + return true; + } + } } } } @@ -2516,25 +2586,21 @@ */ public void setBlockTileEntity(int par1, int par2, int par3, TileEntity par4TileEntity) { - if (par4TileEntity != null && !par4TileEntity.isInvalid()) - { - if (this.scanningTileEntities) - { - par4TileEntity.xCoord = par1; - par4TileEntity.yCoord = par2; - par4TileEntity.zCoord = par3; - this.addedTileEntityList.add(par4TileEntity); - } - else - { - this.loadedTileEntityList.add(par4TileEntity); - Chunk var5 = this.getChunkFromChunkCoords(par1 >> 4, par3 >> 4); - - if (var5 != null) - { - var5.setChunkBlockTileEntity(par1 & 15, par2, par3 & 15, par4TileEntity); - } - } + if (par4TileEntity == null || par4TileEntity.isInvalid()) + { + return; + } + + if (par4TileEntity.canUpdate()) + { + List dest = scanningTileEntities ? addedTileEntityList : loadedTileEntityList; + dest.add(par4TileEntity); + } + + Chunk chunk = getChunkFromChunkCoords(par1 >> 4, par3 >> 4); + if (chunk != null) + { + chunk.setChunkBlockTileEntity(par1 & 15, par2, par3 & 15, par4TileEntity); } } @@ -2543,27 +2609,10 @@ */ public void removeBlockTileEntity(int par1, int par2, int par3) { - TileEntity var4 = this.getBlockTileEntity(par1, par2, par3); - - if (var4 != null && this.scanningTileEntities) - { - var4.invalidate(); - this.addedTileEntityList.remove(var4); - } - else - { - if (var4 != null) - { - this.addedTileEntityList.remove(var4); - this.loadedTileEntityList.remove(var4); - } - - Chunk var5 = this.getChunkFromChunkCoords(par1 >> 4, par3 >> 4); - - if (var5 != null) - { - var5.removeChunkBlockTileEntity(par1 & 15, par2, par3 & 15); - } + Chunk chunk = getChunkFromChunkCoords(par1 >> 4, par3 >> 4); + if (chunk != null) + { + chunk.removeChunkBlockTileEntity(par1 & 15, par2, par3 & 15); } } @@ -2589,7 +2638,8 @@ */ public boolean isBlockNormalCube(int par1, int par2, int par3) { - return Block.isNormalCube(this.getBlockId(par1, par2, par3)); + Block block = Block.blocksList[getBlockId(par1, par2, par3)]; + return block != null && block.isBlockNormalCube(this, par1, par2, par3); } /** @@ -2597,8 +2647,7 @@ */ public boolean doesBlockHaveSolidTopSurface(int par1, int par2, int par3) { - Block var4 = Block.blocksList[this.getBlockId(par1, par2, par3)]; - return var4 == null ? false : (var4.blockMaterial.isOpaque() && var4.renderAsNormalBlock() ? true : (var4 instanceof BlockStairs ? (this.getBlockMetadata(par1, par2, par3) & 4) == 4 : (var4 instanceof BlockHalfSlab ? (this.getBlockMetadata(par1, par2, par3) & 8) == 8 : false))); + return isBlockSolidOnSide(par1, par2, par3, ForgeDirection.UP); } /** @@ -2614,7 +2663,7 @@ if (var5 != null && !var5.isEmpty()) { Block var6 = Block.blocksList[this.getBlockId(par1, par2, par3)]; - return var6 == null ? false : var6.blockMaterial.isOpaque() && var6.renderAsNormalBlock(); + return var6 == null ? false : isBlockNormalCube(par1, par2, par3); } else { @@ -2645,8 +2694,7 @@ */ public void setAllowedSpawnTypes(boolean par1, boolean par2) { - this.spawnHostileMobs = par1; - this.spawnPeacefulMobs = par2; + provider.setAllowedSpawnTypes(par1, par2); } /** @@ -2662,6 +2710,11 @@ */ private void calculateInitialWeather() { + provider.calculateInitialWeather(); + } + + public void calculateInitialWeatherBody() + { if (this.worldInfo.isRaining()) { this.rainingStrength = 1.0F; @@ -2677,6 +2730,11 @@ * Updates all weather states. */ protected void updateWeather() + { + provider.updateWeather(); + } + + public void updateWeatherBody() { if (!this.provider.hasNoSky) { @@ -2779,7 +2837,7 @@ public void toggleRain() { - this.worldInfo.setRainTime(1); + provider.toggleRain(); } protected void setActivePlayerChunksAndCheckLight() @@ -2891,6 +2949,11 @@ */ public boolean canBlockFreeze(int par1, int par2, int par3, boolean par4) { + return provider.canBlockFreeze(par1, par2, par3, par4); + } + + public boolean canBlockFreezeBody(int par1, int par2, int par3, boolean par4) + { BiomeGenBase var5 = this.getBiomeGenForCoords(par1, par3); float var6 = var5.getFloatTemperature(); @@ -2948,6 +3011,11 @@ * Tests whether or not snow can be placed at a given location */ public boolean canSnowAt(int par1, int par2, int par3) + { + return provider.canSnowAt(par1, par2, par3); + } + + public boolean canSnowAtBody(int par1, int par2, int par3) { BiomeGenBase var4 = this.getBiomeGenForCoords(par1, par3); float var5 = var4.getFloatTemperature(); @@ -3041,7 +3109,7 @@ private int computeBlockLightValue(int par1, int par2, int par3, int par4, int par5, int par6) { - int var7 = Block.lightValue[par5]; + int var7 = (par5 == 0 || Block.blocksList[par5] == null ? 0 : Block.blocksList[par5].getLightValue(this, par2, par3, par4)); int var8 = this.getSavedLightValue(EnumSkyBlock.Block, par2 - 1, par3, par4) - par6; int var9 = this.getSavedLightValue(EnumSkyBlock.Block, par2 + 1, par3, par4) - par6; int var10 = this.getSavedLightValue(EnumSkyBlock.Block, par2, par3 - 1, par4) - par6; @@ -3309,10 +3377,10 @@ public List getEntitiesWithinAABBExcludingEntity(Entity par1Entity, AxisAlignedBB par2AxisAlignedBB) { this.entitiesWithinAABBExcludingEntity.clear(); - int var3 = MathHelper.floor_double((par2AxisAlignedBB.minX - 2.0D) / 16.0D); - int var4 = MathHelper.floor_double((par2AxisAlignedBB.maxX + 2.0D) / 16.0D); - int var5 = MathHelper.floor_double((par2AxisAlignedBB.minZ - 2.0D) / 16.0D); - int var6 = MathHelper.floor_double((par2AxisAlignedBB.maxZ + 2.0D) / 16.0D); + int var3 = MathHelper.floor_double((par2AxisAlignedBB.minX - MAX_ENTITY_RADIUS) / 16.0D); + int var4 = MathHelper.floor_double((par2AxisAlignedBB.maxX + MAX_ENTITY_RADIUS) / 16.0D); + int var5 = MathHelper.floor_double((par2AxisAlignedBB.minZ - MAX_ENTITY_RADIUS) / 16.0D); + int var6 = MathHelper.floor_double((par2AxisAlignedBB.maxZ + MAX_ENTITY_RADIUS) / 16.0D); for (int var7 = var3; var7 <= var4; ++var7) { @@ -3333,10 +3401,10 @@ */ public List getEntitiesWithinAABB(Class par1Class, AxisAlignedBB par2AxisAlignedBB) { - int var3 = MathHelper.floor_double((par2AxisAlignedBB.minX - 2.0D) / 16.0D); - int var4 = MathHelper.floor_double((par2AxisAlignedBB.maxX + 2.0D) / 16.0D); - int var5 = MathHelper.floor_double((par2AxisAlignedBB.minZ - 2.0D) / 16.0D); - int var6 = MathHelper.floor_double((par2AxisAlignedBB.maxZ + 2.0D) / 16.0D); + int var3 = MathHelper.floor_double((par2AxisAlignedBB.minX - MAX_ENTITY_RADIUS) / 16.0D); + int var4 = MathHelper.floor_double((par2AxisAlignedBB.maxX + MAX_ENTITY_RADIUS) / 16.0D); + int var5 = MathHelper.floor_double((par2AxisAlignedBB.minZ - MAX_ENTITY_RADIUS) / 16.0D); + int var6 = MathHelper.floor_double((par2AxisAlignedBB.maxZ + MAX_ENTITY_RADIUS) / 16.0D); ArrayList var7 = new ArrayList(); for (int var8 = var3; var8 <= var4; ++var8) @@ -3425,11 +3493,14 @@ */ public void addLoadedEntities(List par1List) { - this.loadedEntityList.addAll(par1List); - for (int var2 = 0; var2 < par1List.size(); ++var2) { - this.obtainEntitySkin((Entity)par1List.get(var2)); + Entity entity = (Entity)par1List.get(var2); + if (!MinecraftForge.EVENT_BUS.post(new EntityJoinWorldEvent(entity, this))) + { + loadedEntityList.add(entity); + this.obtainEntitySkin(entity); + } } } @@ -3466,7 +3537,10 @@ { var9 = null; } - + if (var9 != null && var9.isBlockReplaceable(this, par2, par3, par4)) + { + var9 = null; + } return par1 > 0 && var9 == null && var10.canPlaceBlockOnSide(this, par2, par3, par4, par6); } } @@ -3656,7 +3730,7 @@ */ public void setWorldTime(long par1) { - this.worldInfo.setWorldTime(par1); + provider.setWorldTime(par1); } /** @@ -3664,12 +3738,12 @@ */ public long getSeed() { - return this.worldInfo.getSeed(); + return provider.getSeed(); } public long getWorldTime() { - return this.worldInfo.getWorldTime(); + return provider.getWorldTime(); } /** @@ -3677,13 +3751,13 @@ */ public ChunkCoordinates getSpawnPoint() { - return new ChunkCoordinates(this.worldInfo.getSpawnX(), this.worldInfo.getSpawnY(), this.worldInfo.getSpawnZ()); + return provider.getSpawnPoint(); } @SideOnly(Side.CLIENT) public void setSpawnLocation(int par1, int par2, int par3) { - this.worldInfo.setSpawnPosition(par1, par2, par3); + provider.setSpawnPoint(par1, par2, par3); } @SideOnly(Side.CLIENT) @@ -3707,7 +3781,10 @@ if (!this.loadedEntityList.contains(par1Entity)) { - this.loadedEntityList.add(par1Entity); + if (!MinecraftForge.EVENT_BUS.post(new EntityJoinWorldEvent(par1Entity, this))) + { + loadedEntityList.add(par1Entity); + } } } @@ -3715,6 +3792,11 @@ * Called when checking if a certain block can be mined or not. The 'spawn safe zone' check is located here. */ public boolean canMineBlock(EntityPlayer par1EntityPlayer, int par2, int par3, int par4) + { + return provider.canMineBlock(par1EntityPlayer, par2, par3, par4); + } + + public boolean canMineBlockBody(EntityPlayer par1EntityPlayer, int par2, int par3, int par4) { return true; } @@ -3827,8 +3909,7 @@ */ public boolean isBlockHighHumidity(int par1, int par2, int par3) { - BiomeGenBase var4 = this.getBiomeGenForCoords(par1, par3); - return var4.isHighHumidity(); + return provider.isBlockHighHumidity(par1, par2, par3); } /** @@ -3882,7 +3963,7 @@ */ public int getHeight() { - return 256; + return provider.getHeight(); } /** @@ -3890,7 +3971,7 @@ */ public int getActualHeight() { - return this.provider.hasNoSky ? 128 : 256; + return provider.getActualHeight(); } /** @@ -3936,7 +4017,7 @@ */ public double getHorizon() { - return this.worldInfo.getTerrainType().getHorizon(this); + return provider.getHorizon(); } /** @@ -3964,4 +4045,65 @@ var7.destroyBlockPartially(par1, par2, par3, par4, par5); } } + + /** + * Adds a single TileEntity to the world. + * @param entity The TileEntity to be added. + */ + public void addTileEntity(TileEntity entity) + { + List dest = scanningTileEntities ? addedTileEntityList : loadedTileEntityList; + if(entity.canUpdate()) + { + dest.add(entity); + } + } + + /** + * Determine if the given block is considered solid on the + * specified side. Used by placement logic. + * + * @param X Block X Position + * @param Y Block Y Position + * @param Z Block Z Position + * @param side The Side in question + * @return True if the side is solid + */ + public boolean isBlockSolidOnSide(int X, int Y, int Z, ForgeDirection side) + { + return isBlockSolidOnSide(X, Y, Z, side, false); + } + + /** + * Determine if the given block is considered solid on the + * specified side. Used by placement logic. + * + * @param X Block X Position + * @param Y Block Y Position + * @param Z Block Z Position + * @param side The Side in question + * @param _default The defult to return if the block doesn't exist. + * @return True if the side is solid + */ + public boolean isBlockSolidOnSide(int X, int Y, int Z, ForgeDirection side, boolean _default) + { + if (X < -30000000 || Z < -30000000 || X >= 30000000 || Z >= 30000000) + { + return _default; + } + + Chunk var5 = this.chunkProvider.provideChunk(X >> 4, Z >> 4); + if (var5 == null || var5.isEmpty()) + { + return _default; + } + + Block block = Block.blocksList[getBlockId(X, Y, Z)]; + if(block == null) + { + return false; + } + + return block.isBlockSolidOnSide(this, X, Y, Z, side); + } }