    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        public String field_82913_c;
    014
    015        /** World chunk manager being used to generate chunks */
    016        public WorldChunkManager worldChunkMgr;
    017
    018        /**
    019         * States whether the Hell world provider is used(true) or if the normal world provider is used(false)
    020         */
    021        public boolean isHellWorld = false;
    022
    023        /**
    024         * A boolean that tells if a world does not have a sky. Used in calculating weather and skylight
    025         */
    026        public boolean hasNoSky = false;
    027
    028        /** Light to brightness conversion table */
    029        public float[] lightBrightnessTable = new float[16];
    030
    031        /** The id for the dimension (ex. -1: Nether, 0: Overworld, 1: The End) */
    032        public int dimensionId = 0;
    033
    034        /** Array for sunrise/sunset colors (RGBA) */
    035        private float[] colorsSunriseSunset = new float[4];
    036
    037        /**
    038         * associate an existing world with a World provider, and setup its lightbrightness table
    039         */
    040        public final void registerWorld(World par1World)
    041        {
    042            this.worldObj = par1World;
    043            this.terrainType = par1World.getWorldInfo().getTerrainType();
    044            this.field_82913_c = par1World.getWorldInfo().func_82571_y();
    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            worldChunkMgr = terrainType.getChunkManager(worldObj);
    069        }
    070
    071        /**
    072         * Returns the chunk provider back for the world provider
    073         */
    074        public IChunkProvider getChunkProvider()
    075        {
    076            return terrainType.getChunkGenerator(worldObj, field_82913_c);
    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 this.worldObj.func_82732_R().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        /*======================================= Forge Start =========================================*/
    263        private SkyProvider skyProvider = null;
    264        /**
    265         * Sets the providers current dimension ID, used in default getSaveFolder()
    266         * Added to allow default providers to be registered for multiple dimensions.
    267         *
    268         * @param dim Dimension ID
    269         */
    270        public void setDimension(int dim)
    271        {
    272            this.dimensionId = dim;
    273        }
    274
    275        /**
    276         * Returns the sub-folder of the world folder that this WorldProvider saves to.
    277         * EXA: DIM1, DIM-1
    278         * @return The sub-folder name to save this world's chunks to.
    279         */
    280        public String getSaveFolder()
    281        {
    282            return (dimensionId == 0 ? null : "DIM" + dimensionId);
    283        }
    284
    285        /**
    286         * A message to display to the user when they transfer to this dimension.
    287         *
    288         * @return The message to be displayed
    289         */
    290        public String getWelcomeMessage()
    291        {
    292            if (this instanceof WorldProviderEnd)
    293            {
    294                return "Entering the End";
    295            }
    296            else if (this instanceof WorldProviderHell)
    297            {
    298                return "Entering the Nether";
    299            }
    300            return null;
    301        }
    302
    303        /**
    304         * A Message to display to the user when they transfer out of this dismension.
    305         *
    306         * @return The message to be displayed
    307         */
    308        public String getDepartMessage()
    309        {
    310            if (this instanceof WorldProviderEnd)
    311            {
    312                return "Leaving the End";
    313            }
    314            else if (this instanceof WorldProviderHell)
    315            {
    316                return "Leaving the Nether";
    317            }
    318            return null;
    319        }
    320
    321        /**
    322         * The dimensions movement factor. Relative to normal overworld.
    323         * It is applied to the players position when they transfer dimensions.
    324         * Exa: Nether movement is 8.0
    325         * @return The movement factor
    326         */
    327        public double getMovementFactor()
    328        {
    329            if (this instanceof WorldProviderHell)
    330            {
    331                return 8.0;
    332            }
    333            return 1.0;
    334        }
    335
    336        @SideOnly(Side.CLIENT)
    337        public SkyProvider getSkyProvider()
    338        {
    339            return this.skyProvider;
    340        }
    341
    342        @SideOnly(Side.CLIENT)
    343        public void setSkyProvider(SkyProvider skyProvider)
    344        {
    345            this.skyProvider = skyProvider;
    346        }
    347
    348        public ChunkCoordinates getRandomizedSpawnPoint()
    349        {
    350            ChunkCoordinates var5 = new ChunkCoordinates(this.worldObj.getSpawnPoint());
    351
    352            boolean isAdventure = worldObj.getWorldInfo().getGameType() != EnumGameType.ADVENTURE;
    353            int spawnFuzz = terrainType.getSpawnFuzz();
    354            int spawnFuzzHalf = spawnFuzz / 2;
    355
    356            if (!this.hasNoSky && !isAdventure)
    357            {
    358                var5.posX += this.worldObj.rand.nextInt(spawnFuzz) - spawnFuzzHalf;
    359                var5.posZ += this.worldObj.rand.nextInt(spawnFuzz) - spawnFuzzHalf;
    360                var5.posY = this.worldObj.getTopSolidOrLiquidBlock(var5.posX, var5.posZ);
    361            }
    362
    363            return var5;
    364        }
    365
    366        /*======================================= Start Moved From World =========================================*/
    367
    368        public BiomeGenBase getBiomeGenForCoords(int x, int z)
    369        {
    370            return worldObj.getBiomeGenForCoordsBody(x, z);
    371        }
    372
    373        public boolean isDaytime()
    374        {
    375            return worldObj.skylightSubtracted < 4;
    376        }
    377
    378        @SideOnly(Side.CLIENT)
    379        public Vec3 getSkyColor(Entity cameraEntity, float partialTicks)
    380        {
    381            return worldObj.getSkyColorBody(cameraEntity, partialTicks);
    382        }
    383
    384        @SideOnly(Side.CLIENT)
    385        public Vec3 drawClouds(float partialTicks)
    386        {
    387            return worldObj.drawCloudsBody(partialTicks);
    388        }
    389
    390        @SideOnly(Side.CLIENT)
    391        public float getStarBrightness(float par1)
    392        {
    393            return worldObj.getStarBrightnessBody(par1);
    394        }
    395
    396        public void setAllowedSpawnTypes(boolean allowHostile, boolean allowPeaceful)
    397        {
    398            worldObj.spawnHostileMobs = allowHostile;
    399            worldObj.spawnPeacefulMobs = allowPeaceful;
    400        }
    401
    402        public void calculateInitialWeather()
    403        {
    404            worldObj.calculateInitialWeatherBody();
    405        }
    406
    407        public void updateWeather()
    408        {
    409            worldObj.updateWeatherBody();
    410        }
    411
    412        public void toggleRain()
    413        {
    414            worldObj.worldInfo.setRainTime(1);
    415        }
    416
    417        public boolean canBlockFreeze(int x, int y, int z, boolean byWater)
    418        {
    419            return worldObj.canBlockFreezeBody(x, y, z, byWater);
    420        }
    421
    422        public boolean canSnowAt(int x, int y, int z)
    423        {
    424            return worldObj.canSnowAtBody(x, y, z);
    425        }
    426
    427        public void setWorldTime(long time)
    428        {
    429            worldObj.worldInfo.setWorldTime(time);
    430        }
    431
    432        public long getSeed()
    433        {
    434            return worldObj.worldInfo.getSeed();
    435        }
    436
    437        public long getWorldTime()
    438        {
    439            return worldObj.worldInfo.getWorldTime();
    440        }
    441
    442        public ChunkCoordinates getSpawnPoint()
    443        {
    444            WorldInfo info = worldObj.worldInfo;
    445            return new ChunkCoordinates(info.getSpawnX(), info.getSpawnY(), info.getSpawnZ());
    446        }
    447
    448        public void setSpawnPoint(int x, int y, int z)
    449        {
    450            worldObj.worldInfo.setSpawnPosition(x, y, z);
    451        }
    452
    453        public boolean canMineBlock(EntityPlayer player, int x, int y, int z)
    454        {
    455            return worldObj.canMineBlockBody(player, x, y, z);
    456        }
    457
    458        public boolean isBlockHighHumidity(int x, int y, int z)
    459        {
    460            return worldObj.getBiomeGenForCoords(x, z).isHighHumidity();
    461        }
    462
    463        public int getHeight()
    464        {
    465            return 256;
    466        }
    467
    468        public int getActualHeight()
    469        {
    470            return hasNoSky ? 128 : 256;
    471        }
    472
    473        public double getHorizon()
    474        {
    475            return worldObj.worldInfo.getTerrainType().getHorizon(worldObj);
    476        }
    477
    478        public void resetRainAndThunder()
    479        {
    480            worldObj.worldInfo.setRainTime(0);
    481            worldObj.worldInfo.setRaining(false);
    482            worldObj.worldInfo.setThunderTime(0);
    483            worldObj.worldInfo.setThundering(false);
    484        }
    485
    486        public boolean canDoLightning(Chunk chunk)
    487        {
    488            return true;
    489        }
    490
    491        public boolean canDoRainSnowIce(Chunk chunk)
    492        {
    493            return true;
    494        }
    495    }