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 /** 037 * associate an existing world with a World provider, and setup its lightbrightness table 038 */ 039 public final void registerWorld(World par1World) 040 { 041 this.worldObj = par1World; 042 this.terrainType = par1World.getWorldInfo().getTerrainType(); 043 this.registerWorldChunkManager(); 044 this.generateLightBrightnessTable(); 045 } 046 047 /** 048 * Creates the light to brightness table 049 */ 050 protected void generateLightBrightnessTable() 051 { 052 float var1 = 0.0F; 053 054 for (int var2 = 0; var2 <= 15; ++var2) 055 { 056 float var3 = 1.0F - (float)var2 / 15.0F; 057 this.lightBrightnessTable[var2] = (1.0F - var3) / (var3 * 3.0F + 1.0F) * (1.0F - var1) + var1; 058 } 059 } 060 061 /** 062 * creates a new world chunk manager for WorldProvider 063 */ 064 protected void registerWorldChunkManager() 065 { 066 this.worldChunkMgr = this.terrainType.getChunkManager(this.worldObj); 067 } 068 069 /** 070 * Returns the chunk provider back for the world provider 071 */ 072 public IChunkProvider getChunkProvider() 073 { 074 return this.terrainType.getChunkGenerator(this.worldObj); 075 } 076 077 /** 078 * Will check if the x, z position specified is alright to be set as the map spawn point 079 */ 080 public boolean canCoordinateBeSpawn(int par1, int par2) 081 { 082 int var3 = this.worldObj.getFirstUncoveredBlock(par1, par2); 083 return var3 == Block.grass.blockID; 084 } 085 086 /** 087 * Calculates the angle of sun and moon in the sky relative to a specified time (usually worldTime) 088 */ 089 public float calculateCelestialAngle(long par1, float par3) 090 { 091 int var4 = (int)(par1 % 24000L); 092 float var5 = ((float)var4 + par3) / 24000.0F - 0.25F; 093 094 if (var5 < 0.0F) 095 { 096 ++var5; 097 } 098 099 if (var5 > 1.0F) 100 { 101 --var5; 102 } 103 104 float var6 = var5; 105 var5 = 1.0F - (float)((Math.cos((double)var5 * Math.PI) + 1.0D) / 2.0D); 106 var5 = var6 + (var5 - var6) / 3.0F; 107 return var5; 108 } 109 110 @SideOnly(Side.CLIENT) 111 public int getMoonPhase(long par1, float par3) 112 { 113 return (int)(par1 / 24000L) % 8; 114 } 115 116 /** 117 * Returns 'true' if in the "main surface world", but 'false' if in the Nether or End dimensions. 118 */ 119 public boolean isSurfaceWorld() 120 { 121 return true; 122 } 123 124 @SideOnly(Side.CLIENT) 125 126 /** 127 * Returns array with sunrise/sunset colors 128 */ 129 public float[] calcSunriseSunsetColors(float par1, float par2) 130 { 131 float var3 = 0.4F; 132 float var4 = MathHelper.cos(par1 * (float)Math.PI * 2.0F) - 0.0F; 133 float var5 = -0.0F; 134 135 if (var4 >= var5 - var3 && var4 <= var5 + var3) 136 { 137 float var6 = (var4 - var5) / var3 * 0.5F + 0.5F; 138 float var7 = 1.0F - (1.0F - MathHelper.sin(var6 * (float)Math.PI)) * 0.99F; 139 var7 *= var7; 140 this.colorsSunriseSunset[0] = var6 * 0.3F + 0.7F; 141 this.colorsSunriseSunset[1] = var6 * var6 * 0.7F + 0.2F; 142 this.colorsSunriseSunset[2] = var6 * var6 * 0.0F + 0.2F; 143 this.colorsSunriseSunset[3] = var7; 144 return this.colorsSunriseSunset; 145 } 146 else 147 { 148 return null; 149 } 150 } 151 152 @SideOnly(Side.CLIENT) 153 154 /** 155 * Return Vec3D with biome specific fog color 156 */ 157 public Vec3 getFogColor(float par1, float par2) 158 { 159 float var3 = MathHelper.cos(par1 * (float)Math.PI * 2.0F) * 2.0F + 0.5F; 160 161 if (var3 < 0.0F) 162 { 163 var3 = 0.0F; 164 } 165 166 if (var3 > 1.0F) 167 { 168 var3 = 1.0F; 169 } 170 171 float var4 = 0.7529412F; 172 float var5 = 0.84705883F; 173 float var6 = 1.0F; 174 var4 *= var3 * 0.94F + 0.06F; 175 var5 *= var3 * 0.94F + 0.06F; 176 var6 *= var3 * 0.91F + 0.09F; 177 return Vec3.getVec3Pool().getVecFromPool((double)var4, (double)var5, (double)var6); 178 } 179 180 /** 181 * True if the player can respawn in this dimension (true = overworld, false = nether). 182 */ 183 public boolean canRespawnHere() 184 { 185 return true; 186 } 187 188 public static WorldProvider getProviderForDimension(int par0) 189 { 190 return DimensionManager.createProviderFor(par0); 191 } 192 193 @SideOnly(Side.CLIENT) 194 195 /** 196 * the y level at which clouds are rendered. 197 */ 198 public float getCloudHeight() 199 { 200 return 128.0F; 201 } 202 203 @SideOnly(Side.CLIENT) 204 public boolean isSkyColored() 205 { 206 return true; 207 } 208 209 /** 210 * Gets the hard-coded portal location to use when entering this dimension. 211 */ 212 public ChunkCoordinates getEntrancePortalLocation() 213 { 214 return null; 215 } 216 217 public int getAverageGroundLevel() 218 { 219 return this.terrainType.getMinimumSpawnHeight(this.worldObj); 220 } 221 222 @SideOnly(Side.CLIENT) 223 224 /** 225 * returns true if this dimension is supposed to display void particles and pull in the far plane based on the 226 * user's Y offset. 227 */ 228 public boolean getWorldHasVoidParticles() 229 { 230 return this.terrainType.hasVoidParticles(this.hasNoSky); 231 } 232 233 @SideOnly(Side.CLIENT) 234 235 /** 236 * Returns a double value representing the Y value relative to the top of the map at which void fog is at its 237 * maximum. The default factor of 0.03125 relative to 256, for example, means the void fog will be at its maximum at 238 * (256*0.03125), or 8. 239 */ 240 public double getVoidFogYFactor() 241 { 242 return this.terrainType.voidFadeMagnitude(); 243 } 244 245 @SideOnly(Side.CLIENT) 246 247 /** 248 * Returns true if the given X,Z coordinate should show environmental fog. 249 */ 250 public boolean doesXZShowFog(int par1, int par2) 251 { 252 return false; 253 } 254 255 /** 256 * Returns the dimension's name, e.g. "The End", "Nether", or "Overworld". 257 */ 258 public abstract String getDimensionName(); 259 260 /*======================================= Forge Start =========================================*/ 261 private SkyProvider skyProvider = null; 262 /** 263 * Sets the providers current dimension ID, used in default getSaveFolder() 264 * Added to allow default providers to be registered for multiple dimensions. 265 * 266 * @param dim Dimension ID 267 */ 268 public void setDimension(int dim) 269 { 270 this.dimensionId = dim; 271 } 272 273 /** 274 * Returns the sub-folder of the world folder that this WorldProvider saves to. 275 * EXA: DIM1, DIM-1 276 * @return The sub-folder name to save this world's chunks to. 277 */ 278 public String getSaveFolder() 279 { 280 return (dimensionId == 0 ? null : "DIM" + dimensionId); 281 } 282 283 /** 284 * A message to display to the user when they transfer to this dimension. 285 * 286 * @return The message to be displayed 287 */ 288 public String getWelcomeMessage() 289 { 290 if (this instanceof WorldProviderEnd) 291 { 292 return "Entering the End"; 293 } 294 else if (this instanceof WorldProviderHell) 295 { 296 return "Entering the Nether"; 297 } 298 return null; 299 } 300 301 /** 302 * A Message to display to the user when they transfer out of this dismension. 303 * 304 * @return The message to be displayed 305 */ 306 public String getDepartMessage() 307 { 308 if (this instanceof WorldProviderEnd) 309 { 310 return "Leaving the End"; 311 } 312 else if (this instanceof WorldProviderHell) 313 { 314 return "Leaving the Nether"; 315 } 316 return null; 317 } 318 319 /** 320 * The dimensions movement factor. Relative to normal overworld. 321 * It is applied to the players position when they transfer dimensions. 322 * Exa: Nether movement is 8.0 323 * @return The movement factor 324 */ 325 public double getMovementFactor() 326 { 327 if (this instanceof WorldProviderHell) 328 { 329 return 8.0; 330 } 331 return 1.0; 332 } 333 334 @SideOnly(Side.CLIENT) 335 public SkyProvider getSkyProvider() 336 { 337 return this.skyProvider; 338 } 339 340 @SideOnly(Side.CLIENT) 341 public void setSkyProvider(SkyProvider skyProvider) 342 { 343 this.skyProvider = skyProvider; 344 } 345 346 public ChunkCoordinates getRandomizedSpawnPoint() 347 { 348 ChunkCoordinates var5 = new ChunkCoordinates(this.worldObj.getSpawnPoint()); 349 350 boolean isAdventure = worldObj.getWorldInfo().getGameType() != EnumGameType.ADVENTURE; 351 int spawnFuzz = terrainType.getSpawnFuzz(); 352 int spawnFuzzHalf = spawnFuzz / 2; 353 354 if (!this.hasNoSky && !isAdventure) 355 { 356 var5.posX += this.worldObj.rand.nextInt(spawnFuzz) - spawnFuzzHalf; 357 var5.posZ += this.worldObj.rand.nextInt(spawnFuzz) - spawnFuzzHalf; 358 var5.posY = this.worldObj.getTopSolidOrLiquidBlock(var5.posX, var5.posZ); 359 } 360 361 return var5; 362 } 363 364 /*======================================= Start Moved From World =========================================*/ 365 366 public BiomeGenBase getBiomeGenForCoords(int x, int z) 367 { 368 return worldObj.getBiomeGenForCoordsBody(x, z); 369 } 370 371 public boolean isDaytime() 372 { 373 return worldObj.skylightSubtracted < 4; 374 } 375 376 @SideOnly(Side.CLIENT) 377 public Vec3 getSkyColor(Entity cameraEntity, float partialTicks) 378 { 379 return worldObj.getSkyColorBody(cameraEntity, partialTicks); 380 } 381 382 @SideOnly(Side.CLIENT) 383 public Vec3 drawClouds(float partialTicks) 384 { 385 return worldObj.drawCloudsBody(partialTicks); 386 } 387 388 @SideOnly(Side.CLIENT) 389 public float getStarBrightness(float par1) 390 { 391 return worldObj.getStarBrightnessBody(par1); 392 } 393 394 public void setAllowedSpawnTypes(boolean allowHostile, boolean allowPeaceful) 395 { 396 worldObj.spawnHostileMobs = allowHostile; 397 worldObj.spawnPeacefulMobs = allowPeaceful; 398 } 399 400 public void calculateInitialWeather() 401 { 402 worldObj.calculateInitialWeatherBody(); 403 } 404 405 public void updateWeather() 406 { 407 worldObj.updateWeatherBody(); 408 } 409 410 public void toggleRain() 411 { 412 worldObj.worldInfo.setRainTime(1); 413 } 414 415 public boolean canBlockFreeze(int x, int y, int z, boolean byWater) 416 { 417 return worldObj.canBlockFreezeBody(x, y, z, byWater); 418 } 419 420 public boolean canSnowAt(int x, int y, int z) 421 { 422 return worldObj.canSnowAtBody(x, y, z); 423 } 424 425 public void setWorldTime(long time) 426 { 427 worldObj.worldInfo.setWorldTime(time); 428 } 429 430 public long getSeed() 431 { 432 return worldObj.worldInfo.getSeed(); 433 } 434 435 public long getWorldTime() 436 { 437 return worldObj.worldInfo.getWorldTime(); 438 } 439 440 public ChunkCoordinates getSpawnPoint() 441 { 442 WorldInfo info = worldObj.worldInfo; 443 return new ChunkCoordinates(info.getSpawnX(), info.getSpawnY(), info.getSpawnZ()); 444 } 445 446 public void setSpawnPoint(int x, int y, int z) 447 { 448 worldObj.worldInfo.setSpawnPosition(x, y, z); 449 } 450 451 public boolean canMineBlock(EntityPlayer player, int x, int y, int z) 452 { 453 return worldObj.canMineBlockBody(player, x, y, z); 454 } 455 456 public boolean isBlockHighHumidity(int x, int y, int z) 457 { 458 return worldObj.getBiomeGenForCoords(x, z).isHighHumidity(); 459 } 460 461 public int getHeight() 462 { 463 return 256; 464 } 465 466 public int getActualHeight() 467 { 468 return hasNoSky ? 128 : 256; 469 } 470 471 public double getHorizon() 472 { 473 return worldObj.worldInfo.getTerrainType().getHorizon(worldObj); 474 } 475 476 public void resetRainAndThunder() 477 { 478 worldObj.worldInfo.setRainTime(0); 479 worldObj.worldInfo.setRaining(false); 480 worldObj.worldInfo.setThunderTime(0); 481 worldObj.worldInfo.setThundering(false); 482 } 483 484 public boolean canDoLightning(Chunk chunk) 485 { 486 return true; 487 } 488 489 public boolean canDoRainSnowIce(Chunk chunk) 490 { 491 return true; 492 } 493 }