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 }