package net.minecraft.world;
import cpw.mods.fml.relauncher.Side;
import cpw.mods.fml.relauncher.SideOnly;
import net.minecraft.block.Block;
import net.minecraft.entity.Entity;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.entity.player.EntityPlayerMP;
import net.minecraft.util.ChunkCoordinates;
import net.minecraft.util.MathHelper;
import net.minecraft.util.Vec3;
import net.minecraft.world.biome.BiomeGenBase;
import net.minecraft.world.biome.WorldChunkManager;
import net.minecraft.world.biome.WorldChunkManagerHell;
import net.minecraft.world.chunk.Chunk;
import net.minecraft.world.chunk.IChunkProvider;
import net.minecraft.world.gen.ChunkProviderFlat;
import net.minecraft.world.gen.ChunkProviderGenerate;
import net.minecraft.world.gen.FlatGeneratorInfo;
import net.minecraft.world.storage.WorldInfo;
import net.minecraftforge.client.IRenderHandler;
import net.minecraftforge.common.DimensionManager;
public abstract class WorldProvider
{
/** world object being used */
public World worldObj;
public WorldType terrainType;
public String field_82913_c;
/** World chunk manager being used to generate chunks */
public WorldChunkManager worldChunkMgr;
/**
* States whether the Hell world provider is used(true) or if the normal world provider is used(false)
*/
public boolean isHellWorld = false;
/**
* A boolean that tells if a world does not have a sky. Used in calculating weather and skylight
*/
public boolean hasNoSky = false;
/** Light to brightness conversion table */
public float[] lightBrightnessTable = new float[16];
/** The id for the dimension (ex. -1: Nether, 0: Overworld, 1: The End) */
public int dimensionId = 0;
/** Array for sunrise/sunset colors (RGBA) */
private float[] colorsSunriseSunset = new float[4];
/**
* associate an existing world with a World provider, and setup its lightbrightness table
*/
public final void registerWorld(World par1World)
{
this.worldObj = par1World;
this.terrainType = par1World.getWorldInfo().getTerrainType();
this.field_82913_c = par1World.getWorldInfo().getGeneratorOptions();
this.registerWorldChunkManager();
this.generateLightBrightnessTable();
}
/**
* Creates the light to brightness table
*/
protected void generateLightBrightnessTable()
{
float var1 = 0.0F;
for (int var2 = 0; var2 <= 15; ++var2)
{
float var3 = 1.0F - (float)var2 / 15.0F;
this.lightBrightnessTable[var2] = (1.0F - var3) / (var3 * 3.0F + 1.0F) * (1.0F - var1) + var1;
}
}
/**
* creates a new world chunk manager for WorldProvider
*/
protected void registerWorldChunkManager()
{
worldChunkMgr = terrainType.getChunkManager(worldObj);
}
/**
* Returns a new chunk provider which generates chunks for this world
*/
public IChunkProvider createChunkGenerator()
{
return terrainType.getChunkGenerator(worldObj, field_82913_c);
}
/**
* Will check if the x, z position specified is alright to be set as the map spawn point
*/
public boolean canCoordinateBeSpawn(int par1, int par2)
{
int var3 = this.worldObj.getFirstUncoveredBlock(par1, par2);
return var3 == Block.grass.blockID;
}
/**
* Calculates the angle of sun and moon in the sky relative to a specified time (usually worldTime)
*/
public float calculateCelestialAngle(long par1, float par3)
{
int var4 = (int)(par1 % 24000L);
float var5 = ((float)var4 + par3) / 24000.0F - 0.25F;
if (var5 < 0.0F)
{
++var5;
}
if (var5 > 1.0F)
{
--var5;
}
float var6 = var5;
var5 = 1.0F - (float)((Math.cos((double)var5 * Math.PI) + 1.0D) / 2.0D);
var5 = var6 + (var5 - var6) / 3.0F;
return var5;
}
@SideOnly(Side.CLIENT)
public int getMoonPhase(long par1, float par3)
{
return (int)(par1 / 24000L) % 8;
}
/**
* Returns 'true' if in the "main surface world", but 'false' if in the Nether or End dimensions.
*/
public boolean isSurfaceWorld()
{
return true;
}
@SideOnly(Side.CLIENT)
/**
* Returns array with sunrise/sunset colors
*/
public float[] calcSunriseSunsetColors(float par1, float par2)
{
float var3 = 0.4F;
float var4 = MathHelper.cos(par1 * (float)Math.PI * 2.0F) - 0.0F;
float var5 = -0.0F;
if (var4 >= var5 - var3 && var4 <= var5 + var3)
{
float var6 = (var4 - var5) / var3 * 0.5F + 0.5F;
float var7 = 1.0F - (1.0F - MathHelper.sin(var6 * (float)Math.PI)) * 0.99F;
var7 *= var7;
this.colorsSunriseSunset[0] = var6 * 0.3F + 0.7F;
this.colorsSunriseSunset[1] = var6 * var6 * 0.7F + 0.2F;
this.colorsSunriseSunset[2] = var6 * var6 * 0.0F + 0.2F;
this.colorsSunriseSunset[3] = var7;
return this.colorsSunriseSunset;
}
else
{
return null;
}
}
@SideOnly(Side.CLIENT)
/**
* Return Vec3D with biome specific fog color
*/
public Vec3 getFogColor(float par1, float par2)
{
float var3 = MathHelper.cos(par1 * (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 = 0.7529412F;
float var5 = 0.84705883F;
float var6 = 1.0F;
var4 *= var3 * 0.94F + 0.06F;
var5 *= var3 * 0.94F + 0.06F;
var6 *= var3 * 0.91F + 0.09F;
return this.worldObj.getWorldVec3Pool().getVecFromPool((double)var4, (double)var5, (double)var6);
}
/**
* True if the player can respawn in this dimension (true = overworld, false = nether).
*/
public boolean canRespawnHere()
{
return true;
}
public static WorldProvider getProviderForDimension(int par0)
{
return DimensionManager.createProviderFor(par0);
}
@SideOnly(Side.CLIENT)
/**
* the y level at which clouds are rendered.
*/
public float getCloudHeight()
{
return 128.0F;
}
@SideOnly(Side.CLIENT)
public boolean isSkyColored()
{
return true;
}
/**
* Gets the hard-coded portal location to use when entering this dimension.
*/
public ChunkCoordinates getEntrancePortalLocation()
{
return null;
}
public int getAverageGroundLevel()
{
return this.terrainType.getMinimumSpawnHeight(this.worldObj);
}
@SideOnly(Side.CLIENT)
/**
* returns true if this dimension is supposed to display void particles and pull in the far plane based on the
* user's Y offset.
*/
public boolean getWorldHasVoidParticles()
{
return this.terrainType.hasVoidParticles(this.hasNoSky);
}
@SideOnly(Side.CLIENT)
/**
* Returns a double value representing the Y value relative to the top of the map at which void fog is at its
* maximum. The default factor of 0.03125 relative to 256, for example, means the void fog will be at its maximum at
* (256*0.03125), or 8.
*/
public double getVoidFogYFactor()
{
return this.terrainType.voidFadeMagnitude();
}
@SideOnly(Side.CLIENT)
/**
* Returns true if the given X,Z coordinate should show environmental fog.
*/
public boolean doesXZShowFog(int par1, int par2)
{
return false;
}
/**
* Returns the dimension's name, e.g. "The End", "Nether", or "Overworld".
*/
public abstract String getDimensionName();
/*======================================= Forge Start =========================================*/
private IRenderHandler skyRenderer = null;
private IRenderHandler cloudRenderer = null;
/**
* Sets the providers current dimension ID, used in default getSaveFolder()
* Added to allow default providers to be registered for multiple dimensions.
*
* @param dim Dimension ID
*/
public void setDimension(int dim)
{
this.dimensionId = dim;
}
/**
* Returns the sub-folder of the world folder that this WorldProvider saves to.
* EXA: DIM1, DIM-1
* @return The sub-folder name to save this world's chunks to.
*/
public String getSaveFolder()
{
return (dimensionId == 0 ? null : "DIM" + dimensionId);
}
/**
* A message to display to the user when they transfer to this dimension.
*
* @return The message to be displayed
*/
public String getWelcomeMessage()
{
if (this instanceof WorldProviderEnd)
{
return "Entering the End";
}
else if (this instanceof WorldProviderHell)
{
return "Entering the Nether";
}
return null;
}
/**
* A Message to display to the user when they transfer out of this dismension.
*
* @return The message to be displayed
*/
public String getDepartMessage()
{
if (this instanceof WorldProviderEnd)
{
return "Leaving the End";
}
else if (this instanceof WorldProviderHell)
{
return "Leaving the Nether";
}
return null;
}
/**
* The dimensions movement factor. Relative to normal overworld.
* It is applied to the players position when they transfer dimensions.
* Exa: Nether movement is 8.0
* @return The movement factor
*/
public double getMovementFactor()
{
if (this instanceof WorldProviderHell)
{
return 8.0;
}
return 1.0;
}
@SideOnly(Side.CLIENT)
public IRenderHandler getSkyRenderer()
{
return this.skyRenderer;
}
@SideOnly(Side.CLIENT)
public void setSkyRenderer(IRenderHandler skyRenderer)
{
this.skyRenderer = skyRenderer;
}
@SideOnly(Side.CLIENT)
public IRenderHandler getCloudRenderer()
{
return cloudRenderer;
}
@SideOnly(Side.CLIENT)
public void setCloudRenderer(IRenderHandler renderer)
{
cloudRenderer = renderer;
}
public ChunkCoordinates getRandomizedSpawnPoint()
{
ChunkCoordinates var5 = new ChunkCoordinates(this.worldObj.getSpawnPoint());
boolean isAdventure = worldObj.getWorldInfo().getGameType() == EnumGameType.ADVENTURE;
int spawnFuzz = terrainType.getSpawnFuzz();
int spawnFuzzHalf = spawnFuzz / 2;
if (!hasNoSky && !isAdventure)
{
var5.posX += this.worldObj.rand.nextInt(spawnFuzz) - spawnFuzzHalf;
var5.posZ += this.worldObj.rand.nextInt(spawnFuzz) - spawnFuzzHalf;
var5.posY = this.worldObj.getTopSolidOrLiquidBlock(var5.posX, var5.posZ);
}
return var5;
}
/**
* Determine if the cusor on the map should 'spin' when rendered, like it does for the player in the nether.
*
* @param entity The entity holding the map, playername, or frame-ENTITYID
* @param x X Position
* @param y Y Position
* @param z Z Postion
* @return True to 'spin' the cursor
*/
public boolean shouldMapSpin(String entity, double x, double y, double z)
{
return dimensionId < 0;
}
/**
* Determines the dimension the player will be respawned in, typically this brings them back to the overworld.
*
* @param player The player that is respawning
* @return The dimension to respawn the player in
*/
public int getRespawnDimension(EntityPlayerMP player)
{
return 0;
}
/*======================================= Start Moved From World =========================================*/
public BiomeGenBase getBiomeGenForCoords(int x, int z)
{
return worldObj.getBiomeGenForCoordsBody(x, z);
}
public boolean isDaytime()
{
return worldObj.skylightSubtracted < 4;
}
@SideOnly(Side.CLIENT)
public Vec3 getSkyColor(Entity cameraEntity, float partialTicks)
{
return worldObj.getSkyColorBody(cameraEntity, partialTicks);
}
@SideOnly(Side.CLIENT)
public Vec3 drawClouds(float partialTicks)
{
return worldObj.drawCloudsBody(partialTicks);
}
@SideOnly(Side.CLIENT)
public float getStarBrightness(float par1)
{
return worldObj.getStarBrightnessBody(par1);
}
public void setAllowedSpawnTypes(boolean allowHostile, boolean allowPeaceful)
{
worldObj.spawnHostileMobs = allowHostile;
worldObj.spawnPeacefulMobs = allowPeaceful;
}
public void calculateInitialWeather()
{
worldObj.calculateInitialWeatherBody();
}
public void updateWeather()
{
worldObj.updateWeatherBody();
}
public void toggleRain()
{
worldObj.worldInfo.setRainTime(1);
}
public boolean canBlockFreeze(int x, int y, int z, boolean byWater)
{
return worldObj.canBlockFreezeBody(x, y, z, byWater);
}
public boolean canSnowAt(int x, int y, int z)
{
return worldObj.canSnowAtBody(x, y, z);
}
public void setWorldTime(long time)
{
worldObj.worldInfo.setWorldTime(time);
}
public long getSeed()
{
return worldObj.worldInfo.getSeed();
}
public long getWorldTime()
{
return worldObj.worldInfo.getWorldTime();
}
public ChunkCoordinates getSpawnPoint()
{
WorldInfo info = worldObj.worldInfo;
return new ChunkCoordinates(info.getSpawnX(), info.getSpawnY(), info.getSpawnZ());
}
public void setSpawnPoint(int x, int y, int z)
{
worldObj.worldInfo.setSpawnPosition(x, y, z);
}
public boolean canMineBlock(EntityPlayer player, int x, int y, int z)
{
return worldObj.canMineBlockBody(player, x, y, z);
}
public boolean isBlockHighHumidity(int x, int y, int z)
{
return worldObj.getBiomeGenForCoords(x, z).isHighHumidity();
}
public int getHeight()
{
return 256;
}
public int getActualHeight()
{
return hasNoSky ? 128 : 256;
}
public double getHorizon()
{
return worldObj.worldInfo.getTerrainType().getHorizon(worldObj);
}
public void resetRainAndThunder()
{
worldObj.worldInfo.setRainTime(0);
worldObj.worldInfo.setRaining(false);
worldObj.worldInfo.setThunderTime(0);
worldObj.worldInfo.setThundering(false);
}
public boolean canDoLightning(Chunk chunk)
{
return true;
}
public boolean canDoRainSnowIce(Chunk chunk)
{
return true;
}
}