package net.minecraft.src;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collection;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Random;
import java.util.Set;
import gnu.trove.map.hash.TIntObjectHashMap;
import com.prupe.mcpatcher.cc.ColorizeWorld;
import com.prupe.mcpatcher.cc.Colorizer;
import org.newdawn.slick.opengl.Texture;
import net.minecraft.server.MinecraftServer;
import net.minecraft.src.NBTTagCompound;
// Spout Start
import org.spoutcraft.api.Spoutcraft;
import org.spoutcraft.api.material.CustomBlock;
import org.spoutcraft.api.material.MaterialData;
import org.spoutcraft.client.SpoutClient;
import org.spoutcraft.client.SpoutcraftWorld;
import org.spoutcraft.client.block.SpoutcraftChunk;
import org.spoutcraft.client.config.Configuration;
// Spout End
public abstract class World implements IBlockAccess {
/**
* boolean; if true updates scheduled by scheduleBlockUpdate happen immediately
*/
public boolean scheduledUpdatesAreImmediate;
/** A list of all Entities in all currently-loaded chunks */
public List loadedEntityList = new ArrayList();
protected List unloadedEntityList = new ArrayList();
/** A list of all TileEntities in all currently-loaded chunks */
public List loadedTileEntityList = new ArrayList();
private List addedTileEntityList = new ArrayList();
/** Entities marked for removal. */
private List entityRemoval = new ArrayList();
/** Array list of players in the world. */
public List playerEntities = new ArrayList();
/** a list of all the lightning entities */
public List weatherEffects = new ArrayList();
private long cloudColour = 16777215L;
/** How much light is subtracted from full daylight */
public int skylightSubtracted;
/**
* Contains the current Linear Congruential Generator seed for block updates. Used with an A value of 3 and a C value
* of 0x3c6ef35f, producing a highly planar series of values ill-suited for choosing random blocks in a 16x128x16
* field.
*/
protected int updateLCG = (new Random()).nextInt();
/**
* magic number used to generate fast random numbers for 3d distribution within a chunk
*/
protected final int DIST_HASH_MAGIC = 1013904223;
protected float prevRainingStrength;
protected float rainingStrength;
protected float prevThunderingStrength;
protected float thunderingStrength;
/**
* Set to 2 whenever a lightning bolt is generated in SSP. Decrements if > 0 in updateWeather(). Value appears to be
* unused.
*/
public int lastLightningBolt;
/** Option > Difficulty setting (0 - 3) */
public int difficultySetting;
/** RNG for World. */
public Random rand = new Random();
/** The WorldProvider instance that World uses. */
public final WorldProvider provider;
protected List worldAccesses = new ArrayList();
/** Handles chunk operations and caching */
// Spout Start - protected to public
public IChunkProvider chunkProvider;
// Spout End
protected final ISaveHandler saveHandler;
/**
* holds information about a world (size on disk, time, spawn point, seed, ...)
*/
// Spout Start - protected to public
public WorldInfo worldInfo;
// Spout End
/** Boolean that is set to true when trying to find a spawn point */
public boolean findingSpawnPoint;
public MapStorage mapStorage;
public final VillageCollection villageCollectionObj;
protected final VillageSiege villageSiegeObj = new VillageSiege(this);
public final Profiler theProfiler;
/** The world-local pool of vectors */
private final Vec3Pool vecPool = new Vec3Pool(300, 2000);
private final Calendar theCalendar = Calendar.getInstance();
protected Scoreboard worldScoreboard = new Scoreboard();
/** The log agent for this world. */
private final ILogAgent worldLogAgent;
private ArrayList collidingBoundingBoxes = new ArrayList();
private boolean scanningTileEntities;
/** indicates if enemies are spawned or not */
// Spout Start - protected to public
public boolean spawnHostileMobs = true;
// Spout End
/** A flag indicating whether we should spawn peaceful mobs. */
// Spout Start - protected to public
public boolean spawnPeacefulMobs = true;
// Spout End
/** Positions to update */
protected Set activeChunkSet = new HashSet();
/** number of ticks until the next random ambients play */
private int ambientTickCountdown;
/**
* is a temporary list of blocks and light values used when updating light levels. Holds up to 32x32x32 blocks (the
* maximum influence of a light source.) Every element is a packed bit value: 0000000000LLLLzzzzzzyyyyyyxxxxxx. The
* 4-bit L is a light level used when darkening blocks. 6-bit numbers x, y and z represent the block's offset from the
* original block, plus 32 (i.e. value of 31 would mean a -1 offset
*/
// Spout Start - public
public int[] lightUpdateBlockList;
// Spout End
/** This is set to true for client worlds, and false for server worlds. */
public boolean isRemote;
// Spout Start
public final SpoutcraftWorld world = new SpoutcraftWorld(this);
public final TIntObjectHashMap<String> customTitles = new TIntObjectHashMap<String>(200);
// Spout End
/**
* Gets the biome for a given set of x/z coordinates
*/
public BiomeGenBase getBiomeGenForCoords(int par1, int par2) {
if (this.blockExists(par1, 0, par2)) {
Chunk var3 = this.getChunkFromBlockCoords(par1, par2);
if (var3 != null) {
return var3.getBiomeGenForWorldCoords(par1 & 15, par2 & 15, this.provider.worldChunkMgr);
}
}
return this.provider.worldChunkMgr.getBiomeGenAt(par1, par2);
}
public WorldChunkManager getWorldChunkManager() {
return this.provider.worldChunkMgr;
}
public World(ISaveHandler par1ISaveHandler, String par2Str, WorldProvider par3WorldProvider, WorldSettings par4WorldSettings, Profiler par5Profiler, ILogAgent par6ILogAgent) {
this.ambientTickCountdown = this.rand.nextInt(12000);
if (Configuration.optimizedLightingUpdates) {
this.lightUpdateBlockList = new int[256];
} else {
this.lightUpdateBlockList = new int[32768];
}
this.saveHandler = par1ISaveHandler;
this.theProfiler = par5Profiler;
this.worldInfo = new WorldInfo(par4WorldSettings, par2Str);
this.provider = par3WorldProvider;
this.mapStorage = new MapStorage(par1ISaveHandler);
this.worldLogAgent = par6ILogAgent;
VillageCollection var7 = (VillageCollection)this.mapStorage.loadData(VillageCollection.class, "villages");
if (var7 == null) {
this.villageCollectionObj = new VillageCollection(this);
this.mapStorage.setData("villages", this.villageCollectionObj);
} else {
this.villageCollectionObj = var7;
this.villageCollectionObj.func_82566_a(this);
}
par3WorldProvider.registerWorld(this);
this.chunkProvider = this.createChunkProvider();
this.calculateInitialSkylight();
this.calculateInitialWeather();
}
public World(ISaveHandler par1ISaveHandler, String par2Str, WorldSettings par3WorldSettings, WorldProvider par4WorldProvider, Profiler par5Profiler, ILogAgent par6ILogAgent) {
this.ambientTickCountdown = this.rand.nextInt(12000);
if (Configuration.optimizedLightingUpdates) {
this.lightUpdateBlockList = new int[256];
} else {
this.lightUpdateBlockList = new int[32768];
}
this.saveHandler = par1ISaveHandler;
this.theProfiler = par5Profiler;
this.mapStorage = new MapStorage(par1ISaveHandler);
this.worldLogAgent = par6ILogAgent;
this.worldInfo = par1ISaveHandler.loadWorldInfo();
if (par4WorldProvider != null) {
this.provider = par4WorldProvider;
} else if (this.worldInfo != null && this.worldInfo.getVanillaDimension() != 0) {
this.provider = WorldProvider.getProviderForDimension(this.worldInfo.getVanillaDimension());
} else {
this.provider = WorldProvider.getProviderForDimension(0);
}
if (this.worldInfo == null) {
this.worldInfo = new WorldInfo(par3WorldSettings, par2Str);
} else {
this.worldInfo.setWorldName(par2Str);
}
this.provider.registerWorld(this);
this.chunkProvider = this.createChunkProvider();
if (!this.worldInfo.isInitialized()) {
try {
this.initialize(par3WorldSettings);
} catch (Throwable var11) {
CrashReport var8 = CrashReport.makeCrashReport(var11, "Exception initializing level");
try {
this.addWorldInfoToCrashReport(var8);
} catch (Throwable var10) {
;
}
throw new ReportedException(var8);
}
this.worldInfo.setServerInitialized(true);
}
VillageCollection var7 = (VillageCollection)this.mapStorage.loadData(VillageCollection.class, "villages");
if (var7 == null) {
this.villageCollectionObj = new VillageCollection(this);
this.mapStorage.setData("villages", this.villageCollectionObj);
} else {
this.villageCollectionObj = var7;
this.villageCollectionObj.func_82566_a(this);
}
this.calculateInitialSkylight();
this.calculateInitialWeather();
}
/**
* Creates the chunk provider for this world. Called in the constructor. Retrieves provider from worldProvider?
*/
protected abstract IChunkProvider createChunkProvider();
protected void initialize(WorldSettings par1WorldSettings) {
this.worldInfo.setServerInitialized(true);
}
/**
* Sets a new spawn location by finding an uncovered block at a random (x,z) location in the chunk.
*/
public void setSpawnLocation() {
this.setSpawnLocation(8, 64, 8);
}
/**
* Returns the block ID of the first block at this (x,z) location with air above it, searching from sea level upwards.
*/
public int getFirstUncoveredBlock(int par1, int par2) {
int var3;
for (var3 = 63; !this.isAirBlock(par1, var3 + 1, par2); ++var3) {
;
}
return this.getBlockId(par1, var3, par2);
}
/**
* Returns the block ID at coords x,y,z
*/
public int getBlockId(int par1, int par2, int par3) {
if (par1 >= -30000000 && par3 >= -30000000 && par1 < 30000000 && par3 < 30000000) {
if (par2 < 0) {
return 0;
} else if (par2 >= 256) {
return 0;
} else {
Chunk var4 = null;
try {
var4 = this.getChunkFromChunkCoords(par1 >> 4, par3 >> 4);
return var4.getBlockID(par1 & 15, par2, par3 & 15);
} catch (Throwable var8) {
CrashReport var6 = CrashReport.makeCrashReport(var8, "Exception getting block type in world");
CrashReportCategory var7 = var6.makeCategory("Requested block coordinates");
var7.addCrashSection("Found chunk", Boolean.valueOf(var4 == null));
var7.addCrashSection("Location", CrashReportCategory.getLocationInfo(par1, par2, par3));
throw new ReportedException(var6);
}
}
} else {
return 0;
}
}
/**
* Returns true if the block at the specified coordinates is empty
*/
public boolean isAirBlock(int par1, int par2, int par3) {
return this.getBlockId(par1, par2, par3) == 0;
}
/**
* Checks if a block at a given position should have a tile entity.
*/
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();
}
/**
* Returns the render type of the block at the given coordinate.
*/
public int blockGetRenderType(int par1, int par2, int par3) {
int var4 = this.getBlockId(par1, par2, par3);
return Block.blocksList[var4] != null ? Block.blocksList[var4].getRenderType() : -1;
}
/**
* Returns whether a block exists at world coordinates x, y, z
*/
public boolean blockExists(int par1, int par2, int par3) {
return par2 >= 0 && par2 < 256 ? this.chunkExists(par1 >> 4, par3 >> 4) : false;
}
/**
* Checks if any of the chunks within distance (argument 4) blocks of the given block exist
*/
public boolean doChunksNearChunkExist(int par1, int par2, int par3, int par4) {
return this.checkChunksExist(par1 - par4, par2 - par4, par3 - par4, par1 + par4, par2 + par4, par3 + par4);
}
/**
* Checks between a min and max all the chunks inbetween actually exist. Args: minX, minY, minZ, maxX, maxY, maxZ
*/
public boolean checkChunksExist(int par1, int par2, int par3, int par4, int par5, int par6) {
if (par5 >= 0 && par2 < 256) {
par1 >>= 4;
par3 >>= 4;
par4 >>= 4;
par6 >>= 4;
for (int var7 = par1; var7 <= par4; ++var7) {
for (int var8 = par3; var8 <= par6; ++var8) {
if (!this.chunkExists(var7, var8)) {
return false;
}
}
}
return true;
} else {
return false;
}
}
/**
* Returns whether a chunk exists at chunk coordinates x, y
*/
protected boolean chunkExists(int par1, int par2) {
return this.chunkProvider.chunkExists(par1, par2);
}
/**
* Returns a chunk looked up by block coordinates. Args: x, z
*/
public Chunk getChunkFromBlockCoords(int par1, int par2) {
return this.getChunkFromChunkCoords(par1 >> 4, par2 >> 4);
}
/**
* Returns back a chunk looked up by chunk coordinates Args: x, y
*/
public Chunk getChunkFromChunkCoords(int par1, int par2) {
return this.chunkProvider.provideChunk(par1, par2);
}
/**
* Sets the block ID and metadata at a given location. Args: X, Y, Z, new block ID, new metadata, flags. Flag 1 will
* cause a block update. Flag 2 will send the change to clients (you almost always want this). Flag 4 prevents the
* block from being re-rendered, if this is a client world. Flags can be added together.
*/
public boolean setBlock(int par1, int par2, int par3, int par4, int par5, int par6) {
if (par1 >= -30000000 && par3 >= -30000000 && par1 < 30000000 && par3 < 30000000) {
if (par2 < 0) {
return false;
} else if (par2 >= 256) {
return false;
} else {
Chunk var7 = this.getChunkFromChunkCoords(par1 >> 4, par3 >> 4);
int var8 = 0;
if ((par6 & 1) != 0) {
var8 = var7.getBlockID(par1 & 15, par2, par3 & 15);
}
boolean var9 = var7.setBlockIDWithMetadata(par1 & 15, par2, par3 & 15, par4, par5);
this.theProfiler.startSection("checkLight");
this.updateAllLightTypes(par1, par2, par3);
this.theProfiler.endSection();
if (var9) {
if ((par6 & 2) != 0 && (!this.isRemote || (par6 & 4) == 0)) {
this.markBlockForUpdate(par1, par2, par3);
}
if (!this.isRemote && (par6 & 1) != 0) {
this.notifyBlockChange(par1, par2, par3, var8);
Block var10 = Block.blocksList[par4];
if (var10 != null && var10.hasComparatorInputOverride()) {
this.func_96440_m(par1, par2, par3, par4);
}
}
}
return var9;
}
} else {
return false;
}
}
/**
* Returns the block's material.
*/
public Material getBlockMaterial(int par1, int par2, int par3) {
int var4 = this.getBlockId(par1, par2, par3);
return var4 == 0 ? Material.air : Block.blocksList[var4].blockMaterial;
}
/**
* Returns the block metadata at coords x,y,z
*/
public int getBlockMetadata(int par1, int par2, int par3) {
if (par1 >= -30000000 && par3 >= -30000000 && par1 < 30000000 && par3 < 30000000) {
if (par2 < 0) {
return 0;
} else if (par2 >= 256) {
return 0;
} else {
Chunk var4 = this.getChunkFromChunkCoords(par1 >> 4, par3 >> 4);
par1 &= 15;
par3 &= 15;
return var4.getBlockMetadata(par1, par2, par3);
}
} else {
return 0;
}
}
/**
* Sets the blocks metadata and if set will then notify blocks that this block changed, depending on the flag. Args: x,
* y, z, metadata, flag. See setBlock for flag description
*/
public boolean setBlockMetadataWithNotify(int par1, int par2, int par3, int par4, int par5) {
if (par1 >= -30000000 && par3 >= -30000000 && par1 < 30000000 && par3 < 30000000) {
if (par2 < 0) {
return false;
} else if (par2 >= 256) {
return false;
} else {
Chunk var6 = this.getChunkFromChunkCoords(par1 >> 4, par3 >> 4);
int var7 = par1 & 15;
int var8 = par3 & 15;
boolean var9 = var6.setBlockMetadata(var7, par2, var8, par4);
if (var9) {
int var10 = var6.getBlockID(var7, par2, var8);
if ((par5 & 2) != 0 && (!this.isRemote || (par5 & 4) == 0)) {
this.markBlockForUpdate(par1, par2, par3);
}
if (!this.isRemote && (par5 & 1) != 0) {
this.notifyBlockChange(par1, par2, par3, var10);
Block var11 = Block.blocksList[var10];
if (var11 != null && var11.hasComparatorInputOverride()) {
this.func_96440_m(par1, par2, par3, var10);
}
}
}
return var9;
}
} else {
return false;
}
}
/**
* Sets a block to 0 and notifies relevant systems with the block change Args: x, y, z
*/
public boolean setBlockToAir(int par1, int par2, int par3) {
return this.setBlock(par1, par2, par3, 0, 0, 3);
}
/**
* Destroys a block and optionally drops items. Args: X, Y, Z, dropItems
*/
public boolean destroyBlock(int par1, int par2, int par3, boolean par4) {
int var5 = this.getBlockId(par1, par2, par3);
if (var5 > 0) {
int var6 = this.getBlockMetadata(par1, par2, par3);
this.playAuxSFX(2001, par1, par2, par3, var5 + (var6 << 12));
if (par4) {
Block.blocksList[var5].dropBlockAsItem(this, par1, par2, par3, var6, 0);
}
return this.setBlock(par1, par2, par3, 0, 0, 3);
} else {
return false;
}
}
/**
* Sets a block and notifies relevant systems with the block change Args: x, y, z, blockID
*/
public boolean setBlock(int par1, int par2, int par3, int par4) {
return this.setBlock(par1, par2, par3, par4, 0, 3);
}
/**
* On the client, re-renders the block. On the server, sends the block to the client (which will re-render it only if
* the ID or MD changes), including the tile entity description packet if applicable. Args: x, y, z
*/
public void markBlockForUpdate(int par1, int par2, int par3) {
for (int var4 = 0; var4 < this.worldAccesses.size(); ++var4) {
((IWorldAccess)this.worldAccesses.get(var4)).markBlockForUpdate(par1, par2, par3);
}
}
/**
* The block type change and need to notify other systems Args: x, y, z, blockID
*/
public void notifyBlockChange(int par1, int par2, int par3, int par4) {
this.notifyBlocksOfNeighborChange(par1, par2, par3, par4);
}
/**
* marks a vertical line of blocks as dirty
*/
public void markBlocksDirtyVertical(int par1, int par2, int par3, int par4) {
int var5;
if (par3 > par4) {
var5 = par4;
par4 = par3;
par3 = var5;
}
if (!this.provider.hasNoSky) {
for (var5 = par3; var5 <= par4; ++var5) {
this.updateLightByType(EnumSkyBlock.Sky, par1, var5, par2);
}
}
this.markBlockRangeForRenderUpdate(par1, par3, par2, par1, par4, par2);
}
/**
* On the client, re-renders all blocks in this range, inclusive. On the server, does nothing. Args: min x, min y, min
* z, max x, max y, max z
*/
public void markBlockRangeForRenderUpdate(int par1, int par2, int par3, int par4, int par5, int par6) {
for (int var7 = 0; var7 < this.worldAccesses.size(); ++var7) {
((IWorldAccess)this.worldAccesses.get(var7)).markBlockRangeForRenderUpdate(par1, par2, par3, par4, par5, par6);
}
}
/**
* Notifies neighboring blocks that this specified block changed Args: x, y, z, blockID
*/
public void notifyBlocksOfNeighborChange(int par1, int par2, int par3, int par4) {
this.notifyBlockOfNeighborChange(par1 - 1, par2, par3, par4);
this.notifyBlockOfNeighborChange(par1 + 1, par2, par3, par4);
this.notifyBlockOfNeighborChange(par1, par2 - 1, par3, par4);
this.notifyBlockOfNeighborChange(par1, par2 + 1, par3, par4);
this.notifyBlockOfNeighborChange(par1, par2, par3 - 1, par4);
this.notifyBlockOfNeighborChange(par1, par2, par3 + 1, par4);
}
/**
* Calls notifyBlockOfNeighborChange on adjacent blocks, except the one on the given side. Args: X, Y, Z,
* changingBlockID, side
*/
public void notifyBlocksOfNeighborChange(int par1, int par2, int par3, int par4, int par5) {
if (par5 != 4) {
this.notifyBlockOfNeighborChange(par1 - 1, par2, par3, par4);
}
if (par5 != 5) {
this.notifyBlockOfNeighborChange(par1 + 1, par2, par3, par4);
}
if (par5 != 0) {
this.notifyBlockOfNeighborChange(par1, par2 - 1, par3, par4);
}
if (par5 != 1) {
this.notifyBlockOfNeighborChange(par1, par2 + 1, par3, par4);
}
if (par5 != 2) {
this.notifyBlockOfNeighborChange(par1, par2, par3 - 1, par4);
}
if (par5 != 3) {
this.notifyBlockOfNeighborChange(par1, par2, par3 + 1, par4);
}
}
/**
* Notifies a block that one of its neighbor change to the specified type Args: x, y, z, blockID
*/
public void notifyBlockOfNeighborChange(int par1, int par2, int par3, int par4) {
if (!this.isRemote) {
int var5 = this.getBlockId(par1, par2, par3);
Block var6 = Block.blocksList[var5];
if (var6 != null) {
try {
var6.onNeighborBlockChange(this, par1, par2, par3, par4);
} catch (Throwable var13) {
CrashReport var8 = CrashReport.makeCrashReport(var13, "Exception while updating neighbours");
CrashReportCategory var9 = var8.makeCategory("Block being updated");
int var10;
try {
var10 = this.getBlockMetadata(par1, par2, par3);
} catch (Throwable var12) {
var10 = -1;
}
var9.addCrashSectionCallable("Source block type", new CallableLvl1(this, par4));
CrashReportCategory.addBlockCrashInfo(var9, par1, par2, par3, var5, var10);
throw new ReportedException(var8);
}
}
}
}
/**
* Returns true if the given block will receive a scheduled tick in this tick. Args: X, Y, Z, blockID
*/
public boolean isBlockTickScheduledThisTick(int par1, int par2, int par3, int par4) {
return false;
}
/**
* Checks if the specified block is able to see the sky
*/
public boolean canBlockSeeTheSky(int par1, int par2, int par3) {
return this.getChunkFromChunkCoords(par1 >> 4, par3 >> 4).canBlockSeeTheSky(par1 & 15, par2, par3 & 15);
}
/**
* Does the same as getBlockLightValue_do but without checking if its not a normal block
*/
public int getFullBlockLightValue(int par1, int par2, int par3) {
if (par2 < 0) {
return 0;
} else {
if (par2 >= 256) {
par2 = 255;
}
return this.getChunkFromChunkCoords(par1 >> 4, par3 >> 4).getBlockLightValue(par1 & 15, par2, par3 & 15, 0);
}
}
/**
* Gets the light value of a block location
*/
public int getBlockLightValue(int par1, int par2, int par3) {
return this.getBlockLightValue_do(par1, par2, par3, true);
}
/**
* Gets the light value of a block location. This is the actual function that gets the value and has a bool flag that
* indicates if its a half step block to get the maximum light value of a direct neighboring block (left, right,
* forward, back, and up)
*/
public int getBlockLightValue_do(int par1, int par2, int par3, boolean par4) {
if (par1 >= -30000000 && par3 >= -30000000 && par1 < 30000000 && par3 < 30000000) {
if (par4) {
int var5 = this.getBlockId(par1, par2, par3);
if (Block.useNeighborBrightness[var5]) {
int var6 = this.getBlockLightValue_do(par1, par2 + 1, par3, false);
int var7 = this.getBlockLightValue_do(par1 + 1, par2, par3, false);
int var8 = this.getBlockLightValue_do(par1 - 1, par2, par3, false);
int var9 = this.getBlockLightValue_do(par1, par2, par3 + 1, false);
int var10 = this.getBlockLightValue_do(par1, par2, par3 - 1, false);
if (var7 > var6) {
var6 = var7;
}
if (var8 > var6) {
var6 = var8;
}
if (var9 > var6) {
var6 = var9;
}
if (var10 > var6) {
var6 = var10;
}
return var6;
}
}
if (par2 < 0) {
return 0;
} else {
if (par2 >= 256) {
par2 = 255;
}
Chunk var11 = this.getChunkFromChunkCoords(par1 >> 4, par3 >> 4);
par1 &= 15;
par3 &= 15;
return var11.getBlockLightValue(par1, par2, par3, this.skylightSubtracted);
}
} else {
return 15;
}
}
/**
* Returns the y coordinate with a block in it at this x, z coordinate
*/
public int getHeightValue(int par1, int par2) {
if (par1 >= -30000000 && par2 >= -30000000 && par1 < 30000000 && par2 < 30000000) {
if (!this.chunkExists(par1 >> 4, par2 >> 4)) {
return 0;
} else {
Chunk var3 = this.getChunkFromChunkCoords(par1 >> 4, par2 >> 4);
return var3.getHeightValue(par1 & 15, par2 & 15);
}
} else {
return 0;
}
}
/**
* Gets the heightMapMinimum field of the given chunk, or 0 if the chunk is not loaded. Coords are in blocks. Args: X,
* Z
*/
public int getChunkHeightMapMinimum(int par1, int par2) {
if (par1 >= -30000000 && par2 >= -30000000 && par1 < 30000000 && par2 < 30000000) {
if (!this.chunkExists(par1 >> 4, par2 >> 4)) {
return 0;
} else {
Chunk var3 = this.getChunkFromChunkCoords(par1 >> 4, par2 >> 4);
return var3.heightMapMinimum;
}
} else {
return 0;
}
}
/**
* Brightness for SkyBlock.Sky is clear white and (through color computing it is assumed) DEPENDENT ON DAYTIME.
* Brightness for SkyBlock.Block is yellowish and independent.
*/
public int getSkyBlockTypeBrightness(EnumSkyBlock par1EnumSkyBlock, int par2, int par3, int par4) {
if (this.provider.hasNoSky && par1EnumSkyBlock == EnumSkyBlock.Sky) {
return 0;
} else {
if (par3 < 0) {
par3 = 0;
}
if (par3 >= 256) {
return par1EnumSkyBlock.defaultLightValue;
} else if (par2 >= -30000000 && par4 >= -30000000 && par2 < 30000000 && par4 < 30000000) {
int var5 = par2 >> 4;
int var6 = par4 >> 4;
if (!this.chunkExists(var5, var6)) {
return par1EnumSkyBlock.defaultLightValue;
} else if (Block.useNeighborBrightness[this.getBlockId(par2, par3, par4)]) {
int var12 = this.getSavedLightValue(par1EnumSkyBlock, par2, par3 + 1, par4);
int var8 = this.getSavedLightValue(par1EnumSkyBlock, par2 + 1, par3, par4);
int var9 = this.getSavedLightValue(par1EnumSkyBlock, par2 - 1, par3, par4);
int var10 = this.getSavedLightValue(par1EnumSkyBlock, par2, par3, par4 + 1);
int var11 = this.getSavedLightValue(par1EnumSkyBlock, par2, par3, par4 - 1);
if (var8 > var12) {
var12 = var8;
}
if (var9 > var12) {
var12 = var9;
}
if (var10 > var12) {
var12 = var10;
}
if (var11 > var12) {
var12 = var11;
}
return var12;
} else {
Chunk var7 = this.getChunkFromChunkCoords(var5, var6);
return var7.getSavedLightValue(par1EnumSkyBlock, par2 & 15, par3, par4 & 15);
}
} else {
return par1EnumSkyBlock.defaultLightValue;
}
}
}
/**
* Returns saved light value without taking into account the time of day. Either looks in the sky light map or block
* light map based on the enumSkyBlock arg.
*/
public int getSavedLightValue(EnumSkyBlock par1EnumSkyBlock, int par2, int par3, int par4) {
if (par3 < 0) {
par3 = 0;
}
if (par3 >= 256) {
par3 = 255;
}
if (par2 >= -30000000 && par4 >= -30000000 && par2 < 30000000 && par4 < 30000000) {
int var5 = par2 >> 4;
int var6 = par4 >> 4;
if (!this.chunkExists(var5, var6)) {
return par1EnumSkyBlock.defaultLightValue;
} else {
Chunk var7 = this.getChunkFromChunkCoords(var5, var6);
return var7.getSavedLightValue(par1EnumSkyBlock, par2 & 15, par3, par4 & 15);
}
} else {
return par1EnumSkyBlock.defaultLightValue;
}
}
/**
* Sets the light value either into the sky map or block map depending on if enumSkyBlock is set to sky or block. Args:
* enumSkyBlock, x, y, z, lightValue
*/
public void setLightValue(EnumSkyBlock par1EnumSkyBlock, int par2, int par3, int par4, int par5) {
if (par2 >= -30000000 && par4 >= -30000000 && par2 < 30000000 && par4 < 30000000) {
if (par3 >= 0) {
if (par3 < 256) {
if (this.chunkExists(par2 >> 4, par4 >> 4)) {
Chunk var6 = this.getChunkFromChunkCoords(par2 >> 4, par4 >> 4);
var6.setLightValue(par1EnumSkyBlock, par2 & 15, par3, par4 & 15, par5);
for (int var7 = 0; var7 < this.worldAccesses.size(); ++var7) {
((IWorldAccess)this.worldAccesses.get(var7)).markBlockForRenderUpdate(par2, par3, par4);
}
}
}
}
}
}
/**
* On the client, re-renders this block. On the server, does nothing. Used for lighting updates.
*/
public void markBlockForRenderUpdate(int par1, int par2, int par3) {
for (int var4 = 0; var4 < this.worldAccesses.size(); ++var4) {
((IWorldAccess)this.worldAccesses.get(var4)).markBlockForRenderUpdate(par1, par2, par3);
}
}
/**
* Any Light rendered on a 1.8 Block goes through here
*/
public int getLightBrightnessForSkyBlocks(int par1, int par2, int par3, int par4) {
int var5 = this.getSkyBlockTypeBrightness(EnumSkyBlock.Sky, par1, par2, par3);
int var6 = this.getSkyBlockTypeBrightness(EnumSkyBlock.Block, par1, par2, par3);
if (var6 < par4) {
var6 = par4;
}
return var5 << 20 | var6 << 4;
}
public float getBrightness(int par1, int par2, int par3, int par4) {
int var5 = this.getBlockLightValue(par1, par2, par3);
if (var5 < par4) {
var5 = par4;
}
return this.provider.lightBrightnessTable[var5];
}
/**
* Returns how bright the block is shown as which is the block's light value looked up in a lookup table (light values
* aren't linear for brightness). Args: x, y, z
*/
public float getLightBrightness(int par1, int par2, int par3) {
return this.provider.lightBrightnessTable[this.getBlockLightValue(par1, par2, par3)];
}
/**
* Checks whether its daytime by seeing if the light subtracted from the skylight is less than 4
*/
public boolean isDaytime() {
return this.skylightSubtracted < 4;
}
/**
* Performs a raycast against all blocks in the world except liquids.
*/
public MovingObjectPosition clip(Vec3 par1Vec3, Vec3 par2Vec3) {
return this.rayTraceBlocks_do_do(par1Vec3, par2Vec3, false, false);
}
/**
* Performs a raycast against all blocks in the world, and optionally liquids.
*/
public MovingObjectPosition clip(Vec3 par1Vec3, Vec3 par2Vec3, boolean par3) {
return this.rayTraceBlocks_do_do(par1Vec3, par2Vec3, par3, false);
}
public MovingObjectPosition rayTraceBlocks_do_do(Vec3 par1Vec3, Vec3 par2Vec3, boolean par3, boolean par4) {
if (!Double.isNaN(par1Vec3.xCoord) && !Double.isNaN(par1Vec3.yCoord) && !Double.isNaN(par1Vec3.zCoord)) {
if (!Double.isNaN(par2Vec3.xCoord) && !Double.isNaN(par2Vec3.yCoord) && !Double.isNaN(par2Vec3.zCoord)) {
int var5 = MathHelper.floor_double(par2Vec3.xCoord);
int var6 = MathHelper.floor_double(par2Vec3.yCoord);
int var7 = MathHelper.floor_double(par2Vec3.zCoord);
int var8 = MathHelper.floor_double(par1Vec3.xCoord);
int var9 = MathHelper.floor_double(par1Vec3.yCoord);
int var10 = MathHelper.floor_double(par1Vec3.zCoord);
int var11 = this.getBlockId(var8, var9, var10);
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)) {
MovingObjectPosition var14 = var13.collisionRayTrace(this, var8, var9, var10, par1Vec3, par2Vec3);
if (var14 != null) {
return var14;
}
}
var11 = 200;
while (var11-- >= 0) {
if (Double.isNaN(par1Vec3.xCoord) || Double.isNaN(par1Vec3.yCoord) || Double.isNaN(par1Vec3.zCoord)) {
return null;
}
if (var8 == var5 && var9 == var6 && var10 == var7) {
return null;
}
boolean var39 = true;
boolean var40 = true;
boolean var41 = true;
double var15 = 999.0D;
double var17 = 999.0D;
double var19 = 999.0D;
if (var5 > var8) {
var15 = (double)var8 + 1.0D;
} else if (var5 < var8) {
var15 = (double)var8 + 0.0D;
} else {
var39 = false;
}
if (var6 > var9) {
var17 = (double)var9 + 1.0D;
} else if (var6 < var9) {
var17 = (double)var9 + 0.0D;
} else {
var40 = false;
}
if (var7 > var10) {
var19 = (double)var10 + 1.0D;
} else if (var7 < var10) {
var19 = (double)var10 + 0.0D;
} else {
var41 = false;
}
double var21 = 999.0D;
double var23 = 999.0D;
double var25 = 999.0D;
double var27 = par2Vec3.xCoord - par1Vec3.xCoord;
double var29 = par2Vec3.yCoord - par1Vec3.yCoord;
double var31 = par2Vec3.zCoord - par1Vec3.zCoord;
if (var39) {
var21 = (var15 - par1Vec3.xCoord) / var27;
}
if (var40) {
var23 = (var17 - par1Vec3.yCoord) / var29;
}
if (var41) {
var25 = (var19 - par1Vec3.zCoord) / var31;
}
boolean var33 = false;
byte var42;
if (var21 < var23 && var21 < var25) {
if (var5 > var8) {
var42 = 4;
} else {
var42 = 5;
}
par1Vec3.xCoord = var15;
par1Vec3.yCoord += var29 * var21;
par1Vec3.zCoord += var31 * var21;
} else if (var23 < var25) {
if (var6 > var9) {
var42 = 0;
} else {
var42 = 1;
}
par1Vec3.xCoord += var27 * var23;
par1Vec3.yCoord = var17;
par1Vec3.zCoord += var31 * var23;
} else {
if (var7 > var10) {
var42 = 2;
} else {
var42 = 3;
}
par1Vec3.xCoord += var27 * var25;
par1Vec3.yCoord += var29 * var25;
par1Vec3.zCoord = var19;
}
Vec3 var34 = this.getWorldVec3Pool().getVecFromPool(par1Vec3.xCoord, par1Vec3.yCoord, par1Vec3.zCoord);
var8 = (int)(var34.xCoord = (double)MathHelper.floor_double(par1Vec3.xCoord));
if (var42 == 5) {
--var8;
++var34.xCoord;
}
var9 = (int)(var34.yCoord = (double)MathHelper.floor_double(par1Vec3.yCoord));
if (var42 == 1) {
--var9;
++var34.yCoord;
}
var10 = (int)(var34.zCoord = (double)MathHelper.floor_double(par1Vec3.zCoord));
if (var42 == 3) {
--var10;
++var34.zCoord;
}
int var35 = this.getBlockId(var8, var9, var10);
int var36 = this.getBlockMetadata(var8, var9, var10);
Block var37 = Block.blocksList[var35];
if ((!par4 || var37 == null || var37.getCollisionBoundingBoxFromPool(this, var8, var9, var10) != null) && var35 > 0 && var37.canCollideCheck(var36, par3)) {
MovingObjectPosition var38 = var37.collisionRayTrace(this, var8, var9, var10, par1Vec3, par2Vec3);
if (var38 != null) {
return var38;
}
}
}
return null;
} else {
return null;
}
} else {
return null;
}
}
/**
* Plays a sound at the entity's position. Args: entity, sound, volume (relative to 1.0), and frequency (or pitch, also
* relative to 1.0).
*/
public void playSoundAtEntity(Entity par1Entity, String par2Str, float par3, float par4) {
if (par1Entity != null && par2Str != null) {
for (int var5 = 0; var5 < this.worldAccesses.size(); ++var5) {
((IWorldAccess)this.worldAccesses.get(var5)).playSound(par2Str, par1Entity.posX, par1Entity.posY - (double)par1Entity.yOffset, par1Entity.posZ, par3, par4);
}
}
}
/**
* Plays sound to all near players except the player reference given
*/
public void playSoundToNearExcept(EntityPlayer par1EntityPlayer, String par2Str, float par3, float par4) {
if (par1EntityPlayer != null && par2Str != null) {
for (int var5 = 0; var5 < this.worldAccesses.size(); ++var5) {
((IWorldAccess)this.worldAccesses.get(var5)).playSoundToNearExcept(par1EntityPlayer, par2Str, par1EntityPlayer.posX, par1EntityPlayer.posY - (double)par1EntityPlayer.yOffset, par1EntityPlayer.posZ, par3, par4);
}
}
}
/**
* Play a sound effect. Many many parameters for this function. Not sure what they do, but a classic call is :
* (double)i + 0.5D, (double)j + 0.5D, (double)k + 0.5D, 'random.door_open', 1.0F, world.rand.nextFloat() * 0.1F + 0.9F
* with i,j,k position of the block.
*/
public void playSoundEffect(double par1, double par3, double par5, String par7Str, float par8, float par9) {
if (par7Str != null) {
for (int var10 = 0; var10 < this.worldAccesses.size(); ++var10) {
((IWorldAccess)this.worldAccesses.get(var10)).playSound(par7Str, par1, par3, par5, par8, par9);
}
}
}
/**
* par8 is loudness, all pars passed to minecraftInstance.sndManager.playSound
*/
public void playSound(double par1, double par3, double par5, String par7Str, float par8, float par9, boolean par10) {}
/**
* Plays a record at the specified coordinates of the specified name. Args: recordName, x, y, z
*/
public void playRecord(String par1Str, int par2, int par3, int par4) {
for (int var5 = 0; var5 < this.worldAccesses.size(); ++var5) {
((IWorldAccess)this.worldAccesses.get(var5)).playRecord(par1Str, par2, par3, par4);
}
}
/**
* Spawns a particle. Args particleName, x, y, z, velX, velY, velZ
*/
public void spawnParticle(String par1Str, double par2, double par4, double par6, double par8, double par10, double par12) {
spawnParticle(par1Str, par2, par4, par6, par8, par10, par12, null);
}
// Spout Start
// Custom Particle Methods
public void spawnParticle(String par1Str, double par2, double par4, double par6, double par8, double par10, double par12, Texture texture) {
for (int var14 = 0; var14 < this.worldAccesses.size(); ++var14) {
((IWorldAccess)this.worldAccesses.get(var14)).spawnParticle(par1Str, par2, par4, par6, par8, par10, par12, texture);
}
}
// Spout End
/**
* adds a lightning bolt to the list of lightning bolts in this world.
*/
public boolean addWeatherEffect(Entity par1Entity) {
this.weatherEffects.add(par1Entity);
return true;
}
/**
* Called to place all entities as part of a world
*/
public boolean spawnEntityInWorld(Entity par1Entity) {
int var2 = MathHelper.floor_double(par1Entity.posX / 16.0D);
int var3 = MathHelper.floor_double(par1Entity.posZ / 16.0D);
boolean var4 = par1Entity.forceSpawn;
if (par1Entity instanceof EntityPlayer) {
var4 = true;
}
if (!var4 && !this.chunkExists(var2, var3)) {
return false;
} else {
if (par1Entity instanceof EntityPlayer) {
EntityPlayer var5 = (EntityPlayer)par1Entity;
this.playerEntities.add(var5);
this.updateAllPlayersSleepingFlag();
}
this.getChunkFromChunkCoords(var2, var3).addEntity(par1Entity);
this.loadedEntityList.add(par1Entity);
this.onEntityAdded(par1Entity);
return true;
}
}
//ToDo: Was obtainEntitySkin + Spoutcraft API code
protected void onEntityAdded(Entity par1Entity) {
for (int var2 = 0; var2 < this.worldAccesses.size(); ++var2) {
((IWorldAccess)this.worldAccesses.get(var2)).onEntityCreate(par1Entity);
}
}
//ToDo: was releaseEntitySkin + Spoutcraft API code
protected void onEntityRemoved(Entity par1Entity) {
for (int var2 = 0; var2 < this.worldAccesses.size(); ++var2) {
((IWorldAccess)this.worldAccesses.get(var2)).onEntityDestroy(par1Entity);
}
}
/**
* Schedule the entity for removal during the next tick. Marks the entity dead in anticipation.
*/
public void removeEntity(Entity par1Entity) {
if (par1Entity.riddenByEntity != null) {
par1Entity.riddenByEntity.mountEntity((Entity)null);
}
if (par1Entity.ridingEntity != null) {
par1Entity.mountEntity((Entity)null);
}
par1Entity.setDead();
if (par1Entity instanceof EntityPlayer) {
this.playerEntities.remove(par1Entity);
this.updateAllPlayersSleepingFlag();
}
}
/**
* Do NOT use this method to remove normal entities- use normal removeEntity
*/
public void removePlayerEntityDangerously(Entity par1Entity) {
par1Entity.setDead();
if (par1Entity instanceof EntityPlayer) {
this.playerEntities.remove(par1Entity);
this.updateAllPlayersSleepingFlag();
}
int var2 = par1Entity.chunkCoordX;
int var3 = par1Entity.chunkCoordZ;
if (par1Entity.addedToChunk && this.chunkExists(var2, var3)) {
this.getChunkFromChunkCoords(var2, var3).removeEntity(par1Entity);
}
this.loadedEntityList.remove(par1Entity);
this.onEntityRemoved(par1Entity);
}
/**
* Adds a IWorldAccess to the list of worldAccesses
*/
public void addWorldAccess(IWorldAccess par1IWorldAccess) {
this.worldAccesses.add(par1IWorldAccess);
}
/**
* Removes a worldAccess from the worldAccesses object
*/
public void removeWorldAccess(IWorldAccess par1IWorldAccess) {
this.worldAccesses.remove(par1IWorldAccess);
}
/**
* Returns a list of bounding boxes that collide with aabb excluding the passed in entity's collision. Args: entity,
* aabb
*/
public List getCollidingBoundingBoxes(Entity par1Entity, AxisAlignedBB par2AxisAlignedBB) {
this.collidingBoundingBoxes.clear();
int var3 = MathHelper.floor_double(par2AxisAlignedBB.minX);
int var4 = MathHelper.floor_double(par2AxisAlignedBB.maxX + 1.0D);
int var5 = MathHelper.floor_double(par2AxisAlignedBB.minY);
int var6 = MathHelper.floor_double(par2AxisAlignedBB.maxY + 1.0D);
int var7 = MathHelper.floor_double(par2AxisAlignedBB.minZ);
int var8 = MathHelper.floor_double(par2AxisAlignedBB.maxZ + 1.0D);
for (int var9 = var3; var9 < var4; ++var9) {
for (int var10 = var7; var10 < var8; ++var10) {
if (this.blockExists(var9, 64, var10)) {
for (int var11 = var5 - 1; var11 < var6; ++var11) {
Block var12 = Block.blocksList[this.getBlockId(var9, var11, var10)];
if (var12 != null) {
var12.addCollisionBoxesToList(this, var9, var11, var10, par2AxisAlignedBB, this.collidingBoundingBoxes, par1Entity);
}
}
}
}
}
double var14 = 0.25D;
List var16 = this.getEntitiesWithinAABBExcludingEntity(par1Entity, par2AxisAlignedBB.expand(var14, var14, var14));
for (int var15 = 0; var15 < var16.size(); ++var15) {
AxisAlignedBB var13 = ((Entity)var16.get(var15)).getBoundingBox();
if (var13 != null && var13.intersectsWith(par2AxisAlignedBB)) {
this.collidingBoundingBoxes.add(var13);
}
var13 = par1Entity.getCollisionBox((Entity)var16.get(var15));
if (var13 != null && var13.intersectsWith(par2AxisAlignedBB)) {
this.collidingBoundingBoxes.add(var13);
}
}
return this.collidingBoundingBoxes;
}
/**
* calculates and returns a list of colliding bounding boxes within a given AABB
*/
public List getCollidingBlockBounds(AxisAlignedBB par1AxisAlignedBB) {
this.collidingBoundingBoxes.clear();
int var2 = MathHelper.floor_double(par1AxisAlignedBB.minX);
int var3 = MathHelper.floor_double(par1AxisAlignedBB.maxX + 1.0D);
int var4 = MathHelper.floor_double(par1AxisAlignedBB.minY);
int var5 = MathHelper.floor_double(par1AxisAlignedBB.maxY + 1.0D);
int var6 = MathHelper.floor_double(par1AxisAlignedBB.minZ);
int var7 = MathHelper.floor_double(par1AxisAlignedBB.maxZ + 1.0D);
for (int var8 = var2; var8 < var3; ++var8) {
for (int var9 = var6; var9 < var7; ++var9) {
if (this.blockExists(var8, 64, var9)) {
for (int var10 = var4 - 1; var10 < var5; ++var10) {
Block var11 = Block.blocksList[this.getBlockId(var8, var10, var9)];
if (var11 != null) {
var11.addCollisionBoxesToList(this, var8, var10, var9, par1AxisAlignedBB, this.collidingBoundingBoxes, (Entity)null);
}
}
}
}
}
return this.collidingBoundingBoxes;
}
/**
* Returns the amount of skylight subtracted for the current time
*/
public int calculateSkylightSubtracted(float par1) {
float var2 = this.getCelestialAngle(par1);
float var3 = 1.0F - (MathHelper.cos(var2 * (float)Math.PI * 2.0F) * 2.0F + 0.5F);
if (var3 < 0.0F) {
var3 = 0.0F;
}
if (var3 > 1.0F) {
var3 = 1.0F;
}
var3 = 1.0F - var3;
var3 = (float)((double)var3 * (1.0D - (double)(this.getRainStrength(par1) * 5.0F) / 16.0D));
var3 = (float)((double)var3 * (1.0D - (double)(this.getWeightedThunderStrength(par1) * 5.0F) / 16.0D));
var3 = 1.0F - var3;
return (int)(var3 * 11.0F);
}
/**
* Returns the sun brightness - checks time of day, rain and thunder
*/
public float getSunBrightness(float par1) {
float var2 = this.getCelestialAngle(par1);
float var3 = 1.0F - (MathHelper.cos(var2 * (float)Math.PI * 2.0F) * 2.0F + 0.2F);
if (var3 < 0.0F) {
var3 = 0.0F;
}
if (var3 > 1.0F) {
var3 = 1.0F;
}
var3 = 1.0F - var3;
var3 = (float)((double)var3 * (1.0D - (double)(this.getRainStrength(par1) * 5.0F) / 16.0D));
var3 = (float)((double)var3 * (1.0D - (double)(this.getWeightedThunderStrength(par1) * 5.0F) / 16.0D));
return var3 * 0.8F + 0.2F;
}
/**
* Calculates the color for the skybox
*/
public Vec3 getSkyColor(Entity par1Entity, float par2) {
float var3 = this.getCelestialAngle(par2);
float var4 = MathHelper.cos(var3 * (float)Math.PI * 2.0F) * 2.0F + 0.5F;
if (var4 < 0.0F) {
var4 = 0.0F;
}
if (var4 > 1.0F) {
var4 = 1.0F;
}
int var5 = MathHelper.floor_double(par1Entity.posX);
int var6 = MathHelper.floor_double(par1Entity.posZ);
BiomeGenBase var7 = this.getBiomeGenForCoords(var5, var6);
float var8 = var7.getFloatTemperature();
int var9 = var7.getSkyColorByTemp(var8);
// MCPatcher Start
ColorizeWorld.setupForFog(par1Entity);
float var10;
float var11;
float var12;
if (ColorizeWorld.computeSkyColor(this, par2)) {
var10 = Colorizer.setColor[0];
var11 = Colorizer.setColor[1];
var12 = Colorizer.setColor[2];
} else {
var10 = (float)(var9 >> 16 & 255) / 255.0F;
var11 = (float)(var9 >> 8 & 255) / 255.0F;
var12 = (float)(var9 & 255) / 255.0F;
}
// MCPatcher End
var10 *= var4;
var11 *= var4;
var12 *= var4;
float var13 = this.getRainStrength(par2);
float var14;
float var15;
if (var13 > 0.0F) {
var14 = (var10 * 0.3F + var11 * 0.59F + var12 * 0.11F) * 0.6F;
var15 = 1.0F - var13 * 0.75F;
var10 = var10 * var15 + var14 * (1.0F - var15);
var11 = var11 * var15 + var14 * (1.0F - var15);
var12 = var12 * var15 + var14 * (1.0F - var15);
}
var14 = this.getWeightedThunderStrength(par2);
if (var14 > 0.0F) {
var15 = (var10 * 0.3F + var11 * 0.59F + var12 * 0.11F) * 0.2F;
float var16 = 1.0F - var14 * 0.75F;
var10 = var10 * var16 + var15 * (1.0F - var16);
var11 = var11 * var16 + var15 * (1.0F - var16);
var12 = var12 * var16 + var15 * (1.0F - var16);
}
if (this.lastLightningBolt > 0) {
var15 = (float)this.lastLightningBolt - par2;
if (var15 > 1.0F) {
var15 = 1.0F;
}
var15 *= 0.45F;
var10 = var10 * (1.0F - var15) + 0.8F * var15;
var11 = var11 * (1.0F - var15) + 0.8F * var15;
var12 = var12 * (1.0F - var15) + 1.0F * var15;
}
return this.getWorldVec3Pool().getVecFromPool((double)var10, (double)var11, (double)var12);
}
/**
* calls calculateCelestialAngle
*/
public float getCelestialAngle(float par1) {
return this.provider.calculateCelestialAngle(this.worldInfo.getWorldTime(), par1);
}
public int getMoonPhase() {
return this.provider.getMoonPhase(this.worldInfo.getWorldTime());
}
/**
* gets the current fullness of the moon expressed as a float between 1.0 and 0.0, in steps of .25
*/
public float getCurrentMoonPhaseFactor() {
return WorldProvider.moonPhaseFactors[this.provider.getMoonPhase(this.worldInfo.getWorldTime())];
}
/**
* Return getCelestialAngle()*2*PI
*/
public float getCelestialAngleRadians(float par1) {
float var2 = this.getCelestialAngle(par1);
return var2 * (float)Math.PI * 2.0F;
}
public Vec3 getCloudColour(float par1) {
float var2 = this.getCelestialAngle(par1);
float var3 = MathHelper.cos(var2 * (float)Math.PI * 2.0F) * 2.0F + 0.5F;
if (var3 < 0.0F) {
var3 = 0.0F;
}
if (var3 > 1.0F) {
var3 = 1.0F;
}
float var4 = (float)(this.cloudColour >> 16 & 255L) / 255.0F;
float var5 = (float)(this.cloudColour >> 8 & 255L) / 255.0F;
float var6 = (float)(this.cloudColour & 255L) / 255.0F;
float var7 = this.getRainStrength(par1);
float var8;
float var9;
if (var7 > 0.0F) {
var8 = (var4 * 0.3F + var5 * 0.59F + var6 * 0.11F) * 0.6F;
var9 = 1.0F - var7 * 0.95F;
var4 = var4 * var9 + var8 * (1.0F - var9);
var5 = var5 * var9 + var8 * (1.0F - var9);
var6 = var6 * var9 + var8 * (1.0F - var9);
}
var4 *= var3 * 0.9F + 0.1F;
var5 *= var3 * 0.9F + 0.1F;
var6 *= var3 * 0.85F + 0.15F;
var8 = this.getWeightedThunderStrength(par1);
if (var8 > 0.0F) {
var9 = (var4 * 0.3F + var5 * 0.59F + var6 * 0.11F) * 0.2F;
float var10 = 1.0F - var8 * 0.95F;
var4 = var4 * var10 + var9 * (1.0F - var10);
var5 = var5 * var10 + var9 * (1.0F - var10);
var6 = var6 * var10 + var9 * (1.0F - var10);
}
return this.getWorldVec3Pool().getVecFromPool((double)var4, (double)var5, (double)var6);
}
/**
* Returns vector(ish) with R/G/B for fog
*/
public Vec3 getFogColor(float par1) {
float var2 = this.getCelestialAngle(par1);
return this.provider.getFogColor(var2, par1);
}
/**
* Gets the height to which rain/snow will fall. Calculates it if not already stored.
*/
public int getPrecipitationHeight(int par1, int par2) {
return this.getChunkFromBlockCoords(par1, par2).getPrecipitationHeight(par1 & 15, par2 & 15);
}
/**
* Finds the highest block on the x, z coordinate that is solid and returns its y coord. Args x, z
*/
public int getTopSolidOrLiquidBlock(int par1, int par2) {
Chunk var3 = this.getChunkFromBlockCoords(par1, par2);
int var4 = var3.getTopFilledSegment() + 15;
par1 &= 15;
for (par2 &= 15; var4 > 0; --var4) {
int var5 = var3.getBlockID(par1, var4, par2);
if (var5 != 0 && Block.blocksList[var5].blockMaterial.blocksMovement() && Block.blocksList[var5].blockMaterial != Material.leaves) {
return var4 + 1;
}
}
return -1;
}
/**
* How bright are stars in the sky
*/
public float getStarBrightness(float par1) {
float var2 = this.getCelestialAngle(par1);
float var3 = 1.0F - (MathHelper.cos(var2 * (float)Math.PI * 2.0F) * 2.0F + 0.25F);
if (var3 < 0.0F) {
var3 = 0.0F;
}
if (var3 > 1.0F) {
var3 = 1.0F;
}
return var3 * var3 * 0.5F;
}
/**
* Schedules a tick to a block with a delay (Most commonly the tick rate)
*/
public void scheduleBlockUpdate(int par1, int par2, int par3, int par4, int par5) {}
public void scheduleBlockUpdateWithPriority(int par1, int par2, int par3, int par4, int par5, int par6) {}
/**
* Schedules a block update from the saved information in a chunk. Called when the chunk is loaded.
*/
public void scheduleBlockUpdateFromLoad(int par1, int par2, int par3, int par4, int par5, int par6) {}
/**
* Updates (and cleans up) entities and tile entities
*/
public void updateEntities() {
this.theProfiler.startSection("entities");
this.theProfiler.startSection("global");
int var1;
Entity var2;
CrashReport var4;
CrashReportCategory var5;
for (var1 = 0; var1 < this.weatherEffects.size(); ++var1) {
var2 = (Entity)this.weatherEffects.get(var1);
try {
++var2.ticksExisted;
var2.onUpdate();
} catch (Throwable var8) {
var4 = CrashReport.makeCrashReport(var8, "Ticking entity");
var5 = var4.makeCategory("Entity being ticked");
if (var2 == null) {
var5.addCrashSection("Entity", "~~NULL~~");
} else {
var2.addEntityCrashInfo(var5);
}
throw new ReportedException(var4);
}
if (var2.isDead) {
this.weatherEffects.remove(var1--);
}
}
this.theProfiler.endStartSection("remove");
this.loadedEntityList.removeAll(this.unloadedEntityList);
int var3;
int var13;
for (var1 = 0; var1 < this.unloadedEntityList.size(); ++var1) {
var2 = (Entity)this.unloadedEntityList.get(var1);
var3 = var2.chunkCoordX;
var13 = var2.chunkCoordZ;
if (var2.addedToChunk && this.chunkExists(var3, var13)) {
this.getChunkFromChunkCoords(var3, var13).removeEntity(var2);
}
}
for (var1 = 0; var1 < this.unloadedEntityList.size(); ++var1) {
this.onEntityRemoved((Entity)this.unloadedEntityList.get(var1));
}
this.unloadedEntityList.clear();
this.theProfiler.endStartSection("regular");
for (var1 = 0; var1 < this.loadedEntityList.size(); ++var1) {
var2 = (Entity)this.loadedEntityList.get(var1);
if (var2.ridingEntity != null) {
if (!var2.ridingEntity.isDead && var2.ridingEntity.riddenByEntity == var2) {
continue;
}
var2.ridingEntity.riddenByEntity = null;
var2.ridingEntity = null;
}
this.theProfiler.startSection("tick");
if (!var2.isDead) {
try {
this.updateEntity(var2);
} catch (Throwable var7) {
var4 = CrashReport.makeCrashReport(var7, "Ticking entity");
var5 = var4.makeCategory("Entity being ticked");
var2.addEntityCrashInfo(var5);
throw new ReportedException(var4);
}
}
this.theProfiler.endSection();
this.theProfiler.startSection("remove");
if (var2.isDead) {
var3 = var2.chunkCoordX;
var13 = var2.chunkCoordZ;
if (var2.addedToChunk && this.chunkExists(var3, var13)) {
this.getChunkFromChunkCoords(var3, var13).removeEntity(var2);
}
this.loadedEntityList.remove(var1--);
this.onEntityRemoved(var2);
}
this.theProfiler.endSection();
}
this.theProfiler.endStartSection("tileEntities");
this.scanningTileEntities = true;
Iterator var14 = this.loadedTileEntityList.iterator();
while (var14.hasNext()) {
TileEntity var9 = (TileEntity)var14.next();
if (!var9.isInvalid() && var9.hasWorldObj() && this.blockExists(var9.xCoord, var9.yCoord, var9.zCoord)) {
try {
var9.updateEntity();
} catch (Throwable var6) {
var4 = CrashReport.makeCrashReport(var6, "Ticking tile entity");
var5 = var4.makeCategory("Tile entity being ticked");
var9.func_85027_a(var5);
throw new ReportedException(var4);
}
}
if (var9.isInvalid()) {
var14.remove();
if (this.chunkExists(var9.xCoord >> 4, var9.zCoord >> 4)) {
Chunk var11 = this.getChunkFromChunkCoords(var9.xCoord >> 4, var9.zCoord >> 4);
if (var11 != null) {
var11.removeChunkBlockTileEntity(var9.xCoord & 15, var9.yCoord, var9.zCoord & 15);
}
}
}
}
this.scanningTileEntities = false;
if (!this.entityRemoval.isEmpty()) {
this.loadedTileEntityList.removeAll(this.entityRemoval);
this.entityRemoval.clear();
}
this.theProfiler.endStartSection("pendingTileEntities");
if (!this.addedTileEntityList.isEmpty()) {
for (int var10 = 0; var10 < this.addedTileEntityList.size(); ++var10) {
TileEntity var12 = (TileEntity)this.addedTileEntityList.get(var10);
if (!var12.isInvalid()) {
if (!this.loadedTileEntityList.contains(var12)) {
this.loadedTileEntityList.add(var12);
}
if (this.chunkExists(var12.xCoord >> 4, var12.zCoord >> 4)) {
Chunk var15 = this.getChunkFromChunkCoords(var12.xCoord >> 4, var12.zCoord >> 4);
if (var15 != null) {
var15.setChunkBlockTileEntity(var12.xCoord & 15, var12.yCoord, var12.zCoord & 15, var12);
}
}
this.markBlockForUpdate(var12.xCoord, var12.yCoord, var12.zCoord);
}
}
this.addedTileEntityList.clear();
}
this.theProfiler.endSection();
this.theProfiler.endSection();
}
public void addTileEntity(Collection par1Collection) {
if (this.scanningTileEntities) {
this.addedTileEntityList.addAll(par1Collection);
} else {
this.loadedTileEntityList.addAll(par1Collection);
}
}
/**
* Will update the entity in the world if the chunk the entity is in is currently loaded. Args: entity
*/
public void updateEntity(Entity par1Entity) {
this.updateEntityWithOptionalForce(par1Entity, true);
}
/**
* Will update the entity in the world if the chunk the entity is in is currently loaded or its forced to update. Args:
* entity, forceUpdate
*/
public void updateEntityWithOptionalForce(Entity par1Entity, boolean par2) {
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)) {
par1Entity.lastTickPosX = par1Entity.posX;
par1Entity.lastTickPosY = par1Entity.posY;
par1Entity.lastTickPosZ = par1Entity.posZ;
par1Entity.prevRotationYaw = par1Entity.rotationYaw;
par1Entity.prevRotationPitch = par1Entity.rotationPitch;
if (par2 && par1Entity.addedToChunk) {
++par1Entity.ticksExisted;
if (par1Entity.ridingEntity != null) {
par1Entity.updateRidden();
} else {
par1Entity.onUpdate();
}
}
this.theProfiler.startSection("chunkCheck");
if (Double.isNaN(par1Entity.posX) || Double.isInfinite(par1Entity.posX)) {
par1Entity.posX = par1Entity.lastTickPosX;
}
if (Double.isNaN(par1Entity.posY) || Double.isInfinite(par1Entity.posY)) {
par1Entity.posY = par1Entity.lastTickPosY;
}
if (Double.isNaN(par1Entity.posZ) || Double.isInfinite(par1Entity.posZ)) {
par1Entity.posZ = par1Entity.lastTickPosZ;
}
if (Double.isNaN((double)par1Entity.rotationPitch) || Double.isInfinite((double)par1Entity.rotationPitch)) {
par1Entity.rotationPitch = par1Entity.prevRotationPitch;
}
if (Double.isNaN((double)par1Entity.rotationYaw) || Double.isInfinite((double)par1Entity.rotationYaw)) {
par1Entity.rotationYaw = par1Entity.prevRotationYaw;
}
int var6 = MathHelper.floor_double(par1Entity.posX / 16.0D);
int var7 = MathHelper.floor_double(par1Entity.posY / 16.0D);
int var8 = MathHelper.floor_double(par1Entity.posZ / 16.0D);
if (!par1Entity.addedToChunk || par1Entity.chunkCoordX != var6 || par1Entity.chunkCoordY != var7 || par1Entity.chunkCoordZ != var8) {
if (par1Entity.addedToChunk && this.chunkExists(par1Entity.chunkCoordX, par1Entity.chunkCoordZ)) {
this.getChunkFromChunkCoords(par1Entity.chunkCoordX, par1Entity.chunkCoordZ).removeEntityAtIndex(par1Entity, par1Entity.chunkCoordY);
}
if (this.chunkExists(var6, var8)) {
par1Entity.addedToChunk = true;
this.getChunkFromChunkCoords(var6, var8).addEntity(par1Entity);
} else {
par1Entity.addedToChunk = false;
}
}
this.theProfiler.endSection();
if (par2 && par1Entity.addedToChunk && par1Entity.riddenByEntity != null) {
if (!par1Entity.riddenByEntity.isDead && par1Entity.riddenByEntity.ridingEntity == par1Entity) {
this.updateEntity(par1Entity.riddenByEntity);
} else {
par1Entity.riddenByEntity.ridingEntity = null;
par1Entity.riddenByEntity = null;
}
}
}
}
/**
* Returns true if there are no solid, live entities in the specified AxisAlignedBB
*/
public boolean checkNoEntityCollision(AxisAlignedBB par1AxisAlignedBB) {
return this.checkNoEntityCollision(par1AxisAlignedBB, (Entity)null);
}
/**
* Returns true if there are no solid, live entities in the specified AxisAlignedBB, excluding the given entity
*/
public boolean checkNoEntityCollision(AxisAlignedBB par1AxisAlignedBB, Entity par2Entity) {
List var3 = this.getEntitiesWithinAABBExcludingEntity((Entity)null, par1AxisAlignedBB);
for (int var4 = 0; var4 < var3.size(); ++var4) {
Entity var5 = (Entity)var3.get(var4);
if (!var5.isDead && var5.preventEntitySpawning && var5 != par2Entity) {
return false;
}
}
return true;
}
/**
* Returns true if there are any blocks in the region constrained by an AxisAlignedBB
*/
public boolean checkBlockCollision(AxisAlignedBB par1AxisAlignedBB) {
int var2 = MathHelper.floor_double(par1AxisAlignedBB.minX);
int var3 = MathHelper.floor_double(par1AxisAlignedBB.maxX + 1.0D);
int var4 = MathHelper.floor_double(par1AxisAlignedBB.minY);
int var5 = MathHelper.floor_double(par1AxisAlignedBB.maxY + 1.0D);
int var6 = MathHelper.floor_double(par1AxisAlignedBB.minZ);
int var7 = MathHelper.floor_double(par1AxisAlignedBB.maxZ + 1.0D);
if (par1AxisAlignedBB.minX < 0.0D) {
--var2;
}
if (par1AxisAlignedBB.minY < 0.0D) {
--var4;
}
if (par1AxisAlignedBB.minZ < 0.0D) {
--var6;
}
for (int var8 = var2; var8 < var3; ++var8) {
for (int var9 = var4; var9 < var5; ++var9) {
for (int var10 = var6; var10 < var7; ++var10) {
Block var11 = Block.blocksList[this.getBlockId(var8, var9, var10)];
if (var11 != null) {
return true;
}
}
}
}
return false;
}
/**
* Returns if any of the blocks within the aabb are liquids. Args: aabb
*/
public boolean isAnyLiquid(AxisAlignedBB par1AxisAlignedBB) {
int var2 = MathHelper.floor_double(par1AxisAlignedBB.minX);
int var3 = MathHelper.floor_double(par1AxisAlignedBB.maxX + 1.0D);
int var4 = MathHelper.floor_double(par1AxisAlignedBB.minY);
int var5 = MathHelper.floor_double(par1AxisAlignedBB.maxY + 1.0D);
int var6 = MathHelper.floor_double(par1AxisAlignedBB.minZ);
int var7 = MathHelper.floor_double(par1AxisAlignedBB.maxZ + 1.0D);
if (par1AxisAlignedBB.minX < 0.0D) {
--var2;
}
if (par1AxisAlignedBB.minY < 0.0D) {
--var4;
}
if (par1AxisAlignedBB.minZ < 0.0D) {
--var6;
}
for (int var8 = var2; var8 < var3; ++var8) {
for (int var9 = var4; var9 < var5; ++var9) {
for (int var10 = var6; var10 < var7; ++var10) {
Block var11 = Block.blocksList[this.getBlockId(var8, var9, var10)];
if (var11 != null && var11.blockMaterial.isLiquid()) {
return true;
}
}
}
}
return false;
}
/**
* Returns whether or not the given bounding box is on fire or not
*/
public boolean isBoundingBoxBurning(AxisAlignedBB par1AxisAlignedBB) {
int var2 = MathHelper.floor_double(par1AxisAlignedBB.minX);
int var3 = MathHelper.floor_double(par1AxisAlignedBB.maxX + 1.0D);
int var4 = MathHelper.floor_double(par1AxisAlignedBB.minY);
int var5 = MathHelper.floor_double(par1AxisAlignedBB.maxY + 1.0D);
int var6 = MathHelper.floor_double(par1AxisAlignedBB.minZ);
int var7 = MathHelper.floor_double(par1AxisAlignedBB.maxZ + 1.0D);
if (this.checkChunksExist(var2, var4, var6, var3, var5, var7)) {
for (int var8 = var2; var8 < var3; ++var8) {
for (int var9 = var4; var9 < var5; ++var9) {
for (int var10 = var6; var10 < var7; ++var10) {
int var11 = this.getBlockId(var8, var9, var10);
if (var11 == Block.fire.blockID || var11 == Block.lavaMoving.blockID || var11 == Block.lavaStill.blockID) {
return true;
}
}
}
}
}
return false;
}
/**
* handles the acceleration of an object whilst in water. Not sure if it is used elsewhere.
*/
public boolean handleMaterialAcceleration(AxisAlignedBB par1AxisAlignedBB, Material par2Material, Entity par3Entity) {
int var4 = MathHelper.floor_double(par1AxisAlignedBB.minX);
int var5 = MathHelper.floor_double(par1AxisAlignedBB.maxX + 1.0D);
int var6 = MathHelper.floor_double(par1AxisAlignedBB.minY);
int var7 = MathHelper.floor_double(par1AxisAlignedBB.maxY + 1.0D);
int var8 = MathHelper.floor_double(par1AxisAlignedBB.minZ);
int var9 = MathHelper.floor_double(par1AxisAlignedBB.maxZ + 1.0D);
if (!this.checkChunksExist(var4, var6, var8, var5, var7, var9)) {
return false;
} else {
boolean var10 = false;
Vec3 var11 = this.getWorldVec3Pool().getVecFromPool(0.0D, 0.0D, 0.0D);
for (int var12 = var4; var12 < var5; ++var12) {
for (int var13 = var6; var13 < var7; ++var13) {
for (int var14 = var8; var14 < var9; ++var14) {
Block var15 = Block.blocksList[this.getBlockId(var12, var13, var14)];
if (var15 != null && var15.blockMaterial == par2Material) {
double var16 = (double)((float)(var13 + 1) - BlockFluid.getFluidHeightPercent(this.getBlockMetadata(var12, var13, var14)));
if ((double)var7 >= var16) {
var10 = true;
var15.velocityToAddToEntity(this, var12, var13, var14, par3Entity, var11);
}
}
}
}
}
if (var11.lengthVector() > 0.0D && par3Entity.isPushedByWater()) {
var11 = var11.normalize();
double var18 = 0.014D;
par3Entity.motionX += var11.xCoord * var18;
par3Entity.motionY += var11.yCoord * var18;
par3Entity.motionZ += var11.zCoord * var18;
}
return var10;
}
}
/**
* Returns true if the given bounding box contains the given material
*/
public boolean isMaterialInBB(AxisAlignedBB par1AxisAlignedBB, Material par2Material) {
int var3 = MathHelper.floor_double(par1AxisAlignedBB.minX);
int var4 = MathHelper.floor_double(par1AxisAlignedBB.maxX + 1.0D);
int var5 = MathHelper.floor_double(par1AxisAlignedBB.minY);
int var6 = MathHelper.floor_double(par1AxisAlignedBB.maxY + 1.0D);
int var7 = MathHelper.floor_double(par1AxisAlignedBB.minZ);
int var8 = MathHelper.floor_double(par1AxisAlignedBB.maxZ + 1.0D);
for (int var9 = var3; var9 < var4; ++var9) {
for (int var10 = var5; var10 < var6; ++var10) {
for (int var11 = var7; var11 < var8; ++var11) {
Block var12 = Block.blocksList[this.getBlockId(var9, var10, var11)];
if (var12 != null && var12.blockMaterial == par2Material) {
return true;
}
}
}
}
return false;
}
/**
* checks if the given AABB is in the material given. Used while swimming.
*/
public boolean isAABBInMaterial(AxisAlignedBB par1AxisAlignedBB, Material par2Material) {
int var3 = MathHelper.floor_double(par1AxisAlignedBB.minX);
int var4 = MathHelper.floor_double(par1AxisAlignedBB.maxX + 1.0D);
int var5 = MathHelper.floor_double(par1AxisAlignedBB.minY);
int var6 = MathHelper.floor_double(par1AxisAlignedBB.maxY + 1.0D);
int var7 = MathHelper.floor_double(par1AxisAlignedBB.minZ);
int var8 = MathHelper.floor_double(par1AxisAlignedBB.maxZ + 1.0D);
for (int var9 = var3; var9 < var4; ++var9) {
for (int var10 = var5; var10 < var6; ++var10) {
for (int var11 = var7; var11 < var8; ++var11) {
Block var12 = Block.blocksList[this.getBlockId(var9, var10, var11)];
if (var12 != null && var12.blockMaterial == par2Material) {
int var13 = this.getBlockMetadata(var9, var10, var11);
double var14 = (double)(var10 + 1);
if (var13 < 8) {
var14 = (double)(var10 + 1) - (double)var13 / 8.0D;
}
if (var14 >= par1AxisAlignedBB.minY) {
return true;
}
}
}
}
}
return false;
}
/**
* Creates an explosion. Args: entity, x, y, z, strength
*/
public Explosion createExplosion(Entity par1Entity, double par2, double par4, double par6, float par8, boolean par9) {
return this.newExplosion(par1Entity, par2, par4, par6, par8, false, par9);
}
/**
* returns a new explosion. Does initiation (at time of writing Explosion is not finished)
*/
public Explosion newExplosion(Entity par1Entity, double par2, double par4, double par6, float par8, boolean par9, boolean par10) {
Explosion var11 = new Explosion(this, par1Entity, par2, par4, par6, par8);
var11.isFlaming = par9;
var11.isSmoking = par10;
var11.doExplosionA();
var11.doExplosionB(true);
return var11;
}
/**
* Gets the percentage of real blocks within within a bounding box, along a specified vector.
*/
public float getBlockDensity(Vec3 par1Vec3, AxisAlignedBB par2AxisAlignedBB) {
double var3 = 1.0D / ((par2AxisAlignedBB.maxX - par2AxisAlignedBB.minX) * 2.0D + 1.0D);
double var5 = 1.0D / ((par2AxisAlignedBB.maxY - par2AxisAlignedBB.minY) * 2.0D + 1.0D);
double var7 = 1.0D / ((par2AxisAlignedBB.maxZ - par2AxisAlignedBB.minZ) * 2.0D + 1.0D);
int var9 = 0;
int var10 = 0;
for (float var11 = 0.0F; var11 <= 1.0F; var11 = (float)((double)var11 + var3)) {
for (float var12 = 0.0F; var12 <= 1.0F; var12 = (float)((double)var12 + var5)) {
for (float var13 = 0.0F; var13 <= 1.0F; var13 = (float)((double)var13 + var7)) {
double var14 = par2AxisAlignedBB.minX + (par2AxisAlignedBB.maxX - par2AxisAlignedBB.minX) * (double)var11;
double var16 = par2AxisAlignedBB.minY + (par2AxisAlignedBB.maxY - par2AxisAlignedBB.minY) * (double)var12;
double var18 = par2AxisAlignedBB.minZ + (par2AxisAlignedBB.maxZ - par2AxisAlignedBB.minZ) * (double)var13;
if (this.clip(this.getWorldVec3Pool().getVecFromPool(var14, var16, var18), par1Vec3) == null) {
++var9;
}
++var10;
}
}
}
return (float)var9 / (float)var10;
}
/**
* If the block in the given direction of the given coordinate is fire, extinguish it. Args: Player, X,Y,Z,
* blockDirection
*/
public boolean extinguishFire(EntityPlayer par1EntityPlayer, int par2, int par3, int par4, int par5) {
if (par5 == 0) {
--par3;
}
if (par5 == 1) {
++par3;
}
if (par5 == 2) {
--par4;
}
if (par5 == 3) {
++par4;
}
if (par5 == 4) {
--par2;
}
if (par5 == 5) {
++par2;
}
if (this.getBlockId(par2, par3, par4) == Block.fire.blockID) {
this.playAuxSFXAtEntity(par1EntityPlayer, 1004, par2, par3, par4, 0);
this.setBlockToAir(par2, par3, par4);
return true;
} else {
return false;
}
}
/**
* This string is 'All: (number of loaded entities)' Viewable by press ing F3
*/
public String getDebugLoadedEntities() {
return "All: " + this.loadedEntityList.size();
}
/**
* Returns the name of the current chunk provider, by calling chunkprovider.makeString()
*/
public String getProviderName() {
return this.chunkProvider.makeString();
}
/**
* Returns the TileEntity associated with a given block in X,Y,Z coordinates, or null if no TileEntity exists
*/
public TileEntity getBlockTileEntity(int par1, int par2, int par3) {
if (par2 >= 0 && par2 < 256) {
TileEntity var4 = null;
int var5;
TileEntity var6;
if (this.scanningTileEntities) {
for (var5 = 0; var5 < this.addedTileEntityList.size(); ++var5) {
var6 = (TileEntity)this.addedTileEntityList.get(var5);
if (!var6.isInvalid() && var6.xCoord == par1 && var6.yCoord == par2 && var6.zCoord == par3) {
var4 = var6;
break;
}
}
}
if (var4 == null) {
Chunk var7 = this.getChunkFromChunkCoords(par1 >> 4, par3 >> 4);
if (var7 != null) {
var4 = var7.getChunkBlockTileEntity(par1 & 15, par2, par3 & 15);
}
}
if (var4 == null) {
for (var5 = 0; var5 < this.addedTileEntityList.size(); ++var5) {
var6 = (TileEntity)this.addedTileEntityList.get(var5);
if (!var6.isInvalid() && var6.xCoord == par1 && var6.yCoord == par2 && var6.zCoord == par3) {
var4 = var6;
break;
}
}
}
return var4;
} else {
return null;
}
}
/**
* Sets the TileEntity for a given block in X, Y, Z coordinates
*/
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;
Iterator var5 = this.addedTileEntityList.iterator();
while (var5.hasNext()) {
TileEntity var6 = (TileEntity)var5.next();
if (var6.xCoord == par1 && var6.yCoord == par2 && var6.zCoord == par3) {
var6.invalidate();
var5.remove();
}
}
this.addedTileEntityList.add(par4TileEntity);
} else {
this.loadedTileEntityList.add(par4TileEntity);
Chunk var7 = this.getChunkFromChunkCoords(par1 >> 4, par3 >> 4);
if (var7 != null) {
var7.setChunkBlockTileEntity(par1 & 15, par2, par3 & 15, par4TileEntity);
}
}
}
}
/**
* Removes the TileEntity for a given block in X,Y,Z coordinates
*/
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);
}
}
}
/**
* adds tile entity to despawn list (renamed from markEntityForDespawn)
*/
public void markTileEntityForDespawn(TileEntity par1TileEntity) {
this.entityRemoval.add(par1TileEntity);
}
/**
* Returns true if the block at the specified coordinates is an opaque cube. Args: x, y, z
*/
public boolean isBlockOpaqueCube(int par1, int par2, int par3) {
Block var4 = Block.blocksList[this.getBlockId(par1, par2, par3)];
return var4 == null ? false : var4.isOpaqueCube();
}
/**
* Indicate if a material is a normal solid opaque cube.
*/
public boolean isBlockNormalCube(int par1, int par2, int par3) {
return Block.isNormalCube(this.getBlockId(par1, par2, par3));
}
public boolean isBlockFullCube(int par1, int par2, int par3) {
int var4 = this.getBlockId(par1, par2, par3);
if (var4 != 0 && Block.blocksList[var4] != null) {
AxisAlignedBB var5 = Block.blocksList[var4].getCollisionBoundingBoxFromPool(this, par1, par2, par3);
return var5 != null && var5.getAverageEdgeLength() >= 1.0D;
} else {
return false;
}
}
/**
* Returns true if the block at the given coordinate has a solid (buildable) top surface.
*/
public boolean doesBlockHaveSolidTopSurface(int par1, int par2, int par3) {
Block var4 = Block.blocksList[this.getBlockId(par1, par2, par3)];
return this.isBlockTopFacingSurfaceSolid(var4, this.getBlockMetadata(par1, par2, par3));
}
/**
* Performs check to see if the block is a normal, solid block, or if the metadata of the block indicates that its
* facing puts its solid side upwards. (inverted stairs, for example)
*/
public boolean isBlockTopFacingSurfaceSolid(Block par1Block, int par2) {
return par1Block == null ? false : (par1Block.blockMaterial.isOpaque() && par1Block.renderAsNormalBlock() ? true : (par1Block instanceof BlockStairs ? (par2 & 4) == 4 : (par1Block instanceof BlockHalfSlab ? (par2 & 8) == 8 : (par1Block instanceof BlockHopper ? true : (par1Block instanceof BlockSnow ? (par2 & 7) == 7 : false)))));
}
/**
* Checks if the block is a solid, normal cube. If the chunk does not exist, or is not loaded, it returns the boolean
* parameter.
*/
public boolean isBlockNormalCubeDefault(int par1, int par2, int par3, boolean par4) {
if (par1 >= -30000000 && par3 >= -30000000 && par1 < 30000000 && par3 < 30000000) {
Chunk var5 = this.chunkProvider.provideChunk(par1 >> 4, par3 >> 4);
if (var5 != null && !var5.isEmpty()) {
Block var6 = Block.blocksList[this.getBlockId(par1, par2, par3)];
return var6 == null ? false : var6.blockMaterial.isOpaque() && var6.renderAsNormalBlock();
} else {
return par4;
}
} else {
return par4;
}
}
/**
* Called on construction of the World class to setup the initial skylight values
*/
public void calculateInitialSkylight() {
int var1 = this.calculateSkylightSubtracted(1.0F);
if (var1 != this.skylightSubtracted) {
this.skylightSubtracted = var1;
}
}
/**
* Set which types of mobs are allowed to spawn (peaceful vs hostile).
*/
public void setAllowedSpawnTypes(boolean par1, boolean par2) {
this.spawnHostileMobs = par1;
this.spawnPeacefulMobs = par2;
}
/**
* Runs a single tick for the world
*/
public void tick() {
this.updateWeather();
}
/**
* Called from World constructor to set rainingStrength and thunderingStrength
*/
private void calculateInitialWeather() {
if (this.worldInfo.isRaining()) {
this.rainingStrength = 1.0F;
if (this.worldInfo.isThundering()) {
this.thunderingStrength = 1.0F;
}
}
}
/**
* Updates all weather states.
*/
protected void updateWeather() {
if (!this.provider.hasNoSky) {
int var1 = this.worldInfo.getThunderTime();
if (var1 <= 0) {
if (this.worldInfo.isThundering()) {
this.worldInfo.setThunderTime(this.rand.nextInt(12000) + 3600);
} else {
this.worldInfo.setThunderTime(this.rand.nextInt(168000) + 12000);
}
} else {
--var1;
this.worldInfo.setThunderTime(var1);
if (var1 <= 0) {
this.worldInfo.setThundering(!this.worldInfo.isThundering());
}
}
int var2 = this.worldInfo.getRainTime();
if (var2 <= 0) {
if (this.worldInfo.isRaining()) {
this.worldInfo.setRainTime(this.rand.nextInt(12000) + 12000);
} else {
this.worldInfo.setRainTime(this.rand.nextInt(168000) + 12000);
}
} else {
--var2;
this.worldInfo.setRainTime(var2);
if (var2 <= 0) {
this.worldInfo.setRaining(!this.worldInfo.isRaining());
}
}
this.prevRainingStrength = this.rainingStrength;
if (this.worldInfo.isRaining()) {
this.rainingStrength = (float)((double)this.rainingStrength + 0.01D);
} else {
this.rainingStrength = (float)((double)this.rainingStrength - 0.01D);
}
if (this.rainingStrength < 0.0F) {
this.rainingStrength = 0.0F;
}
if (this.rainingStrength > 1.0F) {
this.rainingStrength = 1.0F;
}
this.prevThunderingStrength = this.thunderingStrength;
if (this.worldInfo.isThundering()) {
this.thunderingStrength = (float)((double)this.thunderingStrength + 0.01D);
} else {
this.thunderingStrength = (float)((double)this.thunderingStrength - 0.01D);
}
if (this.thunderingStrength < 0.0F) {
this.thunderingStrength = 0.0F;
}
if (this.thunderingStrength > 1.0F) {
this.thunderingStrength = 1.0F;
}
}
}
public void toggleRain() {
this.worldInfo.setRainTime(1);
}
protected void setActivePlayerChunksAndCheckLight() {
this.activeChunkSet.clear();
this.theProfiler.startSection("buildList");
int var1;
EntityPlayer var2;
int var3;
int var4;
for (var1 = 0; var1 < this.playerEntities.size(); ++var1) {
var2 = (EntityPlayer)this.playerEntities.get(var1);
var3 = MathHelper.floor_double(var2.posX / 16.0D);
var4 = MathHelper.floor_double(var2.posZ / 16.0D);
byte var5 = 7;
for (int var6 = -var5; var6 <= var5; ++var6) {
for (int var7 = -var5; var7 <= var5; ++var7) {
this.activeChunkSet.add(new ChunkCoordIntPair(var6 + var3, var7 + var4));
}
}
}
this.theProfiler.endSection();
if (this.ambientTickCountdown > 0) {
--this.ambientTickCountdown;
}
this.theProfiler.startSection("playerCheckLight");
// Spout Start
if (!this.playerEntities.isEmpty() && Configuration.isClientLight()) {
// Spout End
var1 = this.rand.nextInt(this.playerEntities.size());
var2 = (EntityPlayer)this.playerEntities.get(var1);
var3 = MathHelper.floor_double(var2.posX) + this.rand.nextInt(11) - 5;
var4 = MathHelper.floor_double(var2.posY) + this.rand.nextInt(11) - 5;
int var8 = MathHelper.floor_double(var2.posZ) + this.rand.nextInt(11) - 5;
this.updateAllLightTypes(var3, var4, var8);
}
this.theProfiler.endSection();
}
protected void moodSoundAndLightCheck(int par1, int par2, Chunk par3Chunk) {
this.theProfiler.endStartSection("moodSound");
if (this.ambientTickCountdown == 0 && !this.isRemote) {
this.updateLCG = this.updateLCG * 3 + 1013904223;
int var4 = this.updateLCG >> 2;
int var5 = var4 & 15;
int var6 = var4 >> 8 & 15;
int var7 = var4 >> 16 & 127;
int var8 = par3Chunk.getBlockID(var5, var7, var6);
var5 += par1;
var6 += par2;
if (var8 == 0 && this.getFullBlockLightValue(var5, var7, var6) <= this.rand.nextInt(8) && this.getSavedLightValue(EnumSkyBlock.Sky, var5, var7, var6) <= 0) {
EntityPlayer var9 = this.getClosestPlayer((double)var5 + 0.5D, (double)var7 + 0.5D, (double)var6 + 0.5D, 8.0D);
if (var9 != null && var9.getDistanceSq((double)var5 + 0.5D, (double)var7 + 0.5D, (double)var6 + 0.5D) > 4.0D) {
this.playSoundEffect((double)var5 + 0.5D, (double)var7 + 0.5D, (double)var6 + 0.5D, "ambient.cave.cave", 0.7F, 0.8F + this.rand.nextFloat() * 0.2F);
this.ambientTickCountdown = this.rand.nextInt(12000) + 6000;
}
}
}
this.theProfiler.endStartSection("checkLight");
par3Chunk.enqueueRelightChecks();
}
/**
* plays random cave ambient sounds and runs updateTick on random blocks within each chunk in the vacinity of a player
*/
protected void tickBlocksAndAmbiance() {
this.setActivePlayerChunksAndCheckLight();
}
/**
* checks to see if a given block is both water and is cold enough to freeze
*/
public boolean isBlockFreezable(int par1, int par2, int par3) {
return this.canBlockFreeze(par1, par2, par3, false);
}
/**
* checks to see if a given block is both water and has at least one immediately adjacent non-water block
*/
public boolean isBlockFreezableNaturally(int par1, int par2, int par3) {
return this.canBlockFreeze(par1, par2, par3, true);
}
/**
* checks to see if a given block is both water, and cold enough to freeze - if the par4 boolean is set, this will only
* return true if there is a non-water block immediately adjacent to the specified block
*/
public boolean canBlockFreeze(int par1, int par2, int par3, boolean par4) {
BiomeGenBase var5 = this.getBiomeGenForCoords(par1, par3);
float var6 = var5.getFloatTemperature();
if (var6 > 0.15F) {
return false;
} else {
if (par2 >= 0 && par2 < 256 && this.getSavedLightValue(EnumSkyBlock.Block, par1, par2, par3) < 10) {
int var7 = this.getBlockId(par1, par2, par3);
if ((var7 == Block.waterStill.blockID || var7 == Block.waterMoving.blockID) && this.getBlockMetadata(par1, par2, par3) == 0) {
if (!par4) {
return true;
}
boolean var8 = true;
if (var8 && this.getBlockMaterial(par1 - 1, par2, par3) != Material.water) {
var8 = false;
}
if (var8 && this.getBlockMaterial(par1 + 1, par2, par3) != Material.water) {
var8 = false;
}
if (var8 && this.getBlockMaterial(par1, par2, par3 - 1) != Material.water) {
var8 = false;
}
if (var8 && this.getBlockMaterial(par1, par2, par3 + 1) != Material.water) {
var8 = false;
}
if (!var8) {
return true;
}
}
}
return false;
}
}
/**
* Tests whether or not snow can be placed at a given location
*/
public boolean canSnowAt(int par1, int par2, int par3) {
BiomeGenBase var4 = this.getBiomeGenForCoords(par1, par3);
float var5 = var4.getFloatTemperature();
if (var5 > 0.15F) {
return false;
} else {
if (par2 >= 0 && par2 < 256 && this.getSavedLightValue(EnumSkyBlock.Block, par1, par2, par3) < 10) {
int var6 = this.getBlockId(par1, par2 - 1, par3);
int var7 = this.getBlockId(par1, par2, par3);
if (var7 == 0 && Block.snow.canPlaceBlockAt(this, par1, par2, par3) && var6 != 0 && var6 != Block.ice.blockID && Block.blocksList[var6].blockMaterial.blocksMovement()) {
return true;
}
}
return false;
}
}
public void updateAllLightTypes(int par1, int par2, int par3) {
if (!this.provider.hasNoSky) {
this.updateLightByType(EnumSkyBlock.Sky, par1, par2, par3);
}
this.updateLightByType(EnumSkyBlock.Block, par1, par2, par3);
}
private int computeLightValue(int par1, int par2, int par3, EnumSkyBlock par4EnumSkyBlock) {
if (par4EnumSkyBlock == EnumSkyBlock.Sky && this.canBlockSeeTheSky(par1, par2, par3)) {
return 15;
} else {
int var5 = this.getBlockId(par1, par2, par3);
int var6 = par4EnumSkyBlock == EnumSkyBlock.Sky ? 0 : Block.lightValue[var5];
int var7 = Block.lightOpacity[var5];
if (var7 >= 15 && Block.lightValue[var5] > 0) {
var7 = 1;
}
if (var7 < 1) {
var7 = 1;
}
if (var7 >= 15) {
return 0;
} else if (var6 >= 14) {
return var6;
} else {
for (int var8 = 0; var8 < 6; ++var8) {
int var9 = par1 + Facing.offsetsXForSide[var8];
int var10 = par2 + Facing.offsetsYForSide[var8];
int var11 = par3 + Facing.offsetsZForSide[var8];
int var12 = this.getSavedLightValue(par4EnumSkyBlock, var9, var10, var11) - var7;
if (var12 > var6) {
var6 = var12;
}
if (var6 >= 14) {
return var6;
}
}
return var6;
}
}
}
// Spout Start - Lighting Calculations revert to 1.4.7 setup to make Spout CustomBlock Lighting work.
public int getBlockLightOpacity(int par1, int par2, int par3) {
return par1 >= -30000000 && par3 >= -30000000 && par1 < 30000000 && par3 < 30000000 ? (par2 < 0 ? 0 : (par2 >= 256 ? 0 : this.getChunkFromChunkCoords(par1 >> 4, par3 >> 4).getBlockLightOpacity(par1 & 15, par2, par3 & 15))) : 0;
}
private int computeSkyLightValue(int par1, int par2, int par3, int par4, int par5, int par6) {
int var7 = 0;
if (this.canBlockSeeTheSky(par2, par3, par4)) {
var7 = 15;
} else {
if (par6 == 0) {
par6 = 1;
}
int var8 = this.getSavedLightValue(EnumSkyBlock.Sky, par2 - 1, par3, par4) - par6;
int var9 = this.getSavedLightValue(EnumSkyBlock.Sky, par2 + 1, par3, par4) - par6;
int var10 = this.getSavedLightValue(EnumSkyBlock.Sky, par2, par3 - 1, par4) - par6;
int var11 = this.getSavedLightValue(EnumSkyBlock.Sky, par2, par3 + 1, par4) - par6;
int var12 = this.getSavedLightValue(EnumSkyBlock.Sky, par2, par3, par4 - 1) - par6;
int var13 = this.getSavedLightValue(EnumSkyBlock.Sky, par2, par3, par4 + 1) - par6;
if (var8 > var7) {
var7 = var8;
}
if (var9 > var7) {
var7 = var9;
}
if (var10 > var7) {
var7 = var10;
}
if (var11 > var7) {
var7 = var11;
}
if (var12 > var7) {
var7 = var12;
}
if (var13 > var7) {
var7 = var13;
}
}
return var7;
}
private int computeBlockLightValue(int par1, int par2, int par3, int par4, int par5, int par6) {
// Spout Start
int light = Block.lightValue[par5];
// Fix for generation-time accessing
short customId = 0;
if (SpoutClient.getInstance().getRawWorld() != null) {
SpoutcraftChunk chunk = Spoutcraft.getChunkAt(SpoutClient.getInstance().getRawWorld(), par2, par3, par4);
customId = chunk.getCustomBlockId(par2, par3, par4);
}
if (customId > 0) {
CustomBlock block = MaterialData.getCustomBlock(customId);
if (block != null) {
light = block.getLightLevel();
}
}
int var7 = light;
// Spout End
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;
int var11 = this.getSavedLightValue(EnumSkyBlock.Block, par2, par3 + 1, par4) - par6;
int var12 = this.getSavedLightValue(EnumSkyBlock.Block, par2, par3, par4 - 1) - par6;
int var13 = this.getSavedLightValue(EnumSkyBlock.Block, par2, par3, par4 + 1) - par6;
if (var8 > var7) {
var7 = var8;
}
if (var9 > var7) {
var7 = var9;
}
if (var10 > var7) {
var7 = var10;
}
if (var11 > var7) {
var7 = var11;
}
if (var12 > var7) {
var7 = var12;
}
if (var13 > var7) {
var7 = var13;
}
return var7;
}
public void updateLightByType(EnumSkyBlock par1EnumSkyBlock, int par2, int par3, int par4) {
// Spout Start
this.updateLightByType(this.lightUpdateBlockList, par1EnumSkyBlock, par2, par3, par4);
}
public void updateLightByType(int[] lightUpdateBlockList, EnumSkyBlock par1EnumSkyBlock, int par2, int par3, int par4) {
// Spout End
if (this.doChunksNearChunkExist(par2, par3, par4, 17)) {
int var5 = 0;
int var6 = 0;
this.theProfiler.startSection("getBrightness");
int var7 = this.getSavedLightValue(par1EnumSkyBlock, par2, par3, par4);
boolean var8 = false;
int var9 = this.getBlockId(par2, par3, par4);
int var10 = this.getBlockLightOpacity(par2, par3, par4);
if (var10 == 0) {
var10 = 1;
}
boolean var11 = false;
int var24;
if (par1EnumSkyBlock == EnumSkyBlock.Sky) {
var24 = this.computeSkyLightValue(var7, par2, par3, par4, var9, var10);
} else {
var24 = this.computeBlockLightValue(var7, par2, par3, par4, var9, var10);
}
int var12;
int var13;
int var14;
int var15;
int var17;
int var16;
int var19;
int var18;
if (var24 > var7) {
// Spout Start
lightUpdateBlockList[var6++] = 133152;
// Spout End
} else if (var24 < var7) {
if (par1EnumSkyBlock != EnumSkyBlock.Block) {
;
}
// Spout Start
lightUpdateBlockList[var6++] = 133152 + (var7 << 18);
// Spout End
while (var5 < var6) {
// Spout Start
var9 = lightUpdateBlockList[var5++];
// Spout End
var10 = (var9 & 63) - 32 + par2;
var24 = (var9 >> 6 & 63) - 32 + par3;
var12 = (var9 >> 12 & 63) - 32 + par4;
var13 = var9 >> 18 & 15;
var14 = this.getSavedLightValue(par1EnumSkyBlock, var10, var24, var12);
if (var14 == var13) {
this.setLightValue(par1EnumSkyBlock, var10, var24, var12, 0);
if (var13 > 0) {
var15 = var10 - par2;
var16 = var24 - par3;
var17 = var12 - par4;
if (var15 < 0) {
var15 = -var15;
}
if (var16 < 0) {
var16 = -var16;
}
if (var17 < 0) {
var17 = -var17;
}
if (var15 + var16 + var17 < 17) {
for (var18 = 0; var18 < 6; ++var18) {
var19 = var18 % 2 * 2 - 1;
int var20 = var10 + var18 / 2 % 3 / 2 * var19;
int var21 = var24 + (var18 / 2 + 1) % 3 / 2 * var19;
int var22 = var12 + (var18 / 2 + 2) % 3 / 2 * var19;
var14 = this.getSavedLightValue(par1EnumSkyBlock, var20, var21, var22);
int var23 = Block.lightOpacity[this.getBlockId(var20, var21, var22)];
if (var23 == 0) {
var23 = 1;
}
// Spout Start
if (var14 == var13 - var23 && var6 < lightUpdateBlockList.length) {
lightUpdateBlockList[var6++] = var20 - par2 + 32 + (var21 - par3 + 32 << 6) + (var22 - par4 + 32 << 12) + (var13 - var23 << 18);
// Spout End
}
}
}
}
}
}
var5 = 0;
}
this.theProfiler.endSection();
this.theProfiler.startSection("checkedPosition < toCheckCount");
while (var5 < var6) {
// Spout Start
var9 = lightUpdateBlockList[var5++];
// Spout End
var10 = (var9 & 63) - 32 + par2;
var24 = (var9 >> 6 & 63) - 32 + par3;
var12 = (var9 >> 12 & 63) - 32 + par4;
var13 = this.getSavedLightValue(par1EnumSkyBlock, var10, var24, var12);
var14 = this.getBlockId(var10, var24, var12);
var15 = Block.lightOpacity[var14];
if (var15 == 0) {
var15 = 1;
}
boolean var25 = false;
if (par1EnumSkyBlock == EnumSkyBlock.Sky) {
var16 = this.computeSkyLightValue(var13, var10, var24, var12, var14, var15);
} else {
var16 = this.computeBlockLightValue(var13, var10, var24, var12, var14, var15);
}
if (var16 != var13) {
this.setLightValue(par1EnumSkyBlock, var10, var24, var12, var16);
if (var16 > var13) {
var17 = var10 - par2;
var18 = var24 - par3;
var19 = var12 - par4;
if (var17 < 0) {
var17 = -var17;
}
if (var18 < 0) {
var18 = -var18;
}
if (var19 < 0) {
var19 = -var19;
}
// Spout Start
if (var17 + var18 + var19 < 17 && var6 < lightUpdateBlockList.length - 6) {
if (this.getSavedLightValue(par1EnumSkyBlock, var10 - 1, var24, var12) < var16) {
lightUpdateBlockList[var6++] = var10 - 1 - par2 + 32 + (var24 - par3 + 32 << 6) + (var12 - par4 + 32 << 12);
}
if (this.getSavedLightValue(par1EnumSkyBlock, var10 + 1, var24, var12) < var16) {
lightUpdateBlockList[var6++] = var10 + 1 - par2 + 32 + (var24 - par3 + 32 << 6) + (var12 - par4 + 32 << 12);
}
if (this.getSavedLightValue(par1EnumSkyBlock, var10, var24 - 1, var12) < var16) {
lightUpdateBlockList[var6++] = var10 - par2 + 32 + (var24 - 1 - par3 + 32 << 6) + (var12 - par4 + 32 << 12);
}
if (this.getSavedLightValue(par1EnumSkyBlock, var10, var24 + 1, var12) < var16) {
lightUpdateBlockList[var6++] = var10 - par2 + 32 + (var24 + 1 - par3 + 32 << 6) + (var12 - par4 + 32 << 12);
}
if (this.getSavedLightValue(par1EnumSkyBlock, var10, var24, var12 - 1) < var16) {
lightUpdateBlockList[var6++] = var10 - par2 + 32 + (var24 - par3 + 32 << 6) + (var12 - 1 - par4 + 32 << 12);
}
if (this.getSavedLightValue(par1EnumSkyBlock, var10, var24, var12 + 1) < var16) {
lightUpdateBlockList[var6++] = var10 - par2 + 32 + (var24 - par3 + 32 << 6) + (var12 + 1 - par4 + 32 << 12);
}
}
// Spout End
}
}
}
this.theProfiler.endSection();
}
}
// Spout End - Lighting Calculations revert to 1.4.7 setup to make Spout CustomBlock Lighting work.
/**
* Runs through the list of updates to run and ticks them
*/
public boolean tickUpdates(boolean par1) {
return false;
}
public List getPendingBlockUpdates(Chunk par1Chunk, boolean par2) {
return null;
}
/**
* Will get all entities within the specified AABB excluding the one passed into it. Args: entityToExclude, aabb
*/
public List getEntitiesWithinAABBExcludingEntity(Entity par1Entity, AxisAlignedBB par2AxisAlignedBB) {
return this.getEntitiesWithinAABBExcludingEntity(par1Entity, par2AxisAlignedBB, (IEntitySelector)null);
}
public List getEntitiesWithinAABBExcludingEntity(Entity par1Entity, AxisAlignedBB par2AxisAlignedBB, IEntitySelector par3IEntitySelector) {
ArrayList var4 = new ArrayList();
int var5 = MathHelper.floor_double((par2AxisAlignedBB.minX - 2.0D) / 16.0D);
int var6 = MathHelper.floor_double((par2AxisAlignedBB.maxX + 2.0D) / 16.0D);
int var7 = MathHelper.floor_double((par2AxisAlignedBB.minZ - 2.0D) / 16.0D);
int var8 = MathHelper.floor_double((par2AxisAlignedBB.maxZ + 2.0D) / 16.0D);
for (int var9 = var5; var9 <= var6; ++var9) {
for (int var10 = var7; var10 <= var8; ++var10) {
if (this.chunkExists(var9, var10)) {
this.getChunkFromChunkCoords(var9, var10).getEntitiesWithinAABBForEntity(par1Entity, par2AxisAlignedBB, var4, par3IEntitySelector);
}
}
}
return var4;
}
/**
* Returns all entities of the specified class type which intersect with the AABB. Args: entityClass, aabb
*/
public List getEntitiesWithinAABB(Class par1Class, AxisAlignedBB par2AxisAlignedBB) {
return this.selectEntitiesWithinAABB(par1Class, par2AxisAlignedBB, (IEntitySelector)null);
}
public List selectEntitiesWithinAABB(Class par1Class, AxisAlignedBB par2AxisAlignedBB, IEntitySelector par3IEntitySelector) {
int var4 = MathHelper.floor_double((par2AxisAlignedBB.minX - 2.0D) / 16.0D);
int var5 = MathHelper.floor_double((par2AxisAlignedBB.maxX + 2.0D) / 16.0D);
int var6 = MathHelper.floor_double((par2AxisAlignedBB.minZ - 2.0D) / 16.0D);
int var7 = MathHelper.floor_double((par2AxisAlignedBB.maxZ + 2.0D) / 16.0D);
ArrayList var8 = new ArrayList();
for (int var9 = var4; var9 <= var5; ++var9) {
for (int var10 = var6; var10 <= var7; ++var10) {
if (this.chunkExists(var9, var10)) {
this.getChunkFromChunkCoords(var9, var10).getEntitiesOfTypeWithinAAAB(par1Class, par2AxisAlignedBB, var8, par3IEntitySelector);
}
}
}
return var8;
}
public Entity findNearestEntityWithinAABB(Class par1Class, AxisAlignedBB par2AxisAlignedBB, Entity par3Entity) {
List var4 = this.getEntitiesWithinAABB(par1Class, par2AxisAlignedBB);
Entity var5 = null;
double var6 = Double.MAX_VALUE;
for (int var8 = 0; var8 < var4.size(); ++var8) {
Entity var9 = (Entity)var4.get(var8);
if (var9 != par3Entity) {
double var10 = par3Entity.getDistanceSqToEntity(var9);
if (var10 <= var6) {
var5 = var9;
var6 = var10;
}
}
}
return var5;
}
/**
* Returns the Entity with the given ID, or null if it doesn't exist in this World.
*/
public abstract Entity getEntityByID(int var1);
/**
* Accessor for world Loaded Entity List
*/
public List getLoadedEntityList() {
return this.loadedEntityList;
}
/**
* Args: X, Y, Z, tile entity Marks the chunk the tile entity is in as modified. This is essential as chunks that are
* not marked as modified may be rolled back when exiting the game.
*/
public void markTileEntityChunkModified(int par1, int par2, int par3, TileEntity par4TileEntity) {
if (this.blockExists(par1, par2, par3)) {
this.getChunkFromBlockCoords(par1, par3).setChunkModified();
}
}
/**
* Counts how many entities of an entity class exist in the world. Args: entityClass
*/
public int countEntities(Class par1Class) {
int var2 = 0;
for (int var3 = 0; var3 < this.loadedEntityList.size(); ++var3) {
Entity var4 = (Entity)this.loadedEntityList.get(var3);
if ((!(var4 instanceof EntityLiving) || !((EntityLiving)var4).isNoDespawnRequired()) && par1Class.isAssignableFrom(var4.getClass())) {
++var2;
}
}
return var2;
}
/**
* adds entities to the loaded entities list, and loads thier skins.
*/
public void addLoadedEntities(List par1List) {
this.loadedEntityList.addAll(par1List);
for (int var2 = 0; var2 < par1List.size(); ++var2) {
this.onEntityAdded((Entity)par1List.get(var2));
}
}
/**
* Adds a list of entities to be unloaded on the next pass of World.updateEntities()
*/
public void unloadEntities(List par1List) {
this.unloadedEntityList.addAll(par1List);
}
/**
* Returns true if the given Entity can be placed on the given side of the given block position.
*/
public boolean canPlaceEntityOnSide(int par1, int par2, int par3, int par4, boolean par5, int par6, Entity par7Entity, ItemStack par8ItemStack) {
int var9 = this.getBlockId(par2, par3, par4);
Block var10 = Block.blocksList[var9];
Block var11 = Block.blocksList[par1];
AxisAlignedBB var12 = var11.getCollisionBoundingBoxFromPool(this, par2, par3, par4);
if (par5) {
var12 = null;
}
if (var12 != null && !this.checkNoEntityCollision(var12, par7Entity)) {
return false;
} else {
if (var10 != null && (var10 == Block.waterMoving || var10 == Block.waterStill || var10 == Block.lavaMoving || var10 == Block.lavaStill || var10 == Block.fire || var10.blockMaterial.isReplaceable())) {
var10 = null;
}
return var10 != null && var10.blockMaterial == Material.circuits && var11 == Block.anvil ? true : par1 > 0 && var10 == null && var11.canPlaceBlockOnSide(this, par2, par3, par4, par6, par8ItemStack);
}
}
public PathEntity getPathEntityToEntity(Entity par1Entity, Entity par2Entity, float par3, boolean par4, boolean par5, boolean par6, boolean par7) {
this.theProfiler.startSection("pathfind");
int var8 = MathHelper.floor_double(par1Entity.posX);
int var9 = MathHelper.floor_double(par1Entity.posY + 1.0D);
int var10 = MathHelper.floor_double(par1Entity.posZ);
int var11 = (int)(par3 + 16.0F);
int var12 = var8 - var11;
int var13 = var9 - var11;
int var14 = var10 - var11;
int var15 = var8 + var11;
int var16 = var9 + var11;
int var17 = var10 + var11;
ChunkCache var18 = new ChunkCache(this, var12, var13, var14, var15, var16, var17, 0);
PathEntity var19 = (new PathFinder(var18, par4, par5, par6, par7)).createEntityPathTo(par1Entity, par2Entity, par3);
this.theProfiler.endSection();
return var19;
}
public PathEntity getEntityPathToXYZ(Entity par1Entity, int par2, int par3, int par4, float par5, boolean par6, boolean par7, boolean par8, boolean par9) {
this.theProfiler.startSection("pathfind");
int var10 = MathHelper.floor_double(par1Entity.posX);
int var11 = MathHelper.floor_double(par1Entity.posY);
int var12 = MathHelper.floor_double(par1Entity.posZ);
int var13 = (int)(par5 + 8.0F);
int var14 = var10 - var13;
int var15 = var11 - var13;
int var16 = var12 - var13;
int var17 = var10 + var13;
int var18 = var11 + var13;
int var19 = var12 + var13;
ChunkCache var20 = new ChunkCache(this, var14, var15, var16, var17, var18, var19, 0);
PathEntity var21 = (new PathFinder(var20, par6, par7, par8, par9)).createEntityPathTo(par1Entity, par2, par3, par4, par5);
this.theProfiler.endSection();
return var21;
}
/**
* Is this block powering in the specified direction Args: x, y, z, direction
*/
public int isBlockProvidingPowerTo(int par1, int par2, int par3, int par4) {
int var5 = this.getBlockId(par1, par2, par3);
return var5 == 0 ? 0 : Block.blocksList[var5].isProvidingStrongPower(this, par1, par2, par3, par4);
}
/**
* Returns the highest redstone signal strength powering the given block. Args: X, Y, Z.
*/
public int getBlockPowerInput(int par1, int par2, int par3) {
byte var4 = 0;
int var5 = Math.max(var4, this.isBlockProvidingPowerTo(par1, par2 - 1, par3, 0));
if (var5 >= 15) {
return var5;
} else {
var5 = Math.max(var5, this.isBlockProvidingPowerTo(par1, par2 + 1, par3, 1));
if (var5 >= 15) {
return var5;
} else {
var5 = Math.max(var5, this.isBlockProvidingPowerTo(par1, par2, par3 - 1, 2));
if (var5 >= 15) {
return var5;
} else {
var5 = Math.max(var5, this.isBlockProvidingPowerTo(par1, par2, par3 + 1, 3));
if (var5 >= 15) {
return var5;
} else {
var5 = Math.max(var5, this.isBlockProvidingPowerTo(par1 - 1, par2, par3, 4));
if (var5 >= 15) {
return var5;
} else {
var5 = Math.max(var5, this.isBlockProvidingPowerTo(par1 + 1, par2, par3, 5));
return var5 >= 15 ? var5 : var5;
}
}
}
}
}
}
/**
* Returns the indirect signal strength being outputted by the given block in the *opposite* of the given direction.
* Args: X, Y, Z, direction
*/
public boolean getIndirectPowerOutput(int par1, int par2, int par3, int par4) {
return this.getIndirectPowerLevelTo(par1, par2, par3, par4) > 0;
}
/**
* Gets the power level from a certain block face. Args: x, y, z, direction
*/
public int getIndirectPowerLevelTo(int par1, int par2, int par3, int par4) {
if (this.isBlockNormalCube(par1, par2, par3)) {
return this.getBlockPowerInput(par1, par2, par3);
} else {
int var5 = this.getBlockId(par1, par2, par3);
return var5 == 0 ? 0 : Block.blocksList[var5].isProvidingWeakPower(this, par1, par2, par3, par4);
}
}
/**
* Used to see if one of the blocks next to you or your block is getting power from a neighboring block. Used by items
* like TNT or Doors so they don't have redstone going straight into them. Args: x, y, z
*/
public boolean isBlockIndirectlyGettingPowered(int par1, int par2, int par3) {
return this.getIndirectPowerLevelTo(par1, par2 - 1, par3, 0) > 0 ? true : (this.getIndirectPowerLevelTo(par1, par2 + 1, par3, 1) > 0 ? true : (this.getIndirectPowerLevelTo(par1, par2, par3 - 1, 2) > 0 ? true : (this.getIndirectPowerLevelTo(par1, par2, par3 + 1, 3) > 0 ? true : (this.getIndirectPowerLevelTo(par1 - 1, par2, par3, 4) > 0 ? true : this.getIndirectPowerLevelTo(par1 + 1, par2, par3, 5) > 0))));
}
public int getStrongestIndirectPower(int par1, int par2, int par3) {
int var4 = 0;
for (int var5 = 0; var5 < 6; ++var5) {
int var6 = this.getIndirectPowerLevelTo(par1 + Facing.offsetsXForSide[var5], par2 + Facing.offsetsYForSide[var5], par3 + Facing.offsetsZForSide[var5], var5);
if (var6 >= 15) {
return 15;
}
if (var6 > var4) {
var4 = var6;
}
}
return var4;
}
/**
* Gets the closest player to the entity within the specified distance (if distance is less than 0 then ignored). Args:
* entity, dist
*/
public EntityPlayer getClosestPlayerToEntity(Entity par1Entity, double par2) {
return this.getClosestPlayer(par1Entity.posX, par1Entity.posY, par1Entity.posZ, par2);
}
/**
* Gets the closest player to the point within the specified distance (distance can be set to less than 0 to not limit
* the distance). Args: x, y, z, dist
*/
public EntityPlayer getClosestPlayer(double par1, double par3, double par5, double par7) {
double var9 = -1.0D;
EntityPlayer var11 = null;
for (int var12 = 0; var12 < this.playerEntities.size(); ++var12) {
EntityPlayer var13 = (EntityPlayer)this.playerEntities.get(var12);
double var14 = var13.getDistanceSq(par1, par3, par5);
if ((par7 < 0.0D || var14 < par7 * par7) && (var9 == -1.0D || var14 < var9)) {
var9 = var14;
var11 = var13;
}
}
return var11;
}
/**
* Returns the closest vulnerable player to this entity within the given radius, or null if none is found
*/
public EntityPlayer getClosestVulnerablePlayerToEntity(Entity par1Entity, double par2) {
return this.getClosestVulnerablePlayer(par1Entity.posX, par1Entity.posY, par1Entity.posZ, par2);
}
/**
* Returns the closest vulnerable player within the given radius, or null if none is found.
*/
public EntityPlayer getClosestVulnerablePlayer(double par1, double par3, double par5, double par7) {
double var9 = -1.0D;
EntityPlayer var11 = null;
for (int var12 = 0; var12 < this.playerEntities.size(); ++var12) {
EntityPlayer var13 = (EntityPlayer)this.playerEntities.get(var12);
if (!var13.capabilities.disableDamage && var13.isEntityAlive()) {
double var14 = var13.getDistanceSq(par1, par3, par5);
double var16 = par7;
if (var13.isSneaking()) {
var16 = par7 * 0.800000011920929D;
}
if (var13.isInvisible()) {
float var18 = var13.getArmorVisibility();
if (var18 < 0.1F) {
var18 = 0.1F;
}
var16 *= (double)(0.7F * var18);
}
if ((par7 < 0.0D || var14 < var16 * var16) && (var9 == -1.0D || var14 < var9)) {
var9 = var14;
var11 = var13;
}
}
}
return var11;
}
/**
* Find a player by name in this world.
*/
public EntityPlayer getPlayerEntityByName(String par1Str) {
for (int var2 = 0; var2 < this.playerEntities.size(); ++var2) {
if (par1Str.equals(((EntityPlayer)this.playerEntities.get(var2)).getCommandSenderName())) {
return (EntityPlayer)this.playerEntities.get(var2);
}
}
return null;
}
/**
* If on MP, sends a quitting packet.
*/
public void sendQuittingDisconnectingPacket() {}
/**
* Checks whether the session lock file was modified by another process
*/
public void checkSessionLock() throws MinecraftException {
this.saveHandler.checkSessionLock();
}
public void func_82738_a(long par1) {
this.worldInfo.incrementTotalWorldTime(par1);
}
/**
* Retrieve the world seed from level.dat
*/
public long getSeed() {
return this.worldInfo.getSeed();
}
public long getTotalWorldTime() {
return this.worldInfo.getWorldTotalTime();
}
public long getWorldTime() {
return this.worldInfo.getWorldTime();
}
/**
* Sets the world time.
*/
public void setWorldTime(long par1) {
this.worldInfo.setWorldTime(par1);
}
/**
* Returns the coordinates of the spawn point
*/
public ChunkCoordinates getSpawnPoint() {
return new ChunkCoordinates(this.worldInfo.getSpawnX(), this.worldInfo.getSpawnY(), this.worldInfo.getSpawnZ());
}
public void setSpawnLocation(int par1, int par2, int par3) {
this.worldInfo.setSpawnPosition(par1, par2, par3);
}
/**
* spwans an entity and loads surrounding chunks
*/
public void joinEntityInSurroundings(Entity par1Entity) {
int var2 = MathHelper.floor_double(par1Entity.posX / 16.0D);
int var3 = MathHelper.floor_double(par1Entity.posZ / 16.0D);
byte var4 = 2;
for (int var5 = var2 - var4; var5 <= var2 + var4; ++var5) {
for (int var6 = var3 - var4; var6 <= var3 + var4; ++var6) {
this.getChunkFromChunkCoords(var5, var6);
}
}
if (!this.loadedEntityList.contains(par1Entity)) {
this.loadedEntityList.add(par1Entity);
}
}
/**
* 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 true;
}
/**
* sends a Packet 38 (Entity Status) to all tracked players of that entity
*/
public void setEntityState(Entity par1Entity, byte par2) {}
/**
* gets the IChunkProvider this world uses.
*/
public IChunkProvider getChunkProvider() {
return this.chunkProvider;
}
/**
* Adds a block event with the given Args to the blockEventCache. During the next tick(), the block specified will have
* its onBlockEvent handler called with the given parameters. Args: X,Y,Z, BlockID, EventID, EventParameter
*/
public void addBlockEvent(int par1, int par2, int par3, int par4, int par5, int par6) {
if (par4 > 0) {
Block.blocksList[par4].onBlockEventReceived(this, par1, par2, par3, par5, par6);
}
}
/**
* Returns this world's current save handler
*/
public ISaveHandler getSaveHandler() {
return this.saveHandler;
}
/**
* Gets the World's WorldInfo instance
*/
public WorldInfo getWorldInfo() {
return this.worldInfo;
}
/**
* Gets the GameRules instance.
*/
public GameRules getGameRules() {
return this.worldInfo.getGameRulesInstance();
}
/**
* Updates the flag that indicates whether or not all players in the world are sleeping.
*/
public void updateAllPlayersSleepingFlag() {}
public float getWeightedThunderStrength(float par1) {
return (this.prevThunderingStrength + (this.thunderingStrength - this.prevThunderingStrength) * par1) * this.getRainStrength(par1);
}
/**
* Not sure about this actually. Reverting this one myself.
*/
public float getRainStrength(float par1) {
return this.prevRainingStrength + (this.rainingStrength - this.prevRainingStrength) * par1;
}
public void setRainStrength(float par1) {
this.prevRainingStrength = par1;
this.rainingStrength = par1;
}
/**
* Returns true if the current thunder strength (weighted with the rain strength) is greater than 0.9
*/
public boolean isThundering() {
return (double)this.getWeightedThunderStrength(1.0F) > 0.9D;
}
/**
* Returns true if the current rain strength is greater than 0.2
*/
public boolean isRaining() {
return (double)this.getRainStrength(1.0F) > 0.2D;
}
public boolean canLightningStrikeAt(int par1, int par2, int par3) {
if (!this.isRaining()) {
return false;
} else if (!this.canBlockSeeTheSky(par1, par2, par3)) {
return false;
} else if (this.getPrecipitationHeight(par1, par3) > par2) {
return false;
} else {
BiomeGenBase var4 = this.getBiomeGenForCoords(par1, par3);
return var4.getEnableSnow() ? false : var4.canSpawnLightningBolt();
}
}
/**
* Checks to see if the biome rainfall values for a given x,y,z coordinate set are extremely high
*/
public boolean isBlockHighHumidity(int par1, int par2, int par3) {
BiomeGenBase var4 = this.getBiomeGenForCoords(par1, par3);
return var4.isHighHumidity();
}
/**
* Assigns the given String id to the given MapDataBase using the MapStorage, removing any existing ones of the same
* id.
*/
public void setItemData(String par1Str, WorldSavedData par2WorldSavedData) {
this.mapStorage.setData(par1Str, par2WorldSavedData);
}
/**
* Loads an existing MapDataBase corresponding to the given String id from disk using the MapStorage, instantiating the
* given Class, or returns null if none such file exists. args: Class to instantiate, String dataid
*/
public WorldSavedData loadItemData(Class par1Class, String par2Str) {
return this.mapStorage.loadData(par1Class, par2Str);
}
/**
* Returns an unique new data id from the MapStorage for the given prefix and saves the idCounts map to the 'idcounts'
* file.
*/
public int getUniqueDataId(String par1Str) {
return this.mapStorage.getUniqueDataId(par1Str);
}
public void func_82739_e(int par1, int par2, int par3, int par4, int par5) {
for (int var6 = 0; var6 < this.worldAccesses.size(); ++var6) {
((IWorldAccess)this.worldAccesses.get(var6)).broadcastSound(par1, par2, par3, par4, par5);
}
}
/**
* See description for playAuxSFX.
*/
public void playAuxSFX(int par1, int par2, int par3, int par4, int par5) {
this.playAuxSFXAtEntity((EntityPlayer)null, par1, par2, par3, par4, par5);
}
/**
* See description for playAuxSFX.
*/
public void playAuxSFXAtEntity(EntityPlayer par1EntityPlayer, int par2, int par3, int par4, int par5, int par6) {
try {
for (int var7 = 0; var7 < this.worldAccesses.size(); ++var7) {
((IWorldAccess)this.worldAccesses.get(var7)).playAuxSFX(par1EntityPlayer, par2, par3, par4, par5, par6);
}
} catch (Throwable var10) {
CrashReport var8 = CrashReport.makeCrashReport(var10, "Playing level event");
CrashReportCategory var9 = var8.makeCategory("Level event being played");
var9.addCrashSection("Block coordinates", CrashReportCategory.getLocationInfo(par3, par4, par5));
var9.addCrashSection("Event source", par1EntityPlayer);
var9.addCrashSection("Event type", Integer.valueOf(par2));
var9.addCrashSection("Event data", Integer.valueOf(par6));
throw new ReportedException(var8);
}
}
/**
* Returns current world height.
*/
public int getHeight() {
return 256;
}
/**
* Returns current world height.
*/
public int getActualHeight() {
return this.provider.hasNoSky ? 128 : 256;
}
public IUpdatePlayerListBox getMinecartSoundUpdater(EntityMinecart par1EntityMinecart) {
return null;
}
/**
* puts the World Random seed to a specific state dependant on the inputs
*/
public Random setRandomSeed(int par1, int par2, int par3) {
long var4 = (long)par1 * 341873128712L + (long)par2 * 132897987541L + this.getWorldInfo().getSeed() + (long)par3;
this.rand.setSeed(var4);
return this.rand;
}
/**
* Returns the location of the closest structure of the specified type. If not found returns null.
*/
public ChunkPosition findClosestStructure(String par1Str, int par2, int par3, int par4) {
return this.getChunkProvider().findClosestStructure(this, par1Str, par2, par3, par4);
}
/**
* set by !chunk.getAreLevelsEmpty
*/
public boolean extendedLevelsInChunkCache() {
return false;
}
/**
* Returns horizon height for use in rendering the sky.
*/
public double getHorizon() {
return this.worldInfo.getTerrainType() == WorldType.FLAT ? 0.0D : 63.0D;
}
/**
* Adds some basic stats of the world to the given crash report.
*/
public CrashReportCategory addWorldInfoToCrashReport(CrashReport par1CrashReport) {
CrashReportCategory var2 = par1CrashReport.makeCategoryDepth("Affected level", 1);
var2.addCrashSection("Level name", this.worldInfo == null ? "????" : this.worldInfo.getWorldName());
var2.addCrashSectionCallable("All players", new CallableLvl2(this));
var2.addCrashSectionCallable("Chunk stats", new CallableLvl3(this));
try {
this.worldInfo.addToCrashReport(var2);
} catch (Throwable var4) {
var2.addCrashSectionThrowable("Level Data Unobtainable", var4);
}
return var2;
}
/**
* Starts (or continues) destroying a block with given ID at the given coordinates for the given partially destroyed
* value
*/
public void destroyBlockInWorldPartially(int par1, int par2, int par3, int par4, int par5) {
for (int var6 = 0; var6 < this.worldAccesses.size(); ++var6) {
IWorldAccess var7 = (IWorldAccess)this.worldAccesses.get(var6);
var7.destroyBlockPartially(par1, par2, par3, par4, par5);
}
}
/**
* Return the Vec3Pool object for this world.
*/
public Vec3Pool getWorldVec3Pool() {
return this.vecPool;
}
/**
* returns a calendar object containing the current date
*/
public Calendar getCurrentDate() {
if (this.getTotalWorldTime() % 600L == 0L) {
this.theCalendar.setTimeInMillis(MinecraftServer.getSystemTimeMillis());
}
return this.theCalendar;
}
public void func_92088_a(double par1, double par3, double par5, double par7, double par9, double par11, NBTTagCompound par13NBTTagCompound) {}
public Scoreboard getScoreboard() {
return this.worldScoreboard;
}
public void func_96440_m(int par1, int par2, int par3, int par4) {
for (int var5 = 0; var5 < 4; ++var5) {
int var6 = par1 + Direction.offsetX[var5];
int var7 = par3 + Direction.offsetZ[var5];
int var8 = this.getBlockId(var6, par2, var7);
if (var8 != 0) {
Block var9 = Block.blocksList[var8];
if (Block.redstoneComparatorIdle.func_94487_f(var8)) {
var9.onNeighborBlockChange(this, var6, par2, var7, par4);
} else if (Block.isNormalCube(var8)) {
var6 += Direction.offsetX[var5];
var7 += Direction.offsetZ[var5];
var8 = this.getBlockId(var6, par2, var7);
var9 = Block.blocksList[var8];
if (Block.redstoneComparatorIdle.func_94487_f(var8)) {
var9.onNeighborBlockChange(this, var6, par2, var7, par4);
}
}
}
}
}
public ILogAgent getWorldLogAgent() {
return this.worldLogAgent;
}
/**
* returns a float value that can be used to determine how likely something is to go awry in the area. It increases
* based on how long the player is within the vicinity, the lunar phase, and game difficulty. The value can be up to
* 1.5 on the highest difficulty, 1.0 otherwise.
*/
public float getLocationTensionFactor(double par1, double par3, double par5) {
return this.getTensionFactorForBlock(MathHelper.floor_double(par1), MathHelper.floor_double(par3), MathHelper.floor_double(par5));
}
/**
* returns a float value that can be used to determine how likely something is to go awry in the area. It increases
* based on how long the player is within the vicinity, the lunar phase, and game difficulty. The value can be up to
* 1.5 on the highest difficulty, 1.0 otherwise.
*/
public float getTensionFactorForBlock(int par1, int par2, int par3) {
float var4 = 0.0F;
boolean var5 = this.difficultySetting == 3;
if (this.blockExists(par1, par2, par3)) {
float var6 = this.getCurrentMoonPhaseFactor();
var4 += MathHelper.clamp_float((float)this.getChunkFromBlockCoords(par1, par3).inhabitedTime / 3600000.0F, 0.0F, 1.0F) * (var5 ? 1.0F : 0.75F);
var4 += var6 * 0.25F;
}
if (this.difficultySetting < 2) {
var4 *= (float)this.difficultySetting / 2.0F;
}
return MathHelper.clamp_float(var4, 0.0F, var5 ? 1.5F : 1.0F);
}
// Spout Start
public void doColorfulStuff() {
for(int i = 0; i < this.playerEntities.size(); ++i) {
EntityPlayer ep = (EntityPlayer)this.playerEntities.get(i);
if (ep != Minecraft.getMinecraft().thePlayer || Minecraft.getMinecraft().gameSettings.thirdPersonView != 0) {
ep.doFancyStuff();
}
}
}
public int getGrassColorCache(int x, int y, int z) {
Chunk chunk = getChunkFromBlockCoords(x, z);
if (chunk != null) {
return chunk.grassColorCache;
}
return 0xffffff;
}
public void setGrassColorCache(int x, int y, int z, int color) {
Chunk chunk = getChunkFromBlockCoords(x, z);
if (chunk != null) {
chunk.grassColorCache = color;
}
}
public int getWaterColorCache(int x, int y, int z) {
Chunk chunk = getChunkFromBlockCoords(x, z);
if (chunk != null) {
return chunk.waterColorCache;
}
return 0xffffff;
}
public void setWaterColorCache(int x, int y, int z, int color) {
Chunk chunk = getChunkFromBlockCoords(x, z);
if (chunk != null) {
chunk.waterColorCache = color;
}
}
// Spout End
}