001 package net.minecraft.src; 002 003 import net.minecraftforge.client.SkyProvider; 004 import net.minecraftforge.common.DimensionManager; 005 import cpw.mods.fml.common.Side; 006 import cpw.mods.fml.common.asm.SideOnly; 007 008 public abstract class WorldProvider 009 { 010 /** world object being used */ 011 public World worldObj; 012 public WorldType terrainType; 013 014 /** World chunk manager being used to generate chunks */ 015 public WorldChunkManager worldChunkMgr; 016 017 /** 018 * States whether the Hell world provider is used(true) or if the normal world provider is used(false) 019 */ 020 public boolean isHellWorld = false; 021 022 /** 023 * A boolean that tells if a world does not have a sky. Used in calculating weather and skylight 024 */ 025 public boolean hasNoSky = false; 026 027 /** Light to brightness conversion table */ 028 public float[] lightBrightnessTable = new float[16]; 029 030 /** The id for the dimension (ex. -1: Nether, 0: Overworld, 1: The End) */ 031 public int dimensionId = 0; 032 033 /** Array for sunrise/sunset colors (RGBA) */ 034 private float[] colorsSunriseSunset = new float[4]; 035 036 private SkyProvider skyProvider = null; 037 038 /** 039 * associate an existing world with a World provider, and setup its lightbrightness table 040 */ 041 public final void registerWorld(World par1World) 042 { 043 this.worldObj = par1World; 044 this.terrainType = par1World.getWorldInfo().getTerrainType(); 045 this.registerWorldChunkManager(); 046 this.generateLightBrightnessTable(); 047 } 048 049 /** 050 * Creates the light to brightness table 051 */ 052 protected void generateLightBrightnessTable() 053 { 054 float var1 = 0.0F; 055 056 for (int var2 = 0; var2 <= 15; ++var2) 057 { 058 float var3 = 1.0F - (float)var2 / 15.0F; 059 this.lightBrightnessTable[var2] = (1.0F - var3) / (var3 * 3.0F + 1.0F) * (1.0F - var1) + var1; 060 } 061 } 062 063 /** 064 * creates a new world chunk manager for WorldProvider 065 */ 066 protected void registerWorldChunkManager() 067 { 068 this.worldChunkMgr = this.terrainType.getChunkManager(this.worldObj); 069 } 070 071 /** 072 * Returns the chunk provider back for the world provider 073 */ 074 public IChunkProvider getChunkProvider() 075 { 076 return this.terrainType.getChunkGenerator(this.worldObj); 077 } 078 079 /** 080 * Will check if the x, z position specified is alright to be set as the map spawn point 081 */ 082 public boolean canCoordinateBeSpawn(int par1, int par2) 083 { 084 int var3 = this.worldObj.getFirstUncoveredBlock(par1, par2); 085 return var3 == Block.grass.blockID; 086 } 087 088 /** 089 * Calculates the angle of sun and moon in the sky relative to a specified time (usually worldTime) 090 */ 091 public float calculateCelestialAngle(long par1, float par3) 092 { 093 int var4 = (int)(par1 % 24000L); 094 float var5 = ((float)var4 + par3) / 24000.0F - 0.25F; 095 096 if (var5 < 0.0F) 097 { 098 ++var5; 099 } 100 101 if (var5 > 1.0F) 102 { 103 --var5; 104 } 105 106 float var6 = var5; 107 var5 = 1.0F - (float)((Math.cos((double)var5 * Math.PI) + 1.0D) / 2.0D); 108 var5 = var6 + (var5 - var6) / 3.0F; 109 return var5; 110 } 111 112 @SideOnly(Side.CLIENT) 113 public int getMoonPhase(long par1, float par3) 114 { 115 return (int)(par1 / 24000L) % 8; 116 } 117 118 /** 119 * Returns 'true' if in the "main surface world", but 'false' if in the Nether or End dimensions. 120 */ 121 public boolean isSurfaceWorld() 122 { 123 return true; 124 } 125 126 @SideOnly(Side.CLIENT) 127 128 /** 129 * Returns array with sunrise/sunset colors 130 */ 131 public float[] calcSunriseSunsetColors(float par1, float par2) 132 { 133 float var3 = 0.4F; 134 float var4 = MathHelper.cos(par1 * (float)Math.PI * 2.0F) - 0.0F; 135 float var5 = -0.0F; 136 137 if (var4 >= var5 - var3 && var4 <= var5 + var3) 138 { 139 float var6 = (var4 - var5) / var3 * 0.5F + 0.5F; 140 float var7 = 1.0F - (1.0F - MathHelper.sin(var6 * (float)Math.PI)) * 0.99F; 141 var7 *= var7; 142 this.colorsSunriseSunset[0] = var6 * 0.3F + 0.7F; 143 this.colorsSunriseSunset[1] = var6 * var6 * 0.7F + 0.2F; 144 this.colorsSunriseSunset[2] = var6 * var6 * 0.0F + 0.2F; 145 this.colorsSunriseSunset[3] = var7; 146 return this.colorsSunriseSunset; 147 } 148 else 149 { 150 return null; 151 } 152 } 153 154 @SideOnly(Side.CLIENT) 155 156 /** 157 * Return Vec3D with biome specific fog color 158 */ 159 public Vec3 getFogColor(float par1, float par2) 160 { 161 float var3 = MathHelper.cos(par1 * (float)Math.PI * 2.0F) * 2.0F + 0.5F; 162 163 if (var3 < 0.0F) 164 { 165 var3 = 0.0F; 166 } 167 168 if (var3 > 1.0F) 169 { 170 var3 = 1.0F; 171 } 172 173 float var4 = 0.7529412F; 174 float var5 = 0.84705883F; 175 float var6 = 1.0F; 176 var4 *= var3 * 0.94F + 0.06F; 177 var5 *= var3 * 0.94F + 0.06F; 178 var6 *= var3 * 0.91F + 0.09F; 179 return Vec3.getVec3Pool().getVecFromPool((double)var4, (double)var5, (double)var6); 180 } 181 182 /** 183 * True if the player can respawn in this dimension (true = overworld, false = nether). 184 */ 185 public boolean canRespawnHere() 186 { 187 return true; 188 } 189 190 public static WorldProvider getProviderForDimension(int par0) 191 { 192 return DimensionManager.createProviderFor(par0); 193 } 194 195 @SideOnly(Side.CLIENT) 196 197 /** 198 * the y level at which clouds are rendered. 199 */ 200 public float getCloudHeight() 201 { 202 return 128.0F; 203 } 204 205 @SideOnly(Side.CLIENT) 206 public boolean isSkyColored() 207 { 208 return true; 209 } 210 211 /** 212 * Gets the hard-coded portal location to use when entering this dimension. 213 */ 214 public ChunkCoordinates getEntrancePortalLocation() 215 { 216 return null; 217 } 218 219 public int getAverageGroundLevel() 220 { 221 return this.terrainType.getMinimumSpawnHeight(this.worldObj); 222 } 223 224 @SideOnly(Side.CLIENT) 225 226 /** 227 * returns true if this dimension is supposed to display void particles and pull in the far plane based on the 228 * user's Y offset. 229 */ 230 public boolean getWorldHasVoidParticles() 231 { 232 return this.terrainType.hasVoidParticles(this.hasNoSky); 233 } 234 235 @SideOnly(Side.CLIENT) 236 237 /** 238 * Returns a double value representing the Y value relative to the top of the map at which void fog is at its 239 * maximum. The default factor of 0.03125 relative to 256, for example, means the void fog will be at its maximum at 240 * (256*0.03125), or 8. 241 */ 242 public double getVoidFogYFactor() 243 { 244 return this.terrainType.voidFadeMagnitude(); 245 } 246 247 @SideOnly(Side.CLIENT) 248 249 /** 250 * Returns true if the given X,Z coordinate should show environmental fog. 251 */ 252 public boolean doesXZShowFog(int par1, int par2) 253 { 254 return false; 255 } 256 257 /** 258 * Returns the dimension's name, e.g. "The End", "Nether", or "Overworld". 259 */ 260 public abstract String getDimensionName(); 261 262 263 /*======================================= Forge Start =========================================*/ 264 private int dimensionID = 0; 265 266 /** 267 * Sets the providers current dimension ID, used in default getSaveFolder() 268 * Added to allow default providers to be registered for multiple dimensions. 269 * 270 * @param dim Dimension ID 271 */ 272 public void setDimension(int dim) 273 { 274 this.dimensionID = dim; 275 } 276 277 /** 278 * Returns the sub-folder of the world folder that this WorldProvider saves to. 279 * EXA: DIM1, DIM-1 280 * @return The sub-folder name to save this world's chunks to. 281 */ 282 public String getSaveFolder() 283 { 284 return (dimensionID == 0 ? null : "DIM" + dimensionID); 285 } 286 287 /** 288 * A message to display to the user when they transfer to this dimension. 289 * 290 * @return The message to be displayed 291 */ 292 public String getWelcomeMessage() 293 { 294 if (this instanceof WorldProviderEnd) 295 { 296 return "Entering the End"; 297 } 298 else if (this instanceof WorldProviderHell) 299 { 300 return "Entering the Nether"; 301 } 302 return null; 303 } 304 305 /** 306 * A Message to display to the user when they transfer out of this dismension. 307 * 308 * @return The message to be displayed 309 */ 310 public String getDepartMessage() 311 { 312 if (this instanceof WorldProviderEnd) 313 { 314 return "Leaving the End"; 315 } 316 else if (this instanceof WorldProviderHell) 317 { 318 return "Leaving the Nether"; 319 } 320 return null; 321 } 322 323 /** 324 * The dimensions movement factor. Relative to normal overworld. 325 * It is applied to the players position when they transfer dimensions. 326 * Exa: Nether movement is 8.0 327 * @return The movement factor 328 */ 329 public double getMovementFactor() 330 { 331 if (this instanceof WorldProviderHell) 332 { 333 return 8.0; 334 } 335 return 1.0; 336 } 337 338 @SideOnly(Side.CLIENT) 339 public SkyProvider getSkyProvider() 340 { 341 return this.skyProvider; 342 } 343 344 @SideOnly(Side.CLIENT) 345 public void setSkyProvider(SkyProvider skyProvider) 346 { 347 this.skyProvider = skyProvider; 348 } 349 350 public ChunkCoordinates getRandomizedSpawnPoint() 351 { 352 ChunkCoordinates var5 = new ChunkCoordinates(this.worldObj.getSpawnPoint()); 353 354 boolean isAdventure = worldObj.getWorldInfo().getGameType() != EnumGameType.ADVENTURE; 355 int spawnFuzz = terrainType.getSpawnFuzz(); 356 int spawnFuzzHalf = spawnFuzz / 2; 357 358 if (!this.hasNoSky && !isAdventure) 359 { 360 var5.posX += this.worldObj.rand.nextInt(spawnFuzz) - spawnFuzzHalf; 361 var5.posZ += this.worldObj.rand.nextInt(spawnFuzz) - spawnFuzzHalf; 362 var5.posY = this.worldObj.getTopSolidOrLiquidBlock(var5.posX, var5.posZ); 363 } 364 365 return var5; 366 } 367 }