base mod created

This commit is contained in:
Mohammad-Ali Minaie
2018-10-08 09:07:47 -04:00
parent 0a7700c356
commit b86dedad2f
7848 changed files with 584664 additions and 1 deletions

View File

@@ -0,0 +1,123 @@
package net.minecraft.world;
import java.util.UUID;
import net.minecraft.util.text.ITextComponent;
public abstract class BossInfo
{
private final UUID uniqueId;
protected ITextComponent name;
protected float percent;
protected BossInfo.Color color;
protected BossInfo.Overlay overlay;
protected boolean darkenSky;
protected boolean playEndBossMusic;
protected boolean createFog;
public BossInfo(UUID uniqueIdIn, ITextComponent nameIn, BossInfo.Color colorIn, BossInfo.Overlay overlayIn)
{
this.uniqueId = uniqueIdIn;
this.name = nameIn;
this.color = colorIn;
this.overlay = overlayIn;
this.percent = 1.0F;
}
public UUID getUniqueId()
{
return this.uniqueId;
}
public ITextComponent getName()
{
return this.name;
}
public void setName(ITextComponent nameIn)
{
this.name = nameIn;
}
public float getPercent()
{
return this.percent;
}
public void setPercent(float percentIn)
{
this.percent = percentIn;
}
public BossInfo.Color getColor()
{
return this.color;
}
public void setColor(BossInfo.Color colorIn)
{
this.color = colorIn;
}
public BossInfo.Overlay getOverlay()
{
return this.overlay;
}
public void setOverlay(BossInfo.Overlay overlayIn)
{
this.overlay = overlayIn;
}
public boolean shouldDarkenSky()
{
return this.darkenSky;
}
public BossInfo setDarkenSky(boolean darkenSkyIn)
{
this.darkenSky = darkenSkyIn;
return this;
}
public boolean shouldPlayEndBossMusic()
{
return this.playEndBossMusic;
}
public BossInfo setPlayEndBossMusic(boolean playEndBossMusicIn)
{
this.playEndBossMusic = playEndBossMusicIn;
return this;
}
public BossInfo setCreateFog(boolean createFogIn)
{
this.createFog = createFogIn;
return this;
}
public boolean shouldCreateFog()
{
return this.createFog;
}
public static enum Color
{
PINK,
BLUE,
RED,
GREEN,
YELLOW,
PURPLE,
WHITE;
}
public static enum Overlay
{
PROGRESS,
NOTCHED_6,
NOTCHED_10,
NOTCHED_12,
NOTCHED_20;
}
}

View File

@@ -0,0 +1,150 @@
package net.minecraft.world;
import com.google.common.base.Objects;
import com.google.common.collect.Sets;
import java.util.Collection;
import java.util.Collections;
import java.util.Set;
import net.minecraft.entity.player.EntityPlayerMP;
import net.minecraft.network.play.server.SPacketUpdateBossInfo;
import net.minecraft.util.math.MathHelper;
import net.minecraft.util.text.ITextComponent;
public class BossInfoServer extends BossInfo
{
private final Set<EntityPlayerMP> players = Sets.<EntityPlayerMP>newHashSet();
private final Set<EntityPlayerMP> readOnlyPlayers;
private boolean visible;
public BossInfoServer(ITextComponent nameIn, BossInfo.Color colorIn, BossInfo.Overlay overlayIn)
{
super(MathHelper.getRandomUUID(), nameIn, colorIn, overlayIn);
this.readOnlyPlayers = Collections.<EntityPlayerMP>unmodifiableSet(this.players);
this.visible = true;
}
public void setPercent(float percentIn)
{
if (percentIn != this.percent)
{
super.setPercent(percentIn);
this.sendUpdate(SPacketUpdateBossInfo.Operation.UPDATE_PCT);
}
}
public void setColor(BossInfo.Color colorIn)
{
if (colorIn != this.color)
{
super.setColor(colorIn);
this.sendUpdate(SPacketUpdateBossInfo.Operation.UPDATE_STYLE);
}
}
public void setOverlay(BossInfo.Overlay overlayIn)
{
if (overlayIn != this.overlay)
{
super.setOverlay(overlayIn);
this.sendUpdate(SPacketUpdateBossInfo.Operation.UPDATE_STYLE);
}
}
public BossInfo setDarkenSky(boolean darkenSkyIn)
{
if (darkenSkyIn != this.darkenSky)
{
super.setDarkenSky(darkenSkyIn);
this.sendUpdate(SPacketUpdateBossInfo.Operation.UPDATE_PROPERTIES);
}
return this;
}
public BossInfo setPlayEndBossMusic(boolean playEndBossMusicIn)
{
if (playEndBossMusicIn != this.playEndBossMusic)
{
super.setPlayEndBossMusic(playEndBossMusicIn);
this.sendUpdate(SPacketUpdateBossInfo.Operation.UPDATE_PROPERTIES);
}
return this;
}
public BossInfo setCreateFog(boolean createFogIn)
{
if (createFogIn != this.createFog)
{
super.setCreateFog(createFogIn);
this.sendUpdate(SPacketUpdateBossInfo.Operation.UPDATE_PROPERTIES);
}
return this;
}
public void setName(ITextComponent nameIn)
{
if (!Objects.equal(nameIn, this.name))
{
super.setName(nameIn);
this.sendUpdate(SPacketUpdateBossInfo.Operation.UPDATE_NAME);
}
}
private void sendUpdate(SPacketUpdateBossInfo.Operation operationIn)
{
if (this.visible)
{
SPacketUpdateBossInfo spacketupdatebossinfo = new SPacketUpdateBossInfo(operationIn, this);
for (EntityPlayerMP entityplayermp : this.players)
{
entityplayermp.connection.sendPacket(spacketupdatebossinfo);
}
}
}
/**
* Makes the boss visible to the given player.
*/
public void addPlayer(EntityPlayerMP player)
{
if (this.players.add(player) && this.visible)
{
player.connection.sendPacket(new SPacketUpdateBossInfo(SPacketUpdateBossInfo.Operation.ADD, this));
}
}
/**
* Makes the boss non-visible to the given player.
*/
public void removePlayer(EntityPlayerMP player)
{
if (this.players.remove(player) && this.visible)
{
player.connection.sendPacket(new SPacketUpdateBossInfo(SPacketUpdateBossInfo.Operation.REMOVE, this));
}
}
public void setVisible(boolean visibleIn)
{
if (visibleIn != this.visible)
{
this.visible = visibleIn;
for (EntityPlayerMP entityplayermp : this.players)
{
entityplayermp.connection.sendPacket(new SPacketUpdateBossInfo(visibleIn ? SPacketUpdateBossInfo.Operation.ADD : SPacketUpdateBossInfo.Operation.REMOVE, this));
}
}
}
/**
* The returned collection is unmodifiable
*/
public Collection<EntityPlayerMP> getPlayers()
{
return this.readOnlyPlayers;
}
}

View File

@@ -0,0 +1,222 @@
package net.minecraft.world;
import javax.annotation.Nullable;
import net.minecraft.block.material.Material;
import net.minecraft.block.state.IBlockState;
import net.minecraft.init.Blocks;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.EnumFacing;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.biome.Biome;
import net.minecraft.world.chunk.Chunk;
import net.minecraftforge.fml.relauncher.Side;
import net.minecraftforge.fml.relauncher.SideOnly;
public class ChunkCache implements IBlockAccess
{
protected int chunkX;
protected int chunkZ;
protected Chunk[][] chunkArray;
/** set by !chunk.getAreLevelsEmpty */
protected boolean empty;
/** Reference to the World object. */
protected World world;
public ChunkCache(World worldIn, BlockPos posFromIn, BlockPos posToIn, int subIn)
{
this.world = worldIn;
this.chunkX = posFromIn.getX() - subIn >> 4;
this.chunkZ = posFromIn.getZ() - subIn >> 4;
int i = posToIn.getX() + subIn >> 4;
int j = posToIn.getZ() + subIn >> 4;
this.chunkArray = new Chunk[i - this.chunkX + 1][j - this.chunkZ + 1];
this.empty = true;
for (int k = this.chunkX; k <= i; ++k)
{
for (int l = this.chunkZ; l <= j; ++l)
{
this.chunkArray[k - this.chunkX][l - this.chunkZ] = worldIn.getChunkFromChunkCoords(k, l);
}
}
for (int i1 = posFromIn.getX() >> 4; i1 <= posToIn.getX() >> 4; ++i1)
{
for (int j1 = posFromIn.getZ() >> 4; j1 <= posToIn.getZ() >> 4; ++j1)
{
Chunk chunk = this.chunkArray[i1 - this.chunkX][j1 - this.chunkZ];
if (chunk != null && !chunk.isEmptyBetween(posFromIn.getY(), posToIn.getY()))
{
this.empty = false;
}
}
}
}
/**
* set by !chunk.getAreLevelsEmpty
*/
@SideOnly(Side.CLIENT)
public boolean isEmpty()
{
return this.empty;
}
@Nullable
public TileEntity getTileEntity(BlockPos pos)
{
return this.getTileEntity(pos, Chunk.EnumCreateEntityType.CHECK); // Forge: don't modify world from other threads
}
@Nullable
public TileEntity getTileEntity(BlockPos pos, Chunk.EnumCreateEntityType p_190300_2_)
{
int i = (pos.getX() >> 4) - this.chunkX;
int j = (pos.getZ() >> 4) - this.chunkZ;
if (!withinBounds(i, j)) return null;
return this.chunkArray[i][j].getTileEntity(pos, p_190300_2_);
}
@SideOnly(Side.CLIENT)
public int getCombinedLight(BlockPos pos, int lightValue)
{
int i = this.getLightForExt(EnumSkyBlock.SKY, pos);
int j = this.getLightForExt(EnumSkyBlock.BLOCK, pos);
if (j < lightValue)
{
j = lightValue;
}
return i << 20 | j << 4;
}
public IBlockState getBlockState(BlockPos pos)
{
if (pos.getY() >= 0 && pos.getY() < 256)
{
int i = (pos.getX() >> 4) - this.chunkX;
int j = (pos.getZ() >> 4) - this.chunkZ;
if (i >= 0 && i < this.chunkArray.length && j >= 0 && j < this.chunkArray[i].length)
{
Chunk chunk = this.chunkArray[i][j];
if (chunk != null)
{
return chunk.getBlockState(pos);
}
}
}
return Blocks.AIR.getDefaultState();
}
@SideOnly(Side.CLIENT)
public Biome getBiome(BlockPos pos)
{
int i = (pos.getX() >> 4) - this.chunkX;
int j = (pos.getZ() >> 4) - this.chunkZ;
if (!withinBounds(i, j)) return net.minecraft.init.Biomes.PLAINS;
return this.chunkArray[i][j].getBiome(pos, this.world.getBiomeProvider());
}
@SideOnly(Side.CLIENT)
private int getLightForExt(EnumSkyBlock type, BlockPos pos)
{
if (type == EnumSkyBlock.SKY && !this.world.provider.hasSkyLight())
{
return 0;
}
else if (pos.getY() >= 0 && pos.getY() < 256)
{
if (this.getBlockState(pos).useNeighborBrightness())
{
int l = 0;
for (EnumFacing enumfacing : EnumFacing.values())
{
int k = this.getLightFor(type, pos.offset(enumfacing));
if (k > l)
{
l = k;
}
if (l >= 15)
{
return l;
}
}
return l;
}
else
{
int i = (pos.getX() >> 4) - this.chunkX;
int j = (pos.getZ() >> 4) - this.chunkZ;
if (!withinBounds(i, j)) return type.defaultLightValue;
return this.chunkArray[i][j].getLightFor(type, pos);
}
}
else
{
return type.defaultLightValue;
}
}
/**
* Checks to see if an air block exists at the provided location. Note that this only checks to see if the blocks
* material is set to air, meaning it is possible for non-vanilla blocks to still pass this check.
*/
public boolean isAirBlock(BlockPos pos)
{
IBlockState state = this.getBlockState(pos);
return state.getBlock().isAir(state, this, pos);
}
@SideOnly(Side.CLIENT)
public int getLightFor(EnumSkyBlock type, BlockPos pos)
{
if (pos.getY() >= 0 && pos.getY() < 256)
{
int i = (pos.getX() >> 4) - this.chunkX;
int j = (pos.getZ() >> 4) - this.chunkZ;
if (!withinBounds(i, j)) return type.defaultLightValue;
return this.chunkArray[i][j].getLightFor(type, pos);
}
else
{
return type.defaultLightValue;
}
}
public int getStrongPower(BlockPos pos, EnumFacing direction)
{
return this.getBlockState(pos).getStrongPower(this, pos, direction);
}
@SideOnly(Side.CLIENT)
public WorldType getWorldType()
{
return this.world.getWorldType();
}
@Override
public boolean isSideSolid(BlockPos pos, EnumFacing side, boolean _default)
{
int x = (pos.getX() >> 4) - this.chunkX;
int z = (pos.getZ() >> 4) - this.chunkZ;
if (pos.getY() < 0 || pos.getY() >= 256) return _default;
if (!withinBounds(x, z)) return _default;
IBlockState state = getBlockState(pos);
return state.getBlock().isSideSolid(state, this, pos, side);
}
private boolean withinBounds(int x, int z)
{
return x >= 0 && x < chunkArray.length && z >= 0 && z < chunkArray[x].length && chunkArray[x][z] != null;
}
}

View File

@@ -0,0 +1,48 @@
package net.minecraft.world;
import net.minecraftforge.fml.relauncher.Side;
import net.minecraftforge.fml.relauncher.SideOnly;
@SideOnly(Side.CLIENT)
public class ColorizerFoliage
{
/** Color buffer for foliage */
private static int[] foliageBuffer = new int[65536];
public static void setFoliageBiomeColorizer(int[] foliageBufferIn)
{
foliageBuffer = foliageBufferIn;
}
/**
* Gets the color modifier to use for foliage.
*/
public static int getFoliageColor(double temperature, double humidity)
{
humidity = humidity * temperature;
int i = (int)((1.0D - temperature) * 255.0D);
int j = (int)((1.0D - humidity) * 255.0D);
return foliageBuffer[j << 8 | i];
}
/**
* Gets the foliage color for pine type (metadata 1) trees
*/
public static int getFoliageColorPine()
{
return 6396257;
}
/**
* Gets the foliage color for birch type (metadata 2) trees
*/
public static int getFoliageColorBirch()
{
return 8431445;
}
public static int getFoliageColorBasic()
{
return 4764952;
}
}

View File

@@ -0,0 +1,28 @@
package net.minecraft.world;
import net.minecraftforge.fml.relauncher.Side;
import net.minecraftforge.fml.relauncher.SideOnly;
@SideOnly(Side.CLIENT)
public class ColorizerGrass
{
/** Color buffer for grass */
private static int[] grassBuffer = new int[65536];
public static void setGrassBiomeColorizer(int[] grassBufferIn)
{
grassBuffer = grassBufferIn;
}
/**
* Gets the color modifier to use for grass.
*/
public static int getGrassColor(double temperature, double humidity)
{
humidity = humidity * temperature;
int i = (int)((1.0D - temperature) * 255.0D);
int j = (int)((1.0D - humidity) * 255.0D);
int k = j << 8 | i;
return k > grassBuffer.length ? -65281 : grassBuffer[k];
}
}

View File

@@ -0,0 +1,65 @@
package net.minecraft.world;
import javax.annotation.concurrent.Immutable;
import net.minecraft.util.math.MathHelper;
@Immutable
public class DifficultyInstance
{
private final EnumDifficulty worldDifficulty;
private final float additionalDifficulty;
public DifficultyInstance(EnumDifficulty worldDifficulty, long worldTime, long chunkInhabitedTime, float moonPhaseFactor)
{
this.worldDifficulty = worldDifficulty;
this.additionalDifficulty = this.calculateAdditionalDifficulty(worldDifficulty, worldTime, chunkInhabitedTime, moonPhaseFactor);
}
public float getAdditionalDifficulty()
{
return this.additionalDifficulty;
}
public boolean isHarderThan(float p_193845_1_)
{
return this.additionalDifficulty > p_193845_1_;
}
public float getClampedAdditionalDifficulty()
{
if (this.additionalDifficulty < 2.0F)
{
return 0.0F;
}
else
{
return this.additionalDifficulty > 4.0F ? 1.0F : (this.additionalDifficulty - 2.0F) / 2.0F;
}
}
private float calculateAdditionalDifficulty(EnumDifficulty difficulty, long worldTime, long chunkInhabitedTime, float moonPhaseFactor)
{
if (difficulty == EnumDifficulty.PEACEFUL)
{
return 0.0F;
}
else
{
boolean flag = difficulty == EnumDifficulty.HARD;
float f = 0.75F;
float f1 = MathHelper.clamp(((float)worldTime + -72000.0F) / 1440000.0F, 0.0F, 1.0F) * 0.25F;
f = f + f1;
float f2 = 0.0F;
f2 = f2 + MathHelper.clamp((float)chunkInhabitedTime / 3600000.0F, 0.0F, 1.0F) * (flag ? 1.0F : 0.75F);
f2 = f2 + MathHelper.clamp(moonPhaseFactor * 0.25F, 0.0F, f1);
if (difficulty == EnumDifficulty.EASY)
{
f2 *= 0.5F;
}
f = f + f2;
return (float)difficulty.getDifficultyId() * f;
}
}
}

View File

@@ -0,0 +1,106 @@
package net.minecraft.world;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
public enum DimensionType
{
OVERWORLD(0, "overworld", "", WorldProviderSurface.class),
NETHER(-1, "the_nether", "_nether", WorldProviderHell.class),
THE_END(1, "the_end", "_end", WorldProviderEnd.class);
private final int id;
private final String name;
private final String suffix;
private final Class <? extends WorldProvider > clazz;
private boolean shouldLoadSpawn = false;
private DimensionType(int idIn, String nameIn, String suffixIn, Class <? extends WorldProvider > clazzIn)
{
this.id = idIn;
this.name = nameIn;
this.suffix = suffixIn;
this.clazz = clazzIn;
this.shouldLoadSpawn = idIn == 0;
}
public int getId()
{
return this.id;
}
public String getName()
{
return this.name;
}
public String getSuffix()
{
return this.suffix;
}
public WorldProvider createDimension()
{
try
{
Constructor <? extends WorldProvider > constructor = this.clazz.getConstructor();
return constructor.newInstance();
}
catch (NoSuchMethodException nosuchmethodexception)
{
throw new Error("Could not create new dimension", nosuchmethodexception);
}
catch (InvocationTargetException invocationtargetexception)
{
throw new Error("Could not create new dimension", invocationtargetexception);
}
catch (InstantiationException instantiationexception)
{
throw new Error("Could not create new dimension", instantiationexception);
}
catch (IllegalAccessException illegalaccessexception)
{
throw new Error("Could not create new dimension", illegalaccessexception);
}
}
public static DimensionType getById(int id)
{
for (DimensionType dimensiontype : values())
{
if (dimensiontype.getId() == id)
{
return dimensiontype;
}
}
throw new IllegalArgumentException("Invalid dimension id " + id);
}
public boolean shouldLoadSpawn(){ return this.shouldLoadSpawn; }
public DimensionType setLoadSpawn(boolean value) { this.shouldLoadSpawn = value; return this; }
private static Class<?>[] ENUM_ARGS = {int.class, String.class, String.class, Class.class};
static { net.minecraftforge.common.util.EnumHelper.testEnum(DimensionType.class, ENUM_ARGS); }
public static DimensionType register(String name, String suffix, int id, Class<? extends WorldProvider> provider, boolean keepLoaded)
{
String enum_name = name.replace(" ", "_").toLowerCase();
DimensionType ret = net.minecraftforge.common.util.EnumHelper.addEnum(DimensionType.class, enum_name, ENUM_ARGS,
id, name, suffix, provider);
return ret.setLoadSpawn(keepLoaded);
}
//TODO: Unregister? There is no way to really delete a enum value...
public static DimensionType byName(String p_193417_0_)
{
for (DimensionType dimensiontype : values())
{
if (dimensiontype.getName().equals(p_193417_0_))
{
return dimensiontype;
}
}
throw new IllegalArgumentException("Invalid dimension " + p_193417_0_);
}
}

View File

@@ -0,0 +1,42 @@
package net.minecraft.world;
public enum EnumDifficulty
{
PEACEFUL(0, "options.difficulty.peaceful"),
EASY(1, "options.difficulty.easy"),
NORMAL(2, "options.difficulty.normal"),
HARD(3, "options.difficulty.hard");
private static final EnumDifficulty[] ID_MAPPING = new EnumDifficulty[values().length];
private final int difficultyId;
private final String difficultyResourceKey;
private EnumDifficulty(int difficultyIdIn, String difficultyResourceKeyIn)
{
this.difficultyId = difficultyIdIn;
this.difficultyResourceKey = difficultyResourceKeyIn;
}
public int getDifficultyId()
{
return this.difficultyId;
}
public static EnumDifficulty getDifficultyEnum(int id)
{
return ID_MAPPING[id % ID_MAPPING.length];
}
public String getDifficultyResourceKey()
{
return this.difficultyResourceKey;
}
static
{
for (EnumDifficulty enumdifficulty : values())
{
ID_MAPPING[enumdifficulty.difficultyId] = enumdifficulty;
}
}
}

View File

@@ -0,0 +1,14 @@
package net.minecraft.world;
public enum EnumSkyBlock
{
SKY(15),
BLOCK(0);
public final int defaultLightValue;
private EnumSkyBlock(int defaultLightValueIn)
{
this.defaultLightValue = defaultLightValueIn;
}
}

View File

@@ -0,0 +1,297 @@
package net.minecraft.world;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.google.common.collect.Sets;
import java.util.List;
import java.util.Map;
import java.util.Random;
import java.util.Set;
import javax.annotation.Nullable;
import net.minecraft.block.Block;
import net.minecraft.block.material.Material;
import net.minecraft.block.state.IBlockState;
import net.minecraft.enchantment.EnchantmentProtection;
import net.minecraft.entity.Entity;
import net.minecraft.entity.EntityLivingBase;
import net.minecraft.entity.item.EntityTNTPrimed;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.init.Blocks;
import net.minecraft.init.SoundEvents;
import net.minecraft.util.DamageSource;
import net.minecraft.util.EnumParticleTypes;
import net.minecraft.util.SoundCategory;
import net.minecraft.util.math.AxisAlignedBB;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.MathHelper;
import net.minecraft.util.math.Vec3d;
import net.minecraftforge.fml.relauncher.Side;
import net.minecraftforge.fml.relauncher.SideOnly;
public class Explosion
{
/** whether or not the explosion sets fire to blocks around it */
private final boolean causesFire;
/** whether or not this explosion spawns smoke particles */
private final boolean damagesTerrain;
private final Random random;
private final World world;
private final double x;
private final double y;
private final double z;
private final Entity exploder;
private final float size;
/** A list of ChunkPositions of blocks affected by this explosion */
private final List<BlockPos> affectedBlockPositions;
/** Maps players to the knockback vector applied by the explosion, to send to the client */
private final Map<EntityPlayer, Vec3d> playerKnockbackMap;
private final Vec3d position;
@SideOnly(Side.CLIENT)
public Explosion(World worldIn, Entity entityIn, double x, double y, double z, float size, List<BlockPos> affectedPositions)
{
this(worldIn, entityIn, x, y, z, size, false, true, affectedPositions);
}
@SideOnly(Side.CLIENT)
public Explosion(World worldIn, Entity entityIn, double x, double y, double z, float size, boolean causesFire, boolean damagesTerrain, List<BlockPos> affectedPositions)
{
this(worldIn, entityIn, x, y, z, size, causesFire, damagesTerrain);
this.affectedBlockPositions.addAll(affectedPositions);
}
public Explosion(World worldIn, Entity entityIn, double x, double y, double z, float size, boolean flaming, boolean damagesTerrain)
{
this.random = new Random();
this.affectedBlockPositions = Lists.<BlockPos>newArrayList();
this.playerKnockbackMap = Maps.<EntityPlayer, Vec3d>newHashMap();
this.world = worldIn;
this.exploder = entityIn;
this.size = size;
this.x = x;
this.y = y;
this.z = z;
this.causesFire = flaming;
this.damagesTerrain = damagesTerrain;
this.position = new Vec3d(this.x, this.y, this.z);
}
/**
* Does the first part of the explosion (destroy blocks)
*/
public void doExplosionA()
{
Set<BlockPos> set = Sets.<BlockPos>newHashSet();
int i = 16;
for (int j = 0; j < 16; ++j)
{
for (int k = 0; k < 16; ++k)
{
for (int l = 0; l < 16; ++l)
{
if (j == 0 || j == 15 || k == 0 || k == 15 || l == 0 || l == 15)
{
double d0 = (double)((float)j / 15.0F * 2.0F - 1.0F);
double d1 = (double)((float)k / 15.0F * 2.0F - 1.0F);
double d2 = (double)((float)l / 15.0F * 2.0F - 1.0F);
double d3 = Math.sqrt(d0 * d0 + d1 * d1 + d2 * d2);
d0 = d0 / d3;
d1 = d1 / d3;
d2 = d2 / d3;
float f = this.size * (0.7F + this.world.rand.nextFloat() * 0.6F);
double d4 = this.x;
double d6 = this.y;
double d8 = this.z;
for (float f1 = 0.3F; f > 0.0F; f -= 0.22500001F)
{
BlockPos blockpos = new BlockPos(d4, d6, d8);
IBlockState iblockstate = this.world.getBlockState(blockpos);
if (iblockstate.getMaterial() != Material.AIR)
{
float f2 = this.exploder != null ? this.exploder.getExplosionResistance(this, this.world, blockpos, iblockstate) : iblockstate.getBlock().getExplosionResistance(world, blockpos, (Entity)null, this);
f -= (f2 + 0.3F) * 0.3F;
}
if (f > 0.0F && (this.exploder == null || this.exploder.canExplosionDestroyBlock(this, this.world, blockpos, iblockstate, f)))
{
set.add(blockpos);
}
d4 += d0 * 0.30000001192092896D;
d6 += d1 * 0.30000001192092896D;
d8 += d2 * 0.30000001192092896D;
}
}
}
}
}
this.affectedBlockPositions.addAll(set);
float f3 = this.size * 2.0F;
int k1 = MathHelper.floor(this.x - (double)f3 - 1.0D);
int l1 = MathHelper.floor(this.x + (double)f3 + 1.0D);
int i2 = MathHelper.floor(this.y - (double)f3 - 1.0D);
int i1 = MathHelper.floor(this.y + (double)f3 + 1.0D);
int j2 = MathHelper.floor(this.z - (double)f3 - 1.0D);
int j1 = MathHelper.floor(this.z + (double)f3 + 1.0D);
List<Entity> list = this.world.getEntitiesWithinAABBExcludingEntity(this.exploder, new AxisAlignedBB((double)k1, (double)i2, (double)j2, (double)l1, (double)i1, (double)j1));
net.minecraftforge.event.ForgeEventFactory.onExplosionDetonate(this.world, this, list, f3);
Vec3d vec3d = new Vec3d(this.x, this.y, this.z);
for (int k2 = 0; k2 < list.size(); ++k2)
{
Entity entity = list.get(k2);
if (!entity.isImmuneToExplosions())
{
double d12 = entity.getDistance(this.x, this.y, this.z) / (double)f3;
if (d12 <= 1.0D)
{
double d5 = entity.posX - this.x;
double d7 = entity.posY + (double)entity.getEyeHeight() - this.y;
double d9 = entity.posZ - this.z;
double d13 = (double)MathHelper.sqrt(d5 * d5 + d7 * d7 + d9 * d9);
if (d13 != 0.0D)
{
d5 = d5 / d13;
d7 = d7 / d13;
d9 = d9 / d13;
double d14 = (double)this.world.getBlockDensity(vec3d, entity.getEntityBoundingBox());
double d10 = (1.0D - d12) * d14;
entity.attackEntityFrom(DamageSource.causeExplosionDamage(this), (float)((int)((d10 * d10 + d10) / 2.0D * 7.0D * (double)f3 + 1.0D)));
double d11 = d10;
if (entity instanceof EntityLivingBase)
{
d11 = EnchantmentProtection.getBlastDamageReduction((EntityLivingBase)entity, d10);
}
entity.motionX += d5 * d11;
entity.motionY += d7 * d11;
entity.motionZ += d9 * d11;
if (entity instanceof EntityPlayer)
{
EntityPlayer entityplayer = (EntityPlayer)entity;
if (!entityplayer.isSpectator() && (!entityplayer.isCreative() || !entityplayer.capabilities.isFlying))
{
this.playerKnockbackMap.put(entityplayer, new Vec3d(d5 * d10, d7 * d10, d9 * d10));
}
}
}
}
}
}
}
/**
* Does the second part of the explosion (sound, particles, drop spawn)
*/
public void doExplosionB(boolean spawnParticles)
{
this.world.playSound((EntityPlayer)null, this.x, this.y, this.z, SoundEvents.ENTITY_GENERIC_EXPLODE, SoundCategory.BLOCKS, 4.0F, (1.0F + (this.world.rand.nextFloat() - this.world.rand.nextFloat()) * 0.2F) * 0.7F);
if (this.size >= 2.0F && this.damagesTerrain)
{
this.world.spawnParticle(EnumParticleTypes.EXPLOSION_HUGE, this.x, this.y, this.z, 1.0D, 0.0D, 0.0D);
}
else
{
this.world.spawnParticle(EnumParticleTypes.EXPLOSION_LARGE, this.x, this.y, this.z, 1.0D, 0.0D, 0.0D);
}
if (this.damagesTerrain)
{
for (BlockPos blockpos : this.affectedBlockPositions)
{
IBlockState iblockstate = this.world.getBlockState(blockpos);
Block block = iblockstate.getBlock();
if (spawnParticles)
{
double d0 = (double)((float)blockpos.getX() + this.world.rand.nextFloat());
double d1 = (double)((float)blockpos.getY() + this.world.rand.nextFloat());
double d2 = (double)((float)blockpos.getZ() + this.world.rand.nextFloat());
double d3 = d0 - this.x;
double d4 = d1 - this.y;
double d5 = d2 - this.z;
double d6 = (double)MathHelper.sqrt(d3 * d3 + d4 * d4 + d5 * d5);
d3 = d3 / d6;
d4 = d4 / d6;
d5 = d5 / d6;
double d7 = 0.5D / (d6 / (double)this.size + 0.1D);
d7 = d7 * (double)(this.world.rand.nextFloat() * this.world.rand.nextFloat() + 0.3F);
d3 = d3 * d7;
d4 = d4 * d7;
d5 = d5 * d7;
this.world.spawnParticle(EnumParticleTypes.EXPLOSION_NORMAL, (d0 + this.x) / 2.0D, (d1 + this.y) / 2.0D, (d2 + this.z) / 2.0D, d3, d4, d5);
this.world.spawnParticle(EnumParticleTypes.SMOKE_NORMAL, d0, d1, d2, d3, d4, d5);
}
if (iblockstate.getMaterial() != Material.AIR)
{
if (block.canDropFromExplosion(this))
{
block.dropBlockAsItemWithChance(this.world, blockpos, this.world.getBlockState(blockpos), 1.0F / this.size, 0);
}
block.onBlockExploded(this.world, blockpos, this);
}
}
}
if (this.causesFire)
{
for (BlockPos blockpos1 : this.affectedBlockPositions)
{
if (this.world.getBlockState(blockpos1).getMaterial() == Material.AIR && this.world.getBlockState(blockpos1.down()).isFullBlock() && this.random.nextInt(3) == 0)
{
this.world.setBlockState(blockpos1, Blocks.FIRE.getDefaultState());
}
}
}
}
public Map<EntityPlayer, Vec3d> getPlayerKnockbackMap()
{
return this.playerKnockbackMap;
}
/**
* Returns either the entity that placed the explosive block, the entity that caused the explosion or null.
*/
@Nullable
public EntityLivingBase getExplosivePlacedBy()
{
if (this.exploder == null)
{
return null;
}
else if (this.exploder instanceof EntityTNTPrimed)
{
return ((EntityTNTPrimed)this.exploder).getTntPlacedBy();
}
else
{
return this.exploder instanceof EntityLivingBase ? (EntityLivingBase)this.exploder : null;
}
}
public void clearAffectedBlockPositions()
{
this.affectedBlockPositions.clear();
}
public List<BlockPos> getAffectedBlockPositions()
{
return this.affectedBlockPositions;
}
public Vec3d getPosition(){ return this.position; }
}

View File

@@ -0,0 +1,208 @@
package net.minecraft.world;
import java.util.Set;
import java.util.TreeMap;
import net.minecraft.nbt.NBTTagCompound;
public class GameRules
{
private final TreeMap<String, GameRules.Value> rules = new TreeMap<String, GameRules.Value>();
public GameRules()
{
this.addGameRule("doFireTick", "true", GameRules.ValueType.BOOLEAN_VALUE);
this.addGameRule("mobGriefing", "true", GameRules.ValueType.BOOLEAN_VALUE);
this.addGameRule("keepInventory", "false", GameRules.ValueType.BOOLEAN_VALUE);
this.addGameRule("doMobSpawning", "true", GameRules.ValueType.BOOLEAN_VALUE);
this.addGameRule("doMobLoot", "true", GameRules.ValueType.BOOLEAN_VALUE);
this.addGameRule("doTileDrops", "true", GameRules.ValueType.BOOLEAN_VALUE);
this.addGameRule("doEntityDrops", "true", GameRules.ValueType.BOOLEAN_VALUE);
this.addGameRule("commandBlockOutput", "true", GameRules.ValueType.BOOLEAN_VALUE);
this.addGameRule("naturalRegeneration", "true", GameRules.ValueType.BOOLEAN_VALUE);
this.addGameRule("doDaylightCycle", "true", GameRules.ValueType.BOOLEAN_VALUE);
this.addGameRule("logAdminCommands", "true", GameRules.ValueType.BOOLEAN_VALUE);
this.addGameRule("showDeathMessages", "true", GameRules.ValueType.BOOLEAN_VALUE);
this.addGameRule("randomTickSpeed", "3", GameRules.ValueType.NUMERICAL_VALUE);
this.addGameRule("sendCommandFeedback", "true", GameRules.ValueType.BOOLEAN_VALUE);
this.addGameRule("reducedDebugInfo", "false", GameRules.ValueType.BOOLEAN_VALUE);
this.addGameRule("spectatorsGenerateChunks", "true", GameRules.ValueType.BOOLEAN_VALUE);
this.addGameRule("spawnRadius", "10", GameRules.ValueType.NUMERICAL_VALUE);
this.addGameRule("disableElytraMovementCheck", "false", GameRules.ValueType.BOOLEAN_VALUE);
this.addGameRule("maxEntityCramming", "24", GameRules.ValueType.NUMERICAL_VALUE);
this.addGameRule("doWeatherCycle", "true", GameRules.ValueType.BOOLEAN_VALUE);
this.addGameRule("doLimitedCrafting", "false", GameRules.ValueType.BOOLEAN_VALUE);
this.addGameRule("maxCommandChainLength", "65536", GameRules.ValueType.NUMERICAL_VALUE);
this.addGameRule("announceAdvancements", "true", GameRules.ValueType.BOOLEAN_VALUE);
this.addGameRule("gameLoopFunction", "-", GameRules.ValueType.FUNCTION);
}
public void addGameRule(String key, String value, GameRules.ValueType type)
{
this.rules.put(key, new GameRules.Value(value, type));
}
public void setOrCreateGameRule(String key, String ruleValue)
{
GameRules.Value gamerules$value = this.rules.get(key);
if (gamerules$value != null)
{
gamerules$value.setValue(ruleValue);
}
else
{
this.addGameRule(key, ruleValue, GameRules.ValueType.ANY_VALUE);
}
}
/**
* Gets the string Game Rule value.
*/
public String getString(String name)
{
GameRules.Value gamerules$value = this.rules.get(name);
return gamerules$value != null ? gamerules$value.getString() : "";
}
/**
* Gets the boolean Game Rule value.
*/
public boolean getBoolean(String name)
{
GameRules.Value gamerules$value = this.rules.get(name);
return gamerules$value != null ? gamerules$value.getBoolean() : false;
}
public int getInt(String name)
{
GameRules.Value gamerules$value = this.rules.get(name);
return gamerules$value != null ? gamerules$value.getInt() : 0;
}
/**
* Return the defined game rules as NBT.
*/
public NBTTagCompound writeToNBT()
{
NBTTagCompound nbttagcompound = new NBTTagCompound();
for (String s : this.rules.keySet())
{
GameRules.Value gamerules$value = this.rules.get(s);
nbttagcompound.setString(s, gamerules$value.getString());
}
return nbttagcompound;
}
/**
* Set defined game rules from NBT.
*/
public void readFromNBT(NBTTagCompound nbt)
{
for (String s : nbt.getKeySet())
{
this.setOrCreateGameRule(s, nbt.getString(s));
}
}
/**
* Return the defined game rules.
*/
public String[] getRules()
{
Set<String> set = this.rules.keySet();
return (String[])set.toArray(new String[set.size()]);
}
/**
* Return whether the specified game rule is defined.
*/
public boolean hasRule(String name)
{
return this.rules.containsKey(name);
}
public boolean areSameType(String key, GameRules.ValueType otherValue)
{
GameRules.Value gamerules$value = this.rules.get(key);
return gamerules$value != null && (gamerules$value.getType() == otherValue || otherValue == GameRules.ValueType.ANY_VALUE);
}
static class Value
{
private String valueString;
private boolean valueBoolean;
private int valueInteger;
private double valueDouble;
private final GameRules.ValueType type;
public Value(String value, GameRules.ValueType type)
{
this.type = type;
this.setValue(value);
}
/**
* Set this game rule value.
*/
public void setValue(String value)
{
this.valueString = value;
this.valueBoolean = Boolean.parseBoolean(value);
this.valueInteger = this.valueBoolean ? 1 : 0;
try
{
this.valueInteger = Integer.parseInt(value);
}
catch (NumberFormatException var4)
{
;
}
try
{
this.valueDouble = Double.parseDouble(value);
}
catch (NumberFormatException var3)
{
;
}
}
/**
* Gets the GameRule's value as String.
*/
public String getString()
{
return this.valueString;
}
/**
* Gets the GameRule's value as boolean.
*/
public boolean getBoolean()
{
return this.valueBoolean;
}
public int getInt()
{
return this.valueInteger;
}
public GameRules.ValueType getType()
{
return this.type;
}
}
public static enum ValueType
{
ANY_VALUE,
BOOLEAN_VALUE,
NUMERICAL_VALUE,
FUNCTION;
}
}

View File

@@ -0,0 +1,137 @@
package net.minecraft.world;
import net.minecraft.entity.player.PlayerCapabilities;
import net.minecraftforge.fml.relauncher.Side;
import net.minecraftforge.fml.relauncher.SideOnly;
public enum GameType
{
NOT_SET(-1, "", ""),
SURVIVAL(0, "survival", "s"),
CREATIVE(1, "creative", "c"),
ADVENTURE(2, "adventure", "a"),
SPECTATOR(3, "spectator", "sp");
int id;
String name;
String shortName;
private GameType(int idIn, String nameIn, String shortNameIn)
{
this.id = idIn;
this.name = nameIn;
this.shortName = shortNameIn;
}
/**
* Returns the ID of this game type
*/
public int getID()
{
return this.id;
}
/**
* Returns the name of this game type
*/
public String getName()
{
return this.name;
}
/**
* Configures the player capabilities based on the game type
*/
public void configurePlayerCapabilities(PlayerCapabilities capabilities)
{
if (this == CREATIVE)
{
capabilities.allowFlying = true;
capabilities.isCreativeMode = true;
capabilities.disableDamage = true;
}
else if (this == SPECTATOR)
{
capabilities.allowFlying = true;
capabilities.isCreativeMode = false;
capabilities.disableDamage = true;
capabilities.isFlying = true;
}
else
{
capabilities.allowFlying = false;
capabilities.isCreativeMode = false;
capabilities.disableDamage = false;
capabilities.isFlying = false;
}
capabilities.allowEdit = !this.hasLimitedInteractions();
}
/**
* Returns true if this is the ADVENTURE game type
*/
public boolean hasLimitedInteractions()
{
return this == ADVENTURE || this == SPECTATOR;
}
/**
* Returns true if this is the CREATIVE game type
*/
public boolean isCreative()
{
return this == CREATIVE;
}
/**
* Returns true if this is the SURVIVAL or ADVENTURE game type
*/
public boolean isSurvivalOrAdventure()
{
return this == SURVIVAL || this == ADVENTURE;
}
/**
* Gets the game type by it's ID. Will be survival if none was found.
*/
public static GameType getByID(int idIn)
{
return parseGameTypeWithDefault(idIn, SURVIVAL);
}
public static GameType parseGameTypeWithDefault(int targetId, GameType fallback)
{
for (GameType gametype : values())
{
if (gametype.id == targetId)
{
return gametype;
}
}
return fallback;
}
/**
* Gets the game type registered with the specified name. If no matches were found, survival will be returned.
*/
@SideOnly(Side.CLIENT)
public static GameType getByName(String gamemodeName)
{
return parseGameTypeWithDefault(gamemodeName, SURVIVAL);
}
public static GameType parseGameTypeWithDefault(String targetName, GameType fallback)
{
for (GameType gametype : values())
{
if (gametype.name.equals(targetName) || gametype.shortName.equals(targetName))
{
return gametype;
}
}
return fallback;
}
}

View File

@@ -0,0 +1,45 @@
package net.minecraft.world;
import javax.annotation.Nullable;
import net.minecraft.block.state.IBlockState;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.EnumFacing;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.biome.Biome;
import net.minecraftforge.fml.relauncher.Side;
import net.minecraftforge.fml.relauncher.SideOnly;
public interface IBlockAccess
{
@Nullable
TileEntity getTileEntity(BlockPos pos);
@SideOnly(Side.CLIENT)
int getCombinedLight(BlockPos pos, int lightValue);
IBlockState getBlockState(BlockPos pos);
/**
* Checks to see if an air block exists at the provided location. Note that this only checks to see if the blocks
* material is set to air, meaning it is possible for non-vanilla blocks to still pass this check.
*/
boolean isAirBlock(BlockPos pos);
@SideOnly(Side.CLIENT)
Biome getBiome(BlockPos pos);
int getStrongPower(BlockPos pos, EnumFacing direction);
@SideOnly(Side.CLIENT)
WorldType getWorldType();
/**
* FORGE: isSideSolid, pulled up from {@link World}
*
* @param pos Position
* @param side Side
* @param _default default return value
* @return if the block is solid on the side
*/
boolean isSideSolid(BlockPos pos, EnumFacing side, boolean _default);
}

View File

@@ -0,0 +1,12 @@
package net.minecraft.world;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.entity.player.InventoryPlayer;
import net.minecraft.inventory.Container;
public interface IInteractionObject extends IWorldNameable
{
Container createContainer(InventoryPlayer playerInventory, EntityPlayer playerIn);
String getGuiID();
}

View File

@@ -0,0 +1,12 @@
package net.minecraft.world;
import net.minecraft.inventory.IInventory;
public interface ILockableContainer extends IInventory, IInteractionObject
{
boolean isLocked();
void setLockCode(LockCode code);
LockCode getLockCode();
}

View File

@@ -0,0 +1,47 @@
package net.minecraft.world;
import javax.annotation.Nullable;
import net.minecraft.block.state.IBlockState;
import net.minecraft.entity.Entity;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.util.SoundCategory;
import net.minecraft.util.SoundEvent;
import net.minecraft.util.math.BlockPos;
public interface IWorldEventListener
{
void notifyBlockUpdate(World worldIn, BlockPos pos, IBlockState oldState, IBlockState newState, int flags);
void notifyLightSet(BlockPos pos);
/**
* On the client, re-renders all blocks in this range, inclusive. On the server, does nothing.
*/
void markBlockRangeForRenderUpdate(int x1, int y1, int z1, int x2, int y2, int z2);
void playSoundToAllNearExcept(@Nullable EntityPlayer player, SoundEvent soundIn, SoundCategory category, double x, double y, double z, float volume, float pitch);
void playRecord(SoundEvent soundIn, BlockPos pos);
void spawnParticle(int particleID, boolean ignoreRange, double xCoord, double yCoord, double zCoord, double xSpeed, double ySpeed, double zSpeed, int... parameters);
void spawnParticle(int id, boolean ignoreRange, boolean p_190570_3_, double x, double y, double z, double xSpeed, double ySpeed, double zSpeed, int... parameters);
/**
* Called on all IWorldAccesses when an entity is created or loaded. On client worlds, starts downloading any
* necessary textures. On server worlds, adds the entity to the entity tracker.
*/
void onEntityAdded(Entity entityIn);
/**
* Called on all IWorldAccesses when an entity is unloaded or destroyed. On client worlds, releases any downloaded
* textures. On server worlds, removes the entity from the entity tracker.
*/
void onEntityRemoved(Entity entityIn);
void broadcastSound(int soundID, BlockPos pos, int data);
void playEvent(EntityPlayer player, int type, BlockPos blockPosIn, int data);
void sendBlockBreakProgress(int breakerId, BlockPos pos, int progress);
}

View File

@@ -0,0 +1,21 @@
package net.minecraft.world;
import net.minecraft.util.text.ITextComponent;
public interface IWorldNameable
{
/**
* Get the name of this object. For players this returns their username
*/
String getName();
/**
* Returns true if this thing is named
*/
boolean hasCustomName();
/**
* Get the formatted ChatComponent that will be used for the sender's username in chat
*/
ITextComponent getDisplayName();
}

View File

@@ -0,0 +1,44 @@
package net.minecraft.world;
import javax.annotation.concurrent.Immutable;
import net.minecraft.nbt.NBTTagCompound;
@Immutable
public class LockCode
{
public static final LockCode EMPTY_CODE = new LockCode("");
private final String lock;
public LockCode(String code)
{
this.lock = code;
}
public boolean isEmpty()
{
return this.lock == null || this.lock.isEmpty();
}
public String getLock()
{
return this.lock;
}
public void toNBT(NBTTagCompound nbt)
{
nbt.setString("Lock", this.lock);
}
public static LockCode fromNBT(NBTTagCompound nbt)
{
if (nbt.hasKey("Lock", 8))
{
String s = nbt.getString("Lock");
return new LockCode(s);
}
else
{
return EMPTY_CODE;
}
}
}

View File

@@ -0,0 +1,9 @@
package net.minecraft.world;
public class MinecraftException extends Exception
{
public MinecraftException(String msg)
{
super(msg);
}
}

View File

@@ -0,0 +1,90 @@
package net.minecraft.world;
import net.minecraft.block.Block;
import net.minecraft.util.math.BlockPos;
public class NextTickListEntry implements Comparable<NextTickListEntry>
{
/** The id number for the next tick entry */
private static long nextTickEntryID;
private final Block block;
public final BlockPos position;
/** Time this tick is scheduled to occur at */
public long scheduledTime;
public int priority;
/** The id of the tick entry */
private final long tickEntryID;
public NextTickListEntry(BlockPos positionIn, Block blockIn)
{
this.tickEntryID = (long)(nextTickEntryID++);
this.position = positionIn.toImmutable();
this.block = blockIn;
}
public boolean equals(Object p_equals_1_)
{
if (!(p_equals_1_ instanceof NextTickListEntry))
{
return false;
}
else
{
NextTickListEntry nextticklistentry = (NextTickListEntry)p_equals_1_;
return this.position.equals(nextticklistentry.position) && Block.isEqualTo(this.block, nextticklistentry.block);
}
}
public int hashCode()
{
return this.position.hashCode();
}
/**
* Sets the scheduled time for this tick entry
*/
public NextTickListEntry setScheduledTime(long scheduledTimeIn)
{
this.scheduledTime = scheduledTimeIn;
return this;
}
public void setPriority(int priorityIn)
{
this.priority = priorityIn;
}
public int compareTo(NextTickListEntry p_compareTo_1_)
{
if (this.scheduledTime < p_compareTo_1_.scheduledTime)
{
return -1;
}
else if (this.scheduledTime > p_compareTo_1_.scheduledTime)
{
return 1;
}
else if (this.priority != p_compareTo_1_.priority)
{
return this.priority - p_compareTo_1_.priority;
}
else if (this.tickEntryID < p_compareTo_1_.tickEntryID)
{
return -1;
}
else
{
return this.tickEntryID > p_compareTo_1_.tickEntryID ? 1 : 0;
}
}
public String toString()
{
return Block.getIdFromBlock(this.block) + ": " + this.position + ", " + this.scheduledTime + ", " + this.priority + ", " + this.tickEntryID;
}
public Block getBlock()
{
return this.block;
}
}

View File

@@ -0,0 +1,118 @@
package net.minecraft.world;
import javax.annotation.Nullable;
import net.minecraft.block.state.IBlockState;
import net.minecraft.entity.Entity;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.entity.player.EntityPlayerMP;
import net.minecraft.network.play.server.SPacketBlockBreakAnim;
import net.minecraft.network.play.server.SPacketEffect;
import net.minecraft.network.play.server.SPacketSoundEffect;
import net.minecraft.server.MinecraftServer;
import net.minecraft.util.SoundCategory;
import net.minecraft.util.SoundEvent;
import net.minecraft.util.math.BlockPos;
public class ServerWorldEventHandler implements IWorldEventListener
{
/** Reference to the MinecraftServer object. */
private final MinecraftServer mcServer;
/** The WorldServer object. */
private final WorldServer world;
public ServerWorldEventHandler(MinecraftServer mcServerIn, WorldServer worldServerIn)
{
this.mcServer = mcServerIn;
this.world = worldServerIn;
}
public void spawnParticle(int particleID, boolean ignoreRange, double xCoord, double yCoord, double zCoord, double xSpeed, double ySpeed, double zSpeed, int... parameters)
{
}
public void spawnParticle(int id, boolean ignoreRange, boolean p_190570_3_, double x, double y, double z, double xSpeed, double ySpeed, double zSpeed, int... parameters)
{
}
/**
* Called on all IWorldAccesses when an entity is created or loaded. On client worlds, starts downloading any
* necessary textures. On server worlds, adds the entity to the entity tracker.
*/
public void onEntityAdded(Entity entityIn)
{
this.world.getEntityTracker().track(entityIn);
if (entityIn instanceof EntityPlayerMP)
{
this.world.provider.onPlayerAdded((EntityPlayerMP)entityIn);
}
}
/**
* Called on all IWorldAccesses when an entity is unloaded or destroyed. On client worlds, releases any downloaded
* textures. On server worlds, removes the entity from the entity tracker.
*/
public void onEntityRemoved(Entity entityIn)
{
this.world.getEntityTracker().untrack(entityIn);
this.world.getScoreboard().removeEntity(entityIn);
if (entityIn instanceof EntityPlayerMP)
{
this.world.provider.onPlayerRemoved((EntityPlayerMP)entityIn);
}
}
public void playSoundToAllNearExcept(@Nullable EntityPlayer player, SoundEvent soundIn, SoundCategory category, double x, double y, double z, float volume, float pitch)
{
this.mcServer.getPlayerList().sendToAllNearExcept(player, x, y, z, volume > 1.0F ? (double)(16.0F * volume) : 16.0D, this.world.provider.getDimension(), new SPacketSoundEffect(soundIn, category, x, y, z, volume, pitch));
}
/**
* On the client, re-renders all blocks in this range, inclusive. On the server, does nothing.
*/
public void markBlockRangeForRenderUpdate(int x1, int y1, int z1, int x2, int y2, int z2)
{
}
public void notifyBlockUpdate(World worldIn, BlockPos pos, IBlockState oldState, IBlockState newState, int flags)
{
this.world.getPlayerChunkMap().markBlockForUpdate(pos);
}
public void notifyLightSet(BlockPos pos)
{
}
public void playRecord(SoundEvent soundIn, BlockPos pos)
{
}
public void playEvent(EntityPlayer player, int type, BlockPos blockPosIn, int data)
{
this.mcServer.getPlayerList().sendToAllNearExcept(player, (double)blockPosIn.getX(), (double)blockPosIn.getY(), (double)blockPosIn.getZ(), 64.0D, this.world.provider.getDimension(), new SPacketEffect(type, blockPosIn, data, false));
}
public void broadcastSound(int soundID, BlockPos pos, int data)
{
this.mcServer.getPlayerList().sendPacketToAllPlayers(new SPacketEffect(soundID, pos, data, true));
}
public void sendBlockBreakProgress(int breakerId, BlockPos pos, int progress)
{
for (EntityPlayerMP entityplayermp : this.mcServer.getPlayerList().getPlayers())
{
if (entityplayermp != null && entityplayermp.world == this.world && entityplayermp.getEntityId() != breakerId)
{
double d0 = (double)pos.getX() - entityplayermp.posX;
double d1 = (double)pos.getY() - entityplayermp.posY;
double d2 = (double)pos.getZ() - entityplayermp.posZ;
if (d0 * d0 + d1 * d1 + d2 * d2 < 1024.0D)
{
entityplayermp.connection.sendPacket(new SPacketBlockBreakAnim(breakerId, pos, progress));
}
}
}
}
}

View File

@@ -0,0 +1,447 @@
package net.minecraft.world;
import it.unimi.dsi.fastutil.longs.Long2ObjectMap;
import it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap;
import it.unimi.dsi.fastutil.objects.ObjectIterator;
import java.util.Random;
import net.minecraft.block.BlockPortal;
import net.minecraft.block.state.IBlockState;
import net.minecraft.block.state.pattern.BlockPattern;
import net.minecraft.entity.Entity;
import net.minecraft.entity.player.EntityPlayerMP;
import net.minecraft.init.Blocks;
import net.minecraft.util.EnumFacing;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.ChunkPos;
import net.minecraft.util.math.MathHelper;
public class Teleporter implements net.minecraftforge.common.util.ITeleporter
{
protected final WorldServer world;
/** A private Random() function in Teleporter */
protected final Random random;
/** Stores successful portal placement locations for rapid lookup. */
protected final Long2ObjectMap<Teleporter.PortalPosition> destinationCoordinateCache = new Long2ObjectOpenHashMap<Teleporter.PortalPosition>(4096);
public Teleporter(WorldServer worldIn)
{
this.world = worldIn;
this.random = new Random(worldIn.getSeed());
}
public void placeInPortal(Entity entityIn, float rotationYaw)
{
if (this.world.provider.getDimensionType().getId() != 1)
{
if (!this.placeInExistingPortal(entityIn, rotationYaw))
{
this.makePortal(entityIn);
this.placeInExistingPortal(entityIn, rotationYaw);
}
}
else
{
int i = MathHelper.floor(entityIn.posX);
int j = MathHelper.floor(entityIn.posY) - 1;
int k = MathHelper.floor(entityIn.posZ);
int l = 1;
int i1 = 0;
for (int j1 = -2; j1 <= 2; ++j1)
{
for (int k1 = -2; k1 <= 2; ++k1)
{
for (int l1 = -1; l1 < 3; ++l1)
{
int i2 = i + k1 * 1 + j1 * 0;
int j2 = j + l1;
int k2 = k + k1 * 0 - j1 * 1;
boolean flag = l1 < 0;
this.world.setBlockState(new BlockPos(i2, j2, k2), flag ? Blocks.OBSIDIAN.getDefaultState() : Blocks.AIR.getDefaultState());
}
}
}
entityIn.setLocationAndAngles((double)i, (double)j, (double)k, entityIn.rotationYaw, 0.0F);
entityIn.motionX = 0.0D;
entityIn.motionY = 0.0D;
entityIn.motionZ = 0.0D;
}
}
public boolean placeInExistingPortal(Entity entityIn, float rotationYaw)
{
int i = 128;
double d0 = -1.0D;
int j = MathHelper.floor(entityIn.posX);
int k = MathHelper.floor(entityIn.posZ);
boolean flag = true;
BlockPos blockpos = BlockPos.ORIGIN;
long l = ChunkPos.asLong(j, k);
if (this.destinationCoordinateCache.containsKey(l))
{
Teleporter.PortalPosition teleporter$portalposition = (Teleporter.PortalPosition)this.destinationCoordinateCache.get(l);
d0 = 0.0D;
blockpos = teleporter$portalposition;
teleporter$portalposition.lastUpdateTime = this.world.getTotalWorldTime();
flag = false;
}
else
{
BlockPos blockpos3 = new BlockPos(entityIn);
for (int i1 = -128; i1 <= 128; ++i1)
{
BlockPos blockpos2;
for (int j1 = -128; j1 <= 128; ++j1)
{
for (BlockPos blockpos1 = blockpos3.add(i1, this.world.getActualHeight() - 1 - blockpos3.getY(), j1); blockpos1.getY() >= 0; blockpos1 = blockpos2)
{
blockpos2 = blockpos1.down();
if (this.world.getBlockState(blockpos1).getBlock() == Blocks.PORTAL)
{
for (blockpos2 = blockpos1.down(); this.world.getBlockState(blockpos2).getBlock() == Blocks.PORTAL; blockpos2 = blockpos2.down())
{
blockpos1 = blockpos2;
}
double d1 = blockpos1.distanceSq(blockpos3);
if (d0 < 0.0D || d1 < d0)
{
d0 = d1;
blockpos = blockpos1;
}
}
}
}
}
}
if (d0 >= 0.0D)
{
if (flag)
{
this.destinationCoordinateCache.put(l, new Teleporter.PortalPosition(blockpos, this.world.getTotalWorldTime()));
}
double d5 = (double)blockpos.getX() + 0.5D;
double d7 = (double)blockpos.getZ() + 0.5D;
BlockPattern.PatternHelper blockpattern$patternhelper = Blocks.PORTAL.createPatternHelper(this.world, blockpos);
boolean flag1 = blockpattern$patternhelper.getForwards().rotateY().getAxisDirection() == EnumFacing.AxisDirection.NEGATIVE;
double d2 = blockpattern$patternhelper.getForwards().getAxis() == EnumFacing.Axis.X ? (double)blockpattern$patternhelper.getFrontTopLeft().getZ() : (double)blockpattern$patternhelper.getFrontTopLeft().getX();
double d6 = (double)(blockpattern$patternhelper.getFrontTopLeft().getY() + 1) - entityIn.getLastPortalVec().y * (double)blockpattern$patternhelper.getHeight();
if (flag1)
{
++d2;
}
if (blockpattern$patternhelper.getForwards().getAxis() == EnumFacing.Axis.X)
{
d7 = d2 + (1.0D - entityIn.getLastPortalVec().x) * (double)blockpattern$patternhelper.getWidth() * (double)blockpattern$patternhelper.getForwards().rotateY().getAxisDirection().getOffset();
}
else
{
d5 = d2 + (1.0D - entityIn.getLastPortalVec().x) * (double)blockpattern$patternhelper.getWidth() * (double)blockpattern$patternhelper.getForwards().rotateY().getAxisDirection().getOffset();
}
float f = 0.0F;
float f1 = 0.0F;
float f2 = 0.0F;
float f3 = 0.0F;
if (blockpattern$patternhelper.getForwards().getOpposite() == entityIn.getTeleportDirection())
{
f = 1.0F;
f1 = 1.0F;
}
else if (blockpattern$patternhelper.getForwards().getOpposite() == entityIn.getTeleportDirection().getOpposite())
{
f = -1.0F;
f1 = -1.0F;
}
else if (blockpattern$patternhelper.getForwards().getOpposite() == entityIn.getTeleportDirection().rotateY())
{
f2 = 1.0F;
f3 = -1.0F;
}
else
{
f2 = -1.0F;
f3 = 1.0F;
}
double d3 = entityIn.motionX;
double d4 = entityIn.motionZ;
entityIn.motionX = d3 * (double)f + d4 * (double)f3;
entityIn.motionZ = d3 * (double)f2 + d4 * (double)f1;
entityIn.rotationYaw = rotationYaw - (float)(entityIn.getTeleportDirection().getOpposite().getHorizontalIndex() * 90) + (float)(blockpattern$patternhelper.getForwards().getHorizontalIndex() * 90);
if (entityIn instanceof EntityPlayerMP)
{
((EntityPlayerMP)entityIn).connection.setPlayerLocation(d5, d6, d7, entityIn.rotationYaw, entityIn.rotationPitch);
}
else
{
entityIn.setLocationAndAngles(d5, d6, d7, entityIn.rotationYaw, entityIn.rotationPitch);
}
return true;
}
else
{
return false;
}
}
public boolean makePortal(Entity entityIn)
{
int i = 16;
double d0 = -1.0D;
int j = MathHelper.floor(entityIn.posX);
int k = MathHelper.floor(entityIn.posY);
int l = MathHelper.floor(entityIn.posZ);
int i1 = j;
int j1 = k;
int k1 = l;
int l1 = 0;
int i2 = this.random.nextInt(4);
BlockPos.MutableBlockPos blockpos$mutableblockpos = new BlockPos.MutableBlockPos();
for (int j2 = j - 16; j2 <= j + 16; ++j2)
{
double d1 = (double)j2 + 0.5D - entityIn.posX;
for (int l2 = l - 16; l2 <= l + 16; ++l2)
{
double d2 = (double)l2 + 0.5D - entityIn.posZ;
label293:
for (int j3 = this.world.getActualHeight() - 1; j3 >= 0; --j3)
{
if (this.world.isAirBlock(blockpos$mutableblockpos.setPos(j2, j3, l2)))
{
while (j3 > 0 && this.world.isAirBlock(blockpos$mutableblockpos.setPos(j2, j3 - 1, l2)))
{
--j3;
}
for (int k3 = i2; k3 < i2 + 4; ++k3)
{
int l3 = k3 % 2;
int i4 = 1 - l3;
if (k3 % 4 >= 2)
{
l3 = -l3;
i4 = -i4;
}
for (int j4 = 0; j4 < 3; ++j4)
{
for (int k4 = 0; k4 < 4; ++k4)
{
for (int l4 = -1; l4 < 4; ++l4)
{
int i5 = j2 + (k4 - 1) * l3 + j4 * i4;
int j5 = j3 + l4;
int k5 = l2 + (k4 - 1) * i4 - j4 * l3;
blockpos$mutableblockpos.setPos(i5, j5, k5);
if (l4 < 0 && !this.world.getBlockState(blockpos$mutableblockpos).getMaterial().isSolid() || l4 >= 0 && !this.world.isAirBlock(blockpos$mutableblockpos))
{
continue label293;
}
}
}
}
double d5 = (double)j3 + 0.5D - entityIn.posY;
double d7 = d1 * d1 + d5 * d5 + d2 * d2;
if (d0 < 0.0D || d7 < d0)
{
d0 = d7;
i1 = j2;
j1 = j3;
k1 = l2;
l1 = k3 % 4;
}
}
}
}
}
}
if (d0 < 0.0D)
{
for (int l5 = j - 16; l5 <= j + 16; ++l5)
{
double d3 = (double)l5 + 0.5D - entityIn.posX;
for (int j6 = l - 16; j6 <= l + 16; ++j6)
{
double d4 = (double)j6 + 0.5D - entityIn.posZ;
label231:
for (int i7 = this.world.getActualHeight() - 1; i7 >= 0; --i7)
{
if (this.world.isAirBlock(blockpos$mutableblockpos.setPos(l5, i7, j6)))
{
while (i7 > 0 && this.world.isAirBlock(blockpos$mutableblockpos.setPos(l5, i7 - 1, j6)))
{
--i7;
}
for (int k7 = i2; k7 < i2 + 2; ++k7)
{
int j8 = k7 % 2;
int j9 = 1 - j8;
for (int j10 = 0; j10 < 4; ++j10)
{
for (int j11 = -1; j11 < 4; ++j11)
{
int j12 = l5 + (j10 - 1) * j8;
int i13 = i7 + j11;
int j13 = j6 + (j10 - 1) * j9;
blockpos$mutableblockpos.setPos(j12, i13, j13);
if (j11 < 0 && !this.world.getBlockState(blockpos$mutableblockpos).getMaterial().isSolid() || j11 >= 0 && !this.world.isAirBlock(blockpos$mutableblockpos))
{
continue label231;
}
}
}
double d6 = (double)i7 + 0.5D - entityIn.posY;
double d8 = d3 * d3 + d6 * d6 + d4 * d4;
if (d0 < 0.0D || d8 < d0)
{
d0 = d8;
i1 = l5;
j1 = i7;
k1 = j6;
l1 = k7 % 2;
}
}
}
}
}
}
}
int i6 = i1;
int k2 = j1;
int k6 = k1;
int l6 = l1 % 2;
int i3 = 1 - l6;
if (l1 % 4 >= 2)
{
l6 = -l6;
i3 = -i3;
}
if (d0 < 0.0D)
{
j1 = MathHelper.clamp(j1, 70, this.world.getActualHeight() - 10);
k2 = j1;
for (int j7 = -1; j7 <= 1; ++j7)
{
for (int l7 = 1; l7 < 3; ++l7)
{
for (int k8 = -1; k8 < 3; ++k8)
{
int k9 = i6 + (l7 - 1) * l6 + j7 * i3;
int k10 = k2 + k8;
int k11 = k6 + (l7 - 1) * i3 - j7 * l6;
boolean flag = k8 < 0;
this.world.setBlockState(new BlockPos(k9, k10, k11), flag ? Blocks.OBSIDIAN.getDefaultState() : Blocks.AIR.getDefaultState());
}
}
}
}
IBlockState iblockstate = Blocks.PORTAL.getDefaultState().withProperty(BlockPortal.AXIS, l6 == 0 ? EnumFacing.Axis.Z : EnumFacing.Axis.X);
for (int i8 = 0; i8 < 4; ++i8)
{
for (int l8 = 0; l8 < 4; ++l8)
{
for (int l9 = -1; l9 < 4; ++l9)
{
int l10 = i6 + (l8 - 1) * l6;
int l11 = k2 + l9;
int k12 = k6 + (l8 - 1) * i3;
boolean flag1 = l8 == 0 || l8 == 3 || l9 == -1 || l9 == 3;
this.world.setBlockState(new BlockPos(l10, l11, k12), flag1 ? Blocks.OBSIDIAN.getDefaultState() : iblockstate, 2);
}
}
for (int i9 = 0; i9 < 4; ++i9)
{
for (int i10 = -1; i10 < 4; ++i10)
{
int i11 = i6 + (i9 - 1) * l6;
int i12 = k2 + i10;
int l12 = k6 + (i9 - 1) * i3;
BlockPos blockpos = new BlockPos(i11, i12, l12);
this.world.notifyNeighborsOfStateChange(blockpos, this.world.getBlockState(blockpos).getBlock(), false);
}
}
}
return true;
}
/**
* called periodically to remove out-of-date portal locations from the cache list. Argument par1 is a
* WorldServer.getTotalWorldTime() value.
*/
public void removeStalePortalLocations(long worldTime)
{
if (worldTime % 100L == 0L)
{
long i = worldTime - 300L;
ObjectIterator<Teleporter.PortalPosition> objectiterator = this.destinationCoordinateCache.values().iterator();
while (objectiterator.hasNext())
{
Teleporter.PortalPosition teleporter$portalposition = (Teleporter.PortalPosition)objectiterator.next();
if (teleporter$portalposition == null || teleporter$portalposition.lastUpdateTime < i)
{
objectiterator.remove();
}
}
}
}
public class PortalPosition extends BlockPos
{
/** The worldtime at which this PortalPosition was last verified */
public long lastUpdateTime;
public PortalPosition(BlockPos pos, long lastUpdate)
{
super(pos.getX(), pos.getY(), pos.getZ());
this.lastUpdateTime = lastUpdate;
}
}
@Override
public void placeEntity(World world, Entity entity, float yaw)
{
if (entity instanceof EntityPlayerMP)
placeInPortal(entity, yaw);
else
placeInExistingPortal(entity, yaw);
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,327 @@
package net.minecraft.world;
import com.google.common.collect.Sets;
import java.util.List;
import java.util.Random;
import java.util.Set;
import net.minecraft.block.Block;
import net.minecraft.block.BlockRailBase;
import net.minecraft.block.material.Material;
import net.minecraft.block.state.IBlockState;
import net.minecraft.entity.EntityLiving;
import net.minecraft.entity.EntitySpawnPlacementRegistry;
import net.minecraft.entity.EnumCreatureType;
import net.minecraft.entity.IEntityLivingData;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.init.Blocks;
import net.minecraft.server.management.PlayerChunkMapEntry;
import net.minecraft.util.WeightedRandom;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.ChunkPos;
import net.minecraft.util.math.MathHelper;
import net.minecraft.world.biome.Biome;
import net.minecraft.world.chunk.Chunk;
public final class WorldEntitySpawner
{
private static final int MOB_COUNT_DIV = (int)Math.pow(17.0D, 2.0D);
/** The 17x17 area around the player where mobs can spawn */
private final Set<ChunkPos> eligibleChunksForSpawning = Sets.<ChunkPos>newHashSet();
/**
* adds all chunks within the spawn radius of the players to eligibleChunksForSpawning. pars: the world,
* hostileCreatures, passiveCreatures. returns number of eligible chunks.
*/
public int findChunksForSpawning(WorldServer worldServerIn, boolean spawnHostileMobs, boolean spawnPeacefulMobs, boolean spawnOnSetTickRate)
{
if (!spawnHostileMobs && !spawnPeacefulMobs)
{
return 0;
}
else
{
this.eligibleChunksForSpawning.clear();
int i = 0;
for (EntityPlayer entityplayer : worldServerIn.playerEntities)
{
if (!entityplayer.isSpectator())
{
int j = MathHelper.floor(entityplayer.posX / 16.0D);
int k = MathHelper.floor(entityplayer.posZ / 16.0D);
int l = 8;
for (int i1 = -8; i1 <= 8; ++i1)
{
for (int j1 = -8; j1 <= 8; ++j1)
{
boolean flag = i1 == -8 || i1 == 8 || j1 == -8 || j1 == 8;
ChunkPos chunkpos = new ChunkPos(i1 + j, j1 + k);
if (!this.eligibleChunksForSpawning.contains(chunkpos))
{
++i;
if (!flag && worldServerIn.getWorldBorder().contains(chunkpos))
{
PlayerChunkMapEntry playerchunkmapentry = worldServerIn.getPlayerChunkMap().getEntry(chunkpos.x, chunkpos.z);
if (playerchunkmapentry != null && playerchunkmapentry.isSentToPlayers())
{
this.eligibleChunksForSpawning.add(chunkpos);
}
}
}
}
}
}
}
int j4 = 0;
BlockPos blockpos1 = worldServerIn.getSpawnPoint();
for (EnumCreatureType enumcreaturetype : EnumCreatureType.values())
{
if ((!enumcreaturetype.getPeacefulCreature() || spawnPeacefulMobs) && (enumcreaturetype.getPeacefulCreature() || spawnHostileMobs) && (!enumcreaturetype.getAnimal() || spawnOnSetTickRate))
{
int k4 = worldServerIn.countEntities(enumcreaturetype, true);
int l4 = enumcreaturetype.getMaxNumberOfCreature() * i / MOB_COUNT_DIV;
if (k4 <= l4)
{
java.util.ArrayList<ChunkPos> shuffled = com.google.common.collect.Lists.newArrayList(this.eligibleChunksForSpawning);
java.util.Collections.shuffle(shuffled);
BlockPos.MutableBlockPos blockpos$mutableblockpos = new BlockPos.MutableBlockPos();
label134:
for (ChunkPos chunkpos1 : shuffled)
{
BlockPos blockpos = getRandomChunkPosition(worldServerIn, chunkpos1.x, chunkpos1.z);
int k1 = blockpos.getX();
int l1 = blockpos.getY();
int i2 = blockpos.getZ();
IBlockState iblockstate = worldServerIn.getBlockState(blockpos);
if (!iblockstate.isNormalCube())
{
int j2 = 0;
for (int k2 = 0; k2 < 3; ++k2)
{
int l2 = k1;
int i3 = l1;
int j3 = i2;
int k3 = 6;
Biome.SpawnListEntry biome$spawnlistentry = null;
IEntityLivingData ientitylivingdata = null;
int l3 = MathHelper.ceil(Math.random() * 4.0D);
for (int i4 = 0; i4 < l3; ++i4)
{
l2 += worldServerIn.rand.nextInt(6) - worldServerIn.rand.nextInt(6);
i3 += worldServerIn.rand.nextInt(1) - worldServerIn.rand.nextInt(1);
j3 += worldServerIn.rand.nextInt(6) - worldServerIn.rand.nextInt(6);
blockpos$mutableblockpos.setPos(l2, i3, j3);
float f = (float)l2 + 0.5F;
float f1 = (float)j3 + 0.5F;
if (!worldServerIn.isAnyPlayerWithinRangeAt((double)f, (double)i3, (double)f1, 24.0D) && blockpos1.distanceSq((double)f, (double)i3, (double)f1) >= 576.0D)
{
if (biome$spawnlistentry == null)
{
biome$spawnlistentry = worldServerIn.getSpawnListEntryForTypeAt(enumcreaturetype, blockpos$mutableblockpos);
if (biome$spawnlistentry == null)
{
break;
}
}
if (worldServerIn.canCreatureTypeSpawnHere(enumcreaturetype, biome$spawnlistentry, blockpos$mutableblockpos) && canCreatureTypeSpawnAtLocation(EntitySpawnPlacementRegistry.getPlacementForEntity(biome$spawnlistentry.entityClass), worldServerIn, blockpos$mutableblockpos))
{
EntityLiving entityliving;
try
{
entityliving = biome$spawnlistentry.newInstance(worldServerIn);
}
catch (Exception exception)
{
exception.printStackTrace();
return j4;
}
entityliving.setLocationAndAngles((double)f, (double)i3, (double)f1, worldServerIn.rand.nextFloat() * 360.0F, 0.0F);
net.minecraftforge.fml.common.eventhandler.Event.Result canSpawn = net.minecraftforge.event.ForgeEventFactory.canEntitySpawn(entityliving, worldServerIn, f, i3, f1, false);
if (canSpawn == net.minecraftforge.fml.common.eventhandler.Event.Result.ALLOW || (canSpawn == net.minecraftforge.fml.common.eventhandler.Event.Result.DEFAULT && (entityliving.getCanSpawnHere() && entityliving.isNotColliding())))
{
if (!net.minecraftforge.event.ForgeEventFactory.doSpecialSpawn(entityliving, worldServerIn, f, i3, f1))
ientitylivingdata = entityliving.onInitialSpawn(worldServerIn.getDifficultyForLocation(new BlockPos(entityliving)), ientitylivingdata);
if (entityliving.isNotColliding())
{
++j2;
worldServerIn.spawnEntity(entityliving);
}
else
{
entityliving.setDead();
}
if (j2 >= net.minecraftforge.event.ForgeEventFactory.getMaxSpawnPackSize(entityliving))
{
continue label134;
}
}
j4 += j2;
}
}
}
}
}
}
}
}
}
return j4;
}
}
private static BlockPos getRandomChunkPosition(World worldIn, int x, int z)
{
Chunk chunk = worldIn.getChunkFromChunkCoords(x, z);
int i = x * 16 + worldIn.rand.nextInt(16);
int j = z * 16 + worldIn.rand.nextInt(16);
int k = MathHelper.roundUp(chunk.getHeight(new BlockPos(i, 0, j)) + 1, 16);
int l = worldIn.rand.nextInt(k > 0 ? k : chunk.getTopFilledSegment() + 16 - 1);
return new BlockPos(i, l, j);
}
public static boolean isValidEmptySpawnBlock(IBlockState state)
{
if (state.isBlockNormalCube())
{
return false;
}
else if (state.canProvidePower())
{
return false;
}
else if (state.getMaterial().isLiquid())
{
return false;
}
else
{
return !BlockRailBase.isRailBlock(state);
}
}
public static boolean canCreatureTypeSpawnAtLocation(EntityLiving.SpawnPlacementType spawnPlacementTypeIn, World worldIn, BlockPos pos)
{
if (!worldIn.getWorldBorder().contains(pos))
{
return false;
}
else
{
return spawnPlacementTypeIn.canSpawnAt(worldIn, pos);
}
}
public static boolean canCreatureTypeSpawnBody(EntityLiving.SpawnPlacementType spawnPlacementTypeIn, World worldIn, BlockPos pos)
{
{
IBlockState iblockstate = worldIn.getBlockState(pos);
if (spawnPlacementTypeIn == EntityLiving.SpawnPlacementType.IN_WATER)
{
return iblockstate.getMaterial() == Material.WATER && worldIn.getBlockState(pos.down()).getMaterial() == Material.WATER && !worldIn.getBlockState(pos.up()).isNormalCube();
}
else
{
BlockPos blockpos = pos.down();
IBlockState state = worldIn.getBlockState(blockpos);
if (!state.getBlock().canCreatureSpawn(state, worldIn, blockpos, spawnPlacementTypeIn))
{
return false;
}
else
{
Block block = worldIn.getBlockState(blockpos).getBlock();
boolean flag = block != Blocks.BEDROCK && block != Blocks.BARRIER;
return flag && isValidEmptySpawnBlock(iblockstate) && isValidEmptySpawnBlock(worldIn.getBlockState(pos.up()));
}
}
}
}
/**
* Called during chunk generation to spawn initial creatures.
*
* @param centerX The X coordinate of the point to spawn mobs arround.
* @param centerZ The Z coordinate of the point to spawn mobs arround.
* @param diameterX The X diameter of the rectangle to spawn mobs in
* @param diameterZ The Z diameter of the rectangle to spawn mobs in
*/
public static void performWorldGenSpawning(World worldIn, Biome biomeIn, int centerX, int centerZ, int diameterX, int diameterZ, Random randomIn)
{
List<Biome.SpawnListEntry> list = biomeIn.getSpawnableList(EnumCreatureType.CREATURE);
if (!list.isEmpty())
{
while (randomIn.nextFloat() < biomeIn.getSpawningChance())
{
Biome.SpawnListEntry biome$spawnlistentry = (Biome.SpawnListEntry)WeightedRandom.getRandomItem(worldIn.rand, list);
int i = biome$spawnlistentry.minGroupCount + randomIn.nextInt(1 + biome$spawnlistentry.maxGroupCount - biome$spawnlistentry.minGroupCount);
IEntityLivingData ientitylivingdata = null;
int j = centerX + randomIn.nextInt(diameterX);
int k = centerZ + randomIn.nextInt(diameterZ);
int l = j;
int i1 = k;
for (int j1 = 0; j1 < i; ++j1)
{
boolean flag = false;
for (int k1 = 0; !flag && k1 < 4; ++k1)
{
BlockPos blockpos = worldIn.getTopSolidOrLiquidBlock(new BlockPos(j, 0, k));
if (canCreatureTypeSpawnAtLocation(EntityLiving.SpawnPlacementType.ON_GROUND, worldIn, blockpos))
{
EntityLiving entityliving;
try
{
entityliving = biome$spawnlistentry.newInstance(worldIn);
}
catch (Exception exception)
{
exception.printStackTrace();
continue;
}
if (net.minecraftforge.event.ForgeEventFactory.canEntitySpawn(entityliving, worldIn, j + 0.5f, (float) blockpos.getY(), k +0.5f, false) == net.minecraftforge.fml.common.eventhandler.Event.Result.DENY) continue;
entityliving.setLocationAndAngles((double)((float)j + 0.5F), (double)blockpos.getY(), (double)((float)k + 0.5F), randomIn.nextFloat() * 360.0F, 0.0F);
worldIn.spawnEntity(entityliving);
ientitylivingdata = entityliving.onInitialSpawn(worldIn.getDifficultyForLocation(new BlockPos(entityliving)), ientitylivingdata);
flag = true;
}
j += randomIn.nextInt(5) - randomIn.nextInt(5);
for (k += randomIn.nextInt(5) - randomIn.nextInt(5); j < centerX || j >= centerX + diameterX || k < centerZ || k >= centerZ + diameterX; k = i1 + randomIn.nextInt(5) - randomIn.nextInt(5))
{
j = l + randomIn.nextInt(5) - randomIn.nextInt(5);
}
}
}
}
}
}
}

View File

@@ -0,0 +1,676 @@
package net.minecraft.world;
import javax.annotation.Nullable;
import net.minecraft.entity.player.EntityPlayerMP;
import net.minecraft.init.Biomes;
import net.minecraft.init.Blocks;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.MathHelper;
import net.minecraft.util.math.Vec3d;
import net.minecraft.world.biome.Biome;
import net.minecraft.world.biome.BiomeProvider;
import net.minecraft.world.biome.BiomeProviderSingle;
import net.minecraft.world.border.WorldBorder;
import net.minecraft.world.gen.ChunkGeneratorDebug;
import net.minecraft.world.gen.ChunkGeneratorFlat;
import net.minecraft.world.gen.ChunkGeneratorOverworld;
import net.minecraft.world.gen.FlatGeneratorInfo;
import net.minecraft.world.gen.IChunkGenerator;
import net.minecraftforge.fml.relauncher.Side;
import net.minecraftforge.fml.relauncher.SideOnly;
public abstract class WorldProvider
{
public static final float[] MOON_PHASE_FACTORS = new float[] {1.0F, 0.75F, 0.5F, 0.25F, 0.0F, 0.25F, 0.5F, 0.75F};
/** world object being used */
protected World world;
private WorldType terrainType;
private String generatorSettings;
/** World chunk manager being used to generate chunks */
protected BiomeProvider biomeProvider;
/** States whether the Hell world provider is used(true) or if the normal world provider is used(false) */
protected boolean doesWaterVaporize;
/**
* Whether this dimension should be treated as the nether.
*
* @see <a href="https://github.com/ModCoderPack/MCPBot-Issues/issues/330">https://github.com/ModCoderPack/MCPBot-
* Issues/issues/330</a>
*/
protected boolean nether;
protected boolean hasSkyLight;
/** Light to brightness conversion table */
protected final float[] lightBrightnessTable = new float[16];
/** Array for sunrise/sunset colors (RGBA) */
private final float[] colorsSunriseSunset = new float[4];
/**
* associate an existing world with a World provider, and setup its lightbrightness table
*/
public final void setWorld(World worldIn)
{
this.world = worldIn;
this.terrainType = worldIn.getWorldInfo().getTerrainType();
this.generatorSettings = worldIn.getWorldInfo().getGeneratorOptions();
this.init();
this.generateLightBrightnessTable();
}
/**
* Creates the light to brightness table
*/
protected void generateLightBrightnessTable()
{
float f = 0.0F;
for (int i = 0; i <= 15; ++i)
{
float f1 = 1.0F - (float)i / 15.0F;
this.lightBrightnessTable[i] = (1.0F - f1) / (f1 * 3.0F + 1.0F) * 1.0F + 0.0F;
}
}
/**
* Creates a new {@link BiomeProvider} for the WorldProvider, and also sets the values of {@link #hasSkylight} and
* {@link #hasNoSky} appropriately.
*
* Note that subclasses generally override this method without calling the parent version.
*/
protected void init()
{
this.hasSkyLight = true;
this.biomeProvider = this.terrainType.getBiomeProvider(world);
}
public IChunkGenerator createChunkGenerator()
{
return this.terrainType.getChunkGenerator(world, generatorSettings);
}
/**
* Will check if the x, z position specified is alright to be set as the map spawn point
*/
public boolean canCoordinateBeSpawn(int x, int z)
{
BlockPos blockpos = new BlockPos(x, 0, z);
if (this.world.getBiome(blockpos).ignorePlayerSpawnSuitability())
{
return true;
}
else
{
return this.world.getGroundAboveSeaLevel(blockpos).getBlock() == Blocks.GRASS;
}
}
/**
* Calculates the angle of sun and moon in the sky relative to a specified time (usually worldTime)
*/
public float calculateCelestialAngle(long worldTime, float partialTicks)
{
int i = (int)(worldTime % 24000L);
float f = ((float)i + partialTicks) / 24000.0F - 0.25F;
if (f < 0.0F)
{
++f;
}
if (f > 1.0F)
{
--f;
}
float f1 = 1.0F - (float)((Math.cos((double)f * Math.PI) + 1.0D) / 2.0D);
f = f + (f1 - f) / 3.0F;
return f;
}
public int getMoonPhase(long worldTime)
{
return (int)(worldTime / 24000L % 8L + 8L) % 8;
}
/**
* Returns 'true' if in the "main surface world", but 'false' if in the Nether or End dimensions.
*/
public boolean isSurfaceWorld()
{
return true;
}
/**
* Returns array with sunrise/sunset colors
*/
@Nullable
@SideOnly(Side.CLIENT)
public float[] calcSunriseSunsetColors(float celestialAngle, float partialTicks)
{
float f = 0.4F;
float f1 = MathHelper.cos(celestialAngle * ((float)Math.PI * 2F)) - 0.0F;
float f2 = -0.0F;
if (f1 >= -0.4F && f1 <= 0.4F)
{
float f3 = (f1 - -0.0F) / 0.4F * 0.5F + 0.5F;
float f4 = 1.0F - (1.0F - MathHelper.sin(f3 * (float)Math.PI)) * 0.99F;
f4 = f4 * f4;
this.colorsSunriseSunset[0] = f3 * 0.3F + 0.7F;
this.colorsSunriseSunset[1] = f3 * f3 * 0.7F + 0.2F;
this.colorsSunriseSunset[2] = f3 * f3 * 0.0F + 0.2F;
this.colorsSunriseSunset[3] = f4;
return this.colorsSunriseSunset;
}
else
{
return null;
}
}
/**
* Return Vec3D with biome specific fog color
*/
@SideOnly(Side.CLIENT)
public Vec3d getFogColor(float p_76562_1_, float p_76562_2_)
{
float f = MathHelper.cos(p_76562_1_ * ((float)Math.PI * 2F)) * 2.0F + 0.5F;
f = MathHelper.clamp(f, 0.0F, 1.0F);
float f1 = 0.7529412F;
float f2 = 0.84705883F;
float f3 = 1.0F;
f1 = f1 * (f * 0.94F + 0.06F);
f2 = f2 * (f * 0.94F + 0.06F);
f3 = f3 * (f * 0.91F + 0.09F);
return new Vec3d((double)f1, (double)f2, (double)f3);
}
/**
* True if the player can respawn in this dimension (true = overworld, false = nether).
*/
public boolean canRespawnHere()
{
return true;
}
/**
* the y level at which clouds are rendered.
*/
@SideOnly(Side.CLIENT)
public float getCloudHeight()
{
return this.terrainType.getCloudHeight();
}
@SideOnly(Side.CLIENT)
public boolean isSkyColored()
{
return true;
}
@Nullable
public BlockPos getSpawnCoordinate()
{
return null;
}
public int getAverageGroundLevel()
{
return this.terrainType.getMinimumSpawnHeight(this.world);
}
/**
* 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.
*/
@SideOnly(Side.CLIENT)
public double getVoidFogYFactor()
{
return this.terrainType.voidFadeMagnitude();
}
/**
* Returns true if the given X,Z coordinate should show environmental fog.
*/
@SideOnly(Side.CLIENT)
public boolean doesXZShowFog(int x, int z)
{
return false;
}
public BiomeProvider getBiomeProvider()
{
return this.biomeProvider;
}
public boolean doesWaterVaporize()
{
return this.doesWaterVaporize;
}
public boolean hasSkyLight()
{
return this.hasSkyLight;
}
public boolean isNether()
{
return this.nether;
}
public float[] getLightBrightnessTable()
{
return this.lightBrightnessTable;
}
public WorldBorder createWorldBorder()
{
return new WorldBorder();
}
/*======================================= Forge Start =========================================*/
private net.minecraftforge.client.IRenderHandler skyRenderer = null;
private net.minecraftforge.client.IRenderHandler cloudRenderer = null;
private net.minecraftforge.client.IRenderHandler weatherRenderer = null;
private int dimensionId;
/**
* Sets the providers current dimension ID, used in default getSaveFolder()
* Added to allow default providers to be registered for multiple dimensions.
* This is to denote the exact dimension ID opposed to the 'type' in WorldType
*
* @param dim Dimension ID
*/
public void setDimension(int dim)
{
this.dimensionId = dim;
}
public int getDimension()
{
return this.dimensionId;
}
/**
* 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.
*/
@Nullable
public String getSaveFolder()
{
return (dimensionId == 0 ? null : "DIM" + dimensionId);
}
/**
* The dimension's movement factor.
* Whenever a player or entity changes dimension from world A to world B, their coordinates are multiplied by
* worldA.provider.getMovementFactor() / worldB.provider.getMovementFactor()
* Example: Overworld factor is 1, nether factor is 8. Traveling from overworld to nether multiplies coordinates by 1/8.
* @return The movement factor
*/
public double getMovementFactor()
{
if (this instanceof WorldProviderHell)
{
return 8.0;
}
return 1.0;
}
/**
* If this method returns true, then chunks received by the client will
* have {@link net.minecraft.world.chunk.Chunk#resetRelightChecks} called
* on them, queuing lighting checks for all air blocks in the chunk (and
* any adjacent light-emitting blocks).
*
* Returning true here is recommended if the chunk generator used also
* does this for newly generated chunks.
*
* @return true if lighting checks should be performed
*/
public boolean shouldClientCheckLighting()
{
return !(this instanceof WorldProviderSurface);
}
@Nullable
@SideOnly(Side.CLIENT)
public net.minecraftforge.client.IRenderHandler getSkyRenderer()
{
return this.skyRenderer;
}
@SideOnly(Side.CLIENT)
public void setSkyRenderer(net.minecraftforge.client.IRenderHandler skyRenderer)
{
this.skyRenderer = skyRenderer;
}
@Nullable
@SideOnly(Side.CLIENT)
public net.minecraftforge.client.IRenderHandler getCloudRenderer()
{
return cloudRenderer;
}
@SideOnly(Side.CLIENT)
public void setCloudRenderer(net.minecraftforge.client.IRenderHandler renderer)
{
cloudRenderer = renderer;
}
@Nullable
@SideOnly(Side.CLIENT)
public net.minecraftforge.client.IRenderHandler getWeatherRenderer()
{
return weatherRenderer;
}
@SideOnly(Side.CLIENT)
public void setWeatherRenderer(net.minecraftforge.client.IRenderHandler renderer)
{
weatherRenderer = renderer;
}
/**
* Allows for manipulating the coloring of the lightmap texture.
* Will be called for each 16*16 combination of sky/block light values.
*
* @param partialTicks Progress between ticks.
* @param sunBrightness Current sun brightness.
* @param skyLight Sky light brightness factor.
* @param blockLight Block light brightness factor.
* @param colors The color values that will be used: [r, g, b].
*
* @see net.minecraft.client.renderer.EntityRenderer#updateLightmap(float)
*/
public void getLightmapColors(float partialTicks, float sunBrightness, float skyLight, float blockLight, float[] colors) {}
public BlockPos getRandomizedSpawnPoint()
{
BlockPos ret = this.world.getSpawnPoint();
boolean isAdventure = world.getWorldInfo().getGameType() == GameType.ADVENTURE;
int spawnFuzz = this.world instanceof WorldServer ? terrainType.getSpawnFuzz((WorldServer)this.world, this.world.getMinecraftServer()) : 1;
int border = MathHelper.floor(world.getWorldBorder().getClosestDistance(ret.getX(), ret.getZ()));
if (border < spawnFuzz) spawnFuzz = border;
if (!isNether() && !isAdventure && spawnFuzz != 0)
{
if (spawnFuzz < 2) spawnFuzz = 2;
int spawnFuzzHalf = spawnFuzz / 2;
ret = world.getTopSolidOrLiquidBlock(ret.add(spawnFuzzHalf - world.rand.nextInt(spawnFuzz), 0, spawnFuzzHalf - world.rand.nextInt(spawnFuzz)));
}
return ret;
}
/**
* Determine if the cursor 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 z Z Position
* @param rotation the regular rotation of the marker
* @return True to 'spin' the cursor
*/
public boolean shouldMapSpin(String entity, double x, double z, double rotation)
{
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(net.minecraft.entity.player.EntityPlayerMP player)
{
return player.getSpawnDimension();
}
/**
* Called from {@link World#initCapabilities()}, to gather capabilities for this world.
* It's safe to access world here since this is called after world is registered.
*
* On server, called directly after mapStorage and world data such as Scoreboard and VillageCollection are initialized.
* On client, called when world is constructed, just before world load event is called.
* Note that this method is always called before the world load event.
* @return initial holder for capabilities on the world
*/
@Nullable
public net.minecraftforge.common.capabilities.ICapabilityProvider initCapabilities() {
return null;
}
/**
* Called on the client to get the music type to play when in this world type.
* At the time of calling, the client player and world are guaranteed to be non-null
* @return null to use vanilla logic, otherwise a MusicType to play in this world
*/
@Nullable
@SideOnly(Side.CLIENT)
public net.minecraft.client.audio.MusicTicker.MusicType getMusicType()
{
return null;
}
/**
* Determines if the player can sleep in this world (or if the bed should explode for example).
*
* @param player The player that is attempting to sleep
* @param pos The location where the player tries to sleep at (the position of the clicked on bed for example)
* @return the result of a player trying to sleep at the given location
*/
public WorldSleepResult canSleepAt(net.minecraft.entity.player.EntityPlayer player, BlockPos pos)
{
return (this.canRespawnHere() && this.world.getBiome(pos) != net.minecraft.init.Biomes.HELL) ? WorldSleepResult.ALLOW : WorldSleepResult.BED_EXPLODES;
}
public static enum WorldSleepResult
{
ALLOW,
DENY,
BED_EXPLODES;
}
/*======================================= Start Moved From World =========================================*/
public Biome getBiomeForCoords(BlockPos pos)
{
return world.getBiomeForCoordsBody(pos);
}
public boolean isDaytime()
{
return world.getSkylightSubtracted() < 4;
}
/**
* The current sun brightness factor for this dimension.
* 0.0f means no light at all, and 1.0f means maximum sunlight.
* This will be used for the "calculateSkylightSubtracted"
* which is for Sky light value calculation.
*
* @return The current brightness factor
* */
public float getSunBrightnessFactor(float par1)
{
return world.getSunBrightnessFactor(par1);
}
/**
* Calculates the current moon phase factor.
* This factor is effective for slimes.
* (This method do not affect the moon rendering)
* */
public float getCurrentMoonPhaseFactor()
{
return world.getCurrentMoonPhaseFactorBody();
}
@SideOnly(Side.CLIENT)
public Vec3d getSkyColor(net.minecraft.entity.Entity cameraEntity, float partialTicks)
{
return world.getSkyColorBody(cameraEntity, partialTicks);
}
@SideOnly(Side.CLIENT)
public Vec3d getCloudColor(float partialTicks)
{
return world.getCloudColorBody(partialTicks);
}
/**
* Gets the Sun Brightness for rendering sky.
* */
@SideOnly(Side.CLIENT)
public float getSunBrightness(float par1)
{
return world.getSunBrightnessBody(par1);
}
/**
* Gets the Star Brightness for rendering sky.
* */
@SideOnly(Side.CLIENT)
public float getStarBrightness(float par1)
{
return world.getStarBrightnessBody(par1);
}
public void setAllowedSpawnTypes(boolean allowHostile, boolean allowPeaceful)
{
world.spawnHostileMobs = allowHostile;
world.spawnPeacefulMobs = allowPeaceful;
}
public void calculateInitialWeather()
{
world.calculateInitialWeatherBody();
}
public void updateWeather()
{
world.updateWeatherBody();
}
public boolean canBlockFreeze(BlockPos pos, boolean byWater)
{
return world.canBlockFreezeBody(pos, byWater);
}
public boolean canSnowAt(BlockPos pos, boolean checkLight)
{
return world.canSnowAtBody(pos, checkLight);
}
public void setWorldTime(long time)
{
world.worldInfo.setWorldTime(time);
}
public long getSeed()
{
return world.worldInfo.getSeed();
}
public long getWorldTime()
{
return world.worldInfo.getWorldTime();
}
public BlockPos getSpawnPoint()
{
net.minecraft.world.storage.WorldInfo info = world.worldInfo;
return new BlockPos(info.getSpawnX(), info.getSpawnY(), info.getSpawnZ());
}
public void setSpawnPoint(BlockPos pos)
{
world.worldInfo.setSpawn(pos);
}
public boolean canMineBlock(net.minecraft.entity.player.EntityPlayer player, BlockPos pos)
{
return world.canMineBlockBody(player, pos);
}
public boolean isBlockHighHumidity(BlockPos pos)
{
return world.getBiome(pos).isHighHumidity();
}
public int getHeight()
{
return 256;
}
public int getActualHeight()
{
return nether ? 128 : 256;
}
public double getHorizon()
{
return world.worldInfo.getTerrainType().getHorizon(world);
}
public void resetRainAndThunder()
{
world.worldInfo.setRainTime(0);
world.worldInfo.setRaining(false);
world.worldInfo.setThunderTime(0);
world.worldInfo.setThundering(false);
}
public boolean canDoLightning(net.minecraft.world.chunk.Chunk chunk)
{
return true;
}
public boolean canDoRainSnowIce(net.minecraft.world.chunk.Chunk chunk)
{
return true;
}
/**
* Called when a Player is added to the provider's world.
*/
public void onPlayerAdded(EntityPlayerMP player)
{
}
/**
* Called when a Player is removed from the provider's world.
*/
public void onPlayerRemoved(EntityPlayerMP player)
{
}
public abstract DimensionType getDimensionType();
/**
* Called when the world is performing a save. Only used to save the state of the Dragon Boss fight in
* WorldProviderEnd in Vanilla.
*/
public void onWorldSave()
{
}
/**
* Called when the world is updating entities. Only used in WorldProviderEnd to update the DragonFightManager in
* Vanilla.
*/
public void onWorldUpdateEntities()
{
}
/**
* Called to determine if the chunk at the given chunk coordinates within the provider's world can be dropped. Used
* in WorldProviderSurface to prevent spawn chunks from being unloaded.
*/
public boolean canDropChunk(int x, int z)
{
return true;
}
}

View File

@@ -0,0 +1,194 @@
package net.minecraft.world;
import javax.annotation.Nullable;
import net.minecraft.init.Biomes;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.MathHelper;
import net.minecraft.util.math.Vec3d;
import net.minecraft.world.biome.BiomeProviderSingle;
import net.minecraft.world.end.DragonFightManager;
import net.minecraft.world.gen.ChunkGeneratorEnd;
import net.minecraft.world.gen.IChunkGenerator;
import net.minecraftforge.fml.relauncher.Side;
import net.minecraftforge.fml.relauncher.SideOnly;
public class WorldProviderEnd extends WorldProvider
{
private DragonFightManager dragonFightManager;
/**
* Creates a new {@link BiomeProvider} for the WorldProvider, and also sets the values of {@link #hasSkylight} and
* {@link #hasNoSky} appropriately.
*
* Note that subclasses generally override this method without calling the parent version.
*/
public void init()
{
this.biomeProvider = new BiomeProviderSingle(Biomes.SKY);
NBTTagCompound nbttagcompound = this.world.getWorldInfo().getDimensionData(this.world.provider.getDimension());
this.dragonFightManager = this.world instanceof WorldServer ? new DragonFightManager((WorldServer)this.world, nbttagcompound.getCompoundTag("DragonFight")) : null;
}
public IChunkGenerator createChunkGenerator()
{
return new ChunkGeneratorEnd(this.world, this.world.getWorldInfo().isMapFeaturesEnabled(), this.world.getSeed(), this.getSpawnCoordinate());
}
/**
* Calculates the angle of sun and moon in the sky relative to a specified time (usually worldTime)
*/
public float calculateCelestialAngle(long worldTime, float partialTicks)
{
return 0.0F;
}
/**
* Returns array with sunrise/sunset colors
*/
@Nullable
@SideOnly(Side.CLIENT)
public float[] calcSunriseSunsetColors(float celestialAngle, float partialTicks)
{
return null;
}
/**
* Return Vec3D with biome specific fog color
*/
@SideOnly(Side.CLIENT)
public Vec3d getFogColor(float p_76562_1_, float p_76562_2_)
{
int i = 10518688;
float f = MathHelper.cos(p_76562_1_ * ((float)Math.PI * 2F)) * 2.0F + 0.5F;
f = MathHelper.clamp(f, 0.0F, 1.0F);
float f1 = 0.627451F;
float f2 = 0.5019608F;
float f3 = 0.627451F;
f1 = f1 * (f * 0.0F + 0.15F);
f2 = f2 * (f * 0.0F + 0.15F);
f3 = f3 * (f * 0.0F + 0.15F);
return new Vec3d((double)f1, (double)f2, (double)f3);
}
@SideOnly(Side.CLIENT)
public boolean isSkyColored()
{
return false;
}
/**
* True if the player can respawn in this dimension (true = overworld, false = nether).
*/
public boolean canRespawnHere()
{
return false;
}
/**
* Returns 'true' if in the "main surface world", but 'false' if in the Nether or End dimensions.
*/
public boolean isSurfaceWorld()
{
return false;
}
/**
* the y level at which clouds are rendered.
*/
@SideOnly(Side.CLIENT)
public float getCloudHeight()
{
return 8.0F;
}
/**
* Will check if the x, z position specified is alright to be set as the map spawn point
*/
public boolean canCoordinateBeSpawn(int x, int z)
{
return this.world.getGroundAboveSeaLevel(new BlockPos(x, 0, z)).getMaterial().blocksMovement();
}
public BlockPos getSpawnCoordinate()
{
return new BlockPos(100, 50, 0);
}
public int getAverageGroundLevel()
{
return 50;
}
/**
* Returns true if the given X,Z coordinate should show environmental fog.
*/
@SideOnly(Side.CLIENT)
public boolean doesXZShowFog(int x, int z)
{
return false;
}
public DimensionType getDimensionType()
{
return DimensionType.THE_END;
}
/**
* Called when the world is performing a save. Only used to save the state of the Dragon Boss fight in
* WorldProviderEnd in Vanilla.
*/
public void onWorldSave()
{
NBTTagCompound nbttagcompound = new NBTTagCompound();
if (this.dragonFightManager != null)
{
nbttagcompound.setTag("DragonFight", this.dragonFightManager.getCompound());
}
this.world.getWorldInfo().setDimensionData(this.world.provider.getDimension(), nbttagcompound);
}
/**
* Called when the world is updating entities. Only used in WorldProviderEnd to update the DragonFightManager in
* Vanilla.
*/
public void onWorldUpdateEntities()
{
if (this.dragonFightManager != null)
{
this.dragonFightManager.tick();
}
}
@Nullable
public DragonFightManager getDragonFightManager()
{
return this.dragonFightManager;
}
/**
* Called when a Player is added to the provider's world.
*/
@Override
public void onPlayerAdded(net.minecraft.entity.player.EntityPlayerMP player)
{
if (this.dragonFightManager != null)
{
this.dragonFightManager.addPlayer(player);
}
}
/**
* Called when a Player is removed from the provider's world.
*/
@Override
public void onPlayerRemoved(net.minecraft.entity.player.EntityPlayerMP player)
{
if (this.dragonFightManager != null)
{
this.dragonFightManager.removePlayer(player);
}
}
}

View File

@@ -0,0 +1,115 @@
package net.minecraft.world;
import net.minecraft.init.Biomes;
import net.minecraft.util.math.Vec3d;
import net.minecraft.world.biome.BiomeProviderSingle;
import net.minecraft.world.border.WorldBorder;
import net.minecraft.world.gen.ChunkGeneratorHell;
import net.minecraft.world.gen.IChunkGenerator;
import net.minecraftforge.fml.relauncher.Side;
import net.minecraftforge.fml.relauncher.SideOnly;
public class WorldProviderHell extends WorldProvider
{
/**
* Creates a new {@link BiomeProvider} for the WorldProvider, and also sets the values of {@link #hasSkylight} and
* {@link #hasNoSky} appropriately.
*
* Note that subclasses generally override this method without calling the parent version.
*/
public void init()
{
this.biomeProvider = new BiomeProviderSingle(Biomes.HELL);
this.doesWaterVaporize = true;
this.nether = true;
}
/**
* Return Vec3D with biome specific fog color
*/
@SideOnly(Side.CLIENT)
public Vec3d getFogColor(float p_76562_1_, float p_76562_2_)
{
return new Vec3d(0.20000000298023224D, 0.029999999329447746D, 0.029999999329447746D);
}
/**
* Creates the light to brightness table
*/
protected void generateLightBrightnessTable()
{
float f = 0.1F;
for (int i = 0; i <= 15; ++i)
{
float f1 = 1.0F - (float)i / 15.0F;
this.lightBrightnessTable[i] = (1.0F - f1) / (f1 * 3.0F + 1.0F) * 0.9F + 0.1F;
}
}
public IChunkGenerator createChunkGenerator()
{
return new ChunkGeneratorHell(this.world, this.world.getWorldInfo().isMapFeaturesEnabled(), this.world.getSeed());
}
/**
* Returns 'true' if in the "main surface world", but 'false' if in the Nether or End dimensions.
*/
public boolean isSurfaceWorld()
{
return false;
}
/**
* Will check if the x, z position specified is alright to be set as the map spawn point
*/
public boolean canCoordinateBeSpawn(int x, int z)
{
return false;
}
/**
* Calculates the angle of sun and moon in the sky relative to a specified time (usually worldTime)
*/
public float calculateCelestialAngle(long worldTime, float partialTicks)
{
return 0.5F;
}
/**
* True if the player can respawn in this dimension (true = overworld, false = nether).
*/
public boolean canRespawnHere()
{
return false;
}
/**
* Returns true if the given X,Z coordinate should show environmental fog.
*/
@SideOnly(Side.CLIENT)
public boolean doesXZShowFog(int x, int z)
{
return true;
}
public WorldBorder createWorldBorder()
{
return new WorldBorder()
{
public double getCenterX()
{
return super.getCenterX() / 8.0D;
}
public double getCenterZ()
{
return super.getCenterZ() / 8.0D;
}
};
}
public DimensionType getDimensionType()
{
return DimensionType.NETHER;
}
}

View File

@@ -0,0 +1,18 @@
package net.minecraft.world;
public class WorldProviderSurface extends WorldProvider
{
public DimensionType getDimensionType()
{
return DimensionType.OVERWORLD;
}
/**
* Called to determine if the chunk at the given chunk coordinates within the provider's world can be dropped. Used
* in WorldProviderSurface to prevent spawn chunks from being unloaded.
*/
public boolean canDropChunk(int x, int z)
{
return !this.world.isSpawnChunk(x, z) || !this.world.provider.getDimensionType().shouldLoadSpawn();
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,18 @@
package net.minecraft.world;
import net.minecraft.profiler.Profiler;
import net.minecraft.server.MinecraftServer;
import net.minecraft.world.storage.ISaveHandler;
import net.minecraft.world.storage.WorldInfo;
public class WorldServerDemo extends WorldServer
{
private static final long DEMO_WORLD_SEED = (long)"North Carolina".hashCode();
public static final WorldSettings DEMO_WORLD_SETTINGS = (new WorldSettings(DEMO_WORLD_SEED, GameType.SURVIVAL, true, false, WorldType.DEFAULT)).enableBonusChest();
public WorldServerDemo(MinecraftServer server, ISaveHandler saveHandlerIn, WorldInfo worldInfoIn, int dimensionId, Profiler profilerIn)
{
super(server, saveHandlerIn, worldInfoIn, dimensionId, profilerIn);
this.worldInfo.populateFromWorldSettings(DEMO_WORLD_SETTINGS);
}
}

View File

@@ -0,0 +1,105 @@
package net.minecraft.world;
import net.minecraft.profiler.Profiler;
import net.minecraft.server.MinecraftServer;
import net.minecraft.village.VillageCollection;
import net.minecraft.world.border.IBorderListener;
import net.minecraft.world.border.WorldBorder;
import net.minecraft.world.storage.DerivedWorldInfo;
import net.minecraft.world.storage.ISaveHandler;
public class WorldServerMulti extends WorldServer
{
private final WorldServer delegate;
private IBorderListener borderListener;
public WorldServerMulti(MinecraftServer server, ISaveHandler saveHandlerIn, int dimensionId, WorldServer delegate, Profiler profilerIn)
{
super(server, saveHandlerIn, new DerivedWorldInfo(delegate.getWorldInfo()), dimensionId, profilerIn);
this.delegate = delegate;
this.borderListener = new IBorderListener()
{
public void onSizeChanged(WorldBorder border, double newSize)
{
WorldServerMulti.this.getWorldBorder().setTransition(newSize);
}
public void onTransitionStarted(WorldBorder border, double oldSize, double newSize, long time)
{
WorldServerMulti.this.getWorldBorder().setTransition(oldSize, newSize, time);
}
public void onCenterChanged(WorldBorder border, double x, double z)
{
WorldServerMulti.this.getWorldBorder().setCenter(x, z);
}
public void onWarningTimeChanged(WorldBorder border, int newTime)
{
WorldServerMulti.this.getWorldBorder().setWarningTime(newTime);
}
public void onWarningDistanceChanged(WorldBorder border, int newDistance)
{
WorldServerMulti.this.getWorldBorder().setWarningDistance(newDistance);
}
public void onDamageAmountChanged(WorldBorder border, double newAmount)
{
WorldServerMulti.this.getWorldBorder().setDamageAmount(newAmount);
}
public void onDamageBufferChanged(WorldBorder border, double newSize)
{
WorldServerMulti.this.getWorldBorder().setDamageBuffer(newSize);
}
};
this.delegate.getWorldBorder().addListener(this.borderListener);
}
/**
* Saves the chunks to disk.
*/
protected void saveLevel() throws MinecraftException
{
this.perWorldStorage.saveAllData();
}
public World init()
{
this.mapStorage = this.delegate.getMapStorage();
this.worldScoreboard = this.delegate.getScoreboard();
this.lootTable = this.delegate.getLootTableManager();
this.advancementManager = this.delegate.getAdvancementManager();
String s = VillageCollection.fileNameForProvider(this.provider);
VillageCollection villagecollection = (VillageCollection)this.perWorldStorage.getOrLoadData(VillageCollection.class, s);
if (villagecollection == null)
{
this.villageCollection = new VillageCollection(this);
this.perWorldStorage.setData(s, this.villageCollection);
}
else
{
this.villageCollection = villagecollection;
this.villageCollection.setWorldsForAll(this);
}
this.initCapabilities();
return this;
}
/**
* Syncs all changes to disk and wait for completion.
*/
@Override
public void flush()
{
super.flush();
this.delegate.getWorldBorder().removeListener(this.borderListener); // Unlink ourselves, to prevent world leak.
}
/**
* Called during saving of a world to give children worlds a chance to save additional data. Only used to save
* WorldProviderEnd's data in Vanilla.
*/
public void saveAdditionalData()
{
this.provider.onWorldSave();
}
}

View File

@@ -0,0 +1,129 @@
package net.minecraft.world;
import net.minecraft.world.storage.WorldInfo;
import net.minecraftforge.fml.relauncher.Side;
import net.minecraftforge.fml.relauncher.SideOnly;
public final class WorldSettings
{
/** The seed for the map. */
private final long seed;
/** The EnumGameType. */
private final GameType gameType;
/** Switch for the map features. 'true' for enabled, 'false' for disabled. */
private final boolean mapFeaturesEnabled;
/** True if hardcore mode is enabled */
private final boolean hardcoreEnabled;
private final WorldType terrainType;
/** True if Commands (cheats) are allowed. */
private boolean commandsAllowed;
/** True if the Bonus Chest is enabled. */
private boolean bonusChestEnabled;
private String generatorOptions;
public WorldSettings(long seedIn, GameType gameType, boolean enableMapFeatures, boolean hardcoreMode, WorldType worldTypeIn)
{
this.generatorOptions = "";
this.seed = seedIn;
this.gameType = gameType;
this.mapFeaturesEnabled = enableMapFeatures;
this.hardcoreEnabled = hardcoreMode;
this.terrainType = worldTypeIn;
}
public WorldSettings(WorldInfo info)
{
this(info.getSeed(), info.getGameType(), info.isMapFeaturesEnabled(), info.isHardcoreModeEnabled(), info.getTerrainType());
}
/**
* Enables the bonus chest.
*/
public WorldSettings enableBonusChest()
{
this.bonusChestEnabled = true;
return this;
}
public WorldSettings setGeneratorOptions(String options)
{
this.generatorOptions = options;
return this;
}
/**
* Enables Commands (cheats).
*/
@SideOnly(Side.CLIENT)
public WorldSettings enableCommands()
{
this.commandsAllowed = true;
return this;
}
/**
* Returns true if the Bonus Chest is enabled.
*/
public boolean isBonusChestEnabled()
{
return this.bonusChestEnabled;
}
/**
* Returns the seed for the world.
*/
public long getSeed()
{
return this.seed;
}
/**
* Gets the game type.
*/
public GameType getGameType()
{
return this.gameType;
}
/**
* Returns true if hardcore mode is enabled, otherwise false
*/
public boolean getHardcoreEnabled()
{
return this.hardcoreEnabled;
}
/**
* Get whether the map features (e.g. strongholds) generation is enabled or disabled.
*/
public boolean isMapFeaturesEnabled()
{
return this.mapFeaturesEnabled;
}
public WorldType getTerrainType()
{
return this.terrainType;
}
/**
* Returns true if Commands (cheats) are allowed.
*/
public boolean areCommandsAllowed()
{
return this.commandsAllowed;
}
/**
* Gets the GameType by ID
*/
public static GameType getGameTypeById(int id)
{
return GameType.getByID(id);
}
public String getGeneratorOptions()
{
return this.generatorOptions;
}
}

View File

@@ -0,0 +1,296 @@
package net.minecraft.world;
import net.minecraftforge.fml.relauncher.Side;
import net.minecraftforge.fml.relauncher.SideOnly;
public class WorldType
{
/** List of world types. */
public static WorldType[] WORLD_TYPES = new WorldType[16];
/** Default world type. */
public static final WorldType DEFAULT = (new WorldType(0, "default", 1)).setVersioned();
/** Flat world type. */
public static final WorldType FLAT = new WorldType(1, "flat");
/** Large Biome world Type. */
public static final WorldType LARGE_BIOMES = new WorldType(2, "largeBiomes");
/** amplified world type */
public static final WorldType AMPLIFIED = (new WorldType(3, "amplified")).enableInfoNotice();
public static final WorldType CUSTOMIZED = new WorldType(4, "customized");
public static final WorldType DEBUG_ALL_BLOCK_STATES = new WorldType(5, "debug_all_block_states");
/** Default (1.1) world type. */
public static final WorldType DEFAULT_1_1 = (new WorldType(8, "default_1_1", 0)).setCanBeCreated(false);
/** ID for this world type. */
private final int id;
private final String name;
/** The int version of the ChunkProvider that generated this world. */
private final int version;
/** Whether this world type can be generated. Normally true; set to false for out-of-date generator versions. */
private boolean canBeCreated;
/** Whether this WorldType has a version or not. */
private boolean versioned;
private boolean hasInfoNotice;
private WorldType(int id, String name)
{
this(id, name, 0);
}
private WorldType(int id, String name, int version)
{
if (name.length() > 16 && DEBUG_ALL_BLOCK_STATES != null) throw new IllegalArgumentException("World type names must not be longer then 16: " + name);
this.name = name;
this.version = version;
this.canBeCreated = true;
this.id = id;
WORLD_TYPES[id] = this;
}
public String getName()
{
return this.name;
}
/**
* Gets the translation key for the name of this world type.
*/
@SideOnly(Side.CLIENT)
public String getTranslationKey()
{
return "generator." + this.name;
}
/**
* Gets the translation key for the info text for this world type.
*/
@SideOnly(Side.CLIENT)
public String getInfoTranslationKey()
{
return this.getTranslationKey() + ".info";
}
/**
* Returns generatorVersion.
*/
public int getVersion()
{
return this.version;
}
public WorldType getWorldTypeForGeneratorVersion(int version)
{
return this == DEFAULT && version == 0 ? DEFAULT_1_1 : this;
}
/**
* Sets canBeCreated to the provided value, and returns this.
*/
private WorldType setCanBeCreated(boolean enable)
{
this.canBeCreated = enable;
return this;
}
/**
* Gets whether this WorldType can be used to generate a new world.
*/
@SideOnly(Side.CLIENT)
public boolean canBeCreated()
{
return this.canBeCreated;
}
/**
* Flags this world type as having an associated version.
*/
private WorldType setVersioned()
{
this.versioned = true;
return this;
}
/**
* Returns true if this world Type has a version associated with it.
*/
public boolean isVersioned()
{
return this.versioned;
}
public static WorldType parseWorldType(String type)
{
for (WorldType worldtype : WORLD_TYPES)
{
if (worldtype != null && worldtype.name.equalsIgnoreCase(type))
{
return worldtype;
}
}
return null;
}
public int getId()
{
return this.id;
}
/**
* returns true if selecting this worldtype from the customize menu should display the generator.[worldtype].info
* message
*/
@SideOnly(Side.CLIENT)
public boolean hasInfoNotice()
{
return this.hasInfoNotice;
}
/**
* enables the display of generator.[worldtype].info message on the customize world menu
*/
private WorldType enableInfoNotice()
{
this.hasInfoNotice = true;
return this;
}
public net.minecraft.world.biome.BiomeProvider getBiomeProvider(World world)
{
if (this == FLAT)
{
net.minecraft.world.gen.FlatGeneratorInfo flatgeneratorinfo = net.minecraft.world.gen.FlatGeneratorInfo.createFlatGeneratorFromString(world.getWorldInfo().getGeneratorOptions());
return new net.minecraft.world.biome.BiomeProviderSingle(net.minecraft.world.biome.Biome.getBiome(flatgeneratorinfo.getBiome(), net.minecraft.init.Biomes.DEFAULT));
}
else if (this == DEBUG_ALL_BLOCK_STATES)
{
return new net.minecraft.world.biome.BiomeProviderSingle(net.minecraft.init.Biomes.PLAINS);
}
else
{
return new net.minecraft.world.biome.BiomeProvider(world.getWorldInfo());
}
}
public net.minecraft.world.gen.IChunkGenerator getChunkGenerator(World world, String generatorOptions)
{
if (this == FLAT) return new net.minecraft.world.gen.ChunkGeneratorFlat(world, world.getSeed(), world.getWorldInfo().isMapFeaturesEnabled(), generatorOptions);
if (this == DEBUG_ALL_BLOCK_STATES) return new net.minecraft.world.gen.ChunkGeneratorDebug(world);
if (this == CUSTOMIZED) return new net.minecraft.world.gen.ChunkGeneratorOverworld(world, world.getSeed(), world.getWorldInfo().isMapFeaturesEnabled(), generatorOptions);
return new net.minecraft.world.gen.ChunkGeneratorOverworld(world, world.getSeed(), world.getWorldInfo().isMapFeaturesEnabled(), generatorOptions);
}
public int getMinimumSpawnHeight(World world)
{
return this == FLAT ? 4 : world.getSeaLevel() + 1;
}
public double getHorizon(World world)
{
return this == FLAT ? 0.0D : 63.0D;
}
public double voidFadeMagnitude()
{
return this == FLAT ? 1.0D : 0.03125D;
}
public boolean handleSlimeSpawnReduction(java.util.Random random, World world)
{
return this == FLAT ? random.nextInt(4) != 1 : false;
}
/*=================================================== FORGE START ======================================*/
private static int getNextID()
{
for (int x = 0; x < WORLD_TYPES.length; x++)
{
if (WORLD_TYPES[x] == null)
{
return x;
}
}
int oldLen = WORLD_TYPES.length;
WORLD_TYPES = java.util.Arrays.copyOf(WORLD_TYPES, oldLen + 16);
return oldLen;
}
/**
* Creates a new world type, the ID is hidden and should not be referenced by modders.
* It will automatically expand the underlying workdType array if there are no IDs left.
* @param name
*/
public WorldType(String name)
{
this(getNextID(), name);
}
/**
* Called when 'Create New World' button is pressed before starting game
*/
public void onGUICreateWorldPress() { }
/**
* Gets the spawn fuzz for players who join the world.
* Useful for void world types.
* @return Fuzz for entity initial spawn in blocks.
*/
public int getSpawnFuzz(WorldServer world, net.minecraft.server.MinecraftServer server)
{
return Math.max(0, server.getSpawnRadius(world));
}
/**
* Called when the 'Customize' button is pressed on world creation GUI
* @param mc The Minecraft instance
* @param guiCreateWorld the createworld GUI
*/
@SideOnly(Side.CLIENT)
public void onCustomizeButton(net.minecraft.client.Minecraft mc, net.minecraft.client.gui.GuiCreateWorld guiCreateWorld)
{
if (this == WorldType.FLAT)
{
mc.displayGuiScreen(new net.minecraft.client.gui.GuiCreateFlatWorld(guiCreateWorld, guiCreateWorld.chunkProviderSettingsJson));
}
else if (this == WorldType.CUSTOMIZED)
{
mc.displayGuiScreen(new net.minecraft.client.gui.GuiCustomizeWorldScreen(guiCreateWorld, guiCreateWorld.chunkProviderSettingsJson));
}
}
/**
* Should world creation GUI show 'Customize' button for this world type?
* @return if this world type has customization parameters
*/
public boolean isCustomizable()
{
return this == FLAT || this == WorldType.CUSTOMIZED;
}
/**
* Get the height to render the clouds for this world type
* @return The height to render clouds at
*/
public float getCloudHeight()
{
return 128.0F;
}
/**
* Creates the GenLayerBiome used for generating the world with the specified ChunkProviderSettings JSON String
* *IF AND ONLY IF* this WorldType == WorldType.CUSTOMIZED.
*
*
* @param worldSeed The world seed
* @param parentLayer The parent layer to feed into any layer you return
* @param chunkSettings The ChunkGeneratorSettings constructed from the custom JSON
* @return A GenLayer that will return ints representing the Biomes to be generated, see GenLayerBiome
*/
public net.minecraft.world.gen.layer.GenLayer getBiomeLayer(long worldSeed, net.minecraft.world.gen.layer.GenLayer parentLayer, net.minecraft.world.gen.ChunkGeneratorSettings chunkSettings)
{
net.minecraft.world.gen.layer.GenLayer ret = new net.minecraft.world.gen.layer.GenLayerBiome(200L, parentLayer, this, chunkSettings);
ret = net.minecraft.world.gen.layer.GenLayerZoom.magnify(1000L, ret, 2);
ret = new net.minecraft.world.gen.layer.GenLayerBiomeEdge(1000L, ret);
return ret;
}
}

View File

@@ -0,0 +1,745 @@
package net.minecraft.world.biome;
import com.google.common.collect.Lists;
import java.util.Collections;
import java.util.List;
import java.util.Random;
import javax.annotation.Nullable;
import net.minecraft.block.BlockFlower;
import net.minecraft.block.BlockSand;
import net.minecraft.block.BlockTallGrass;
import net.minecraft.block.material.Material;
import net.minecraft.block.state.IBlockState;
import net.minecraft.entity.EntityLiving;
import net.minecraft.entity.EnumCreatureType;
import net.minecraft.entity.monster.EntityCreeper;
import net.minecraft.entity.monster.EntityEnderman;
import net.minecraft.entity.monster.EntitySkeleton;
import net.minecraft.entity.monster.EntitySlime;
import net.minecraft.entity.monster.EntitySpider;
import net.minecraft.entity.monster.EntityWitch;
import net.minecraft.entity.monster.EntityZombie;
import net.minecraft.entity.monster.EntityZombieVillager;
import net.minecraft.entity.passive.EntityBat;
import net.minecraft.entity.passive.EntityChicken;
import net.minecraft.entity.passive.EntityCow;
import net.minecraft.entity.passive.EntityPig;
import net.minecraft.entity.passive.EntitySheep;
import net.minecraft.entity.passive.EntitySquid;
import net.minecraft.init.Blocks;
import net.minecraft.util.ObjectIntIdentityMap;
import net.minecraft.util.ResourceLocation;
import net.minecraft.util.WeightedRandom;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.MathHelper;
import net.minecraft.util.registry.RegistryNamespaced;
import net.minecraft.world.ColorizerFoliage;
import net.minecraft.world.ColorizerGrass;
import net.minecraft.world.World;
import net.minecraft.world.chunk.ChunkPrimer;
import net.minecraft.world.gen.NoiseGeneratorPerlin;
import net.minecraft.world.gen.feature.WorldGenAbstractTree;
import net.minecraft.world.gen.feature.WorldGenBigTree;
import net.minecraft.world.gen.feature.WorldGenDoublePlant;
import net.minecraft.world.gen.feature.WorldGenSwamp;
import net.minecraft.world.gen.feature.WorldGenTallGrass;
import net.minecraft.world.gen.feature.WorldGenTrees;
import net.minecraft.world.gen.feature.WorldGenerator;
import net.minecraftforge.fml.relauncher.Side;
import net.minecraftforge.fml.relauncher.SideOnly;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
public abstract class Biome extends net.minecraftforge.registries.IForgeRegistryEntry.Impl<Biome>
{
private static final Logger LOGGER = LogManager.getLogger();
protected static final IBlockState STONE = Blocks.STONE.getDefaultState();
protected static final IBlockState AIR = Blocks.AIR.getDefaultState();
protected static final IBlockState BEDROCK = Blocks.BEDROCK.getDefaultState();
protected static final IBlockState GRAVEL = Blocks.GRAVEL.getDefaultState();
protected static final IBlockState RED_SANDSTONE = Blocks.RED_SANDSTONE.getDefaultState();
protected static final IBlockState SANDSTONE = Blocks.SANDSTONE.getDefaultState();
protected static final IBlockState ICE = Blocks.ICE.getDefaultState();
protected static final IBlockState WATER = Blocks.WATER.getDefaultState();
public static final ObjectIntIdentityMap<Biome> MUTATION_TO_BASE_ID_MAP = new ObjectIntIdentityMap<Biome>();
protected static final NoiseGeneratorPerlin TEMPERATURE_NOISE = new NoiseGeneratorPerlin(new Random(1234L), 1);
protected static final NoiseGeneratorPerlin GRASS_COLOR_NOISE = new NoiseGeneratorPerlin(new Random(2345L), 1);
protected static final WorldGenDoublePlant DOUBLE_PLANT_GENERATOR = new WorldGenDoublePlant();
/** The tree generator. */
protected static final WorldGenTrees TREE_FEATURE = new WorldGenTrees(false);
/** The big tree generator. */
protected static final WorldGenBigTree BIG_TREE_FEATURE = new WorldGenBigTree(false);
/** The swamp tree generator. */
protected static final WorldGenSwamp SWAMP_FEATURE = new WorldGenSwamp();
public static final RegistryNamespaced<ResourceLocation, Biome> REGISTRY = net.minecraftforge.registries.GameData.getWrapper(Biome.class);
public final String biomeName;
/** The base height of this biome. Default 0.1. */
private final float baseHeight;
/** The variation from the base height of the biome. Default 0.3. */
private final float heightVariation;
/** The temperature of this biome. */
private final float temperature;
/** The rainfall in this biome. */
private final float rainfall;
/** Color tint applied to water depending on biome */
private final int waterColor;
/** Set to true if snow is enabled for this biome. */
private final boolean enableSnow;
/** Is true (default) if the biome support rain (desert and nether can't have rain) */
private final boolean enableRain;
/** The unique identifier of the biome for which this is a mutation of. */
@Nullable
private final String baseBiomeRegName;
/** The block expected to be on the top of this biome */
public IBlockState topBlock = Blocks.GRASS.getDefaultState();
/** The block to fill spots in when not on the top */
public IBlockState fillerBlock = Blocks.DIRT.getDefaultState();
/** The biome decorator. */
public BiomeDecorator decorator;
/** Holds the classes of IMobs (hostile mobs) that can be spawned in the biome. */
protected List<Biome.SpawnListEntry> spawnableMonsterList = Lists.<Biome.SpawnListEntry>newArrayList();
/** Holds the classes of any creature that can be spawned in the biome as friendly creature. */
protected List<Biome.SpawnListEntry> spawnableCreatureList = Lists.<Biome.SpawnListEntry>newArrayList();
/** Holds the classes of any aquatic creature that can be spawned in the water of the biome. */
protected List<Biome.SpawnListEntry> spawnableWaterCreatureList = Lists.<Biome.SpawnListEntry>newArrayList();
protected List<Biome.SpawnListEntry> spawnableCaveCreatureList = Lists.<Biome.SpawnListEntry>newArrayList();
// Forge: Stores the spawnable lists for non-vanilla EnumCreatureTypes. Can't be an EnumMap as that doesn't handle new enum values being added after it's created.
protected java.util.Map<EnumCreatureType, List<Biome.SpawnListEntry>> modSpawnableLists = com.google.common.collect.Maps.newHashMap();
public static int getIdForBiome(Biome biome)
{
return REGISTRY.getIDForObject(biome);
}
@Nullable
public static Biome getBiomeForId(int id)
{
return REGISTRY.getObjectById(id);
}
@Nullable
public static Biome getMutationForBiome(Biome biome)
{
return MUTATION_TO_BASE_ID_MAP.getByValue(getIdForBiome(biome));
}
public Biome(Biome.BiomeProperties properties)
{
this.biomeName = properties.biomeName;
this.baseHeight = properties.baseHeight;
this.heightVariation = properties.heightVariation;
this.temperature = properties.temperature;
this.rainfall = properties.rainfall;
this.waterColor = properties.waterColor;
this.enableSnow = properties.enableSnow;
this.enableRain = properties.enableRain;
this.baseBiomeRegName = properties.baseBiomeRegName;
this.decorator = this.createBiomeDecorator();
this.spawnableCreatureList.add(new Biome.SpawnListEntry(EntitySheep.class, 12, 4, 4));
this.spawnableCreatureList.add(new Biome.SpawnListEntry(EntityPig.class, 10, 4, 4));
this.spawnableCreatureList.add(new Biome.SpawnListEntry(EntityChicken.class, 10, 4, 4));
this.spawnableCreatureList.add(new Biome.SpawnListEntry(EntityCow.class, 8, 4, 4));
this.spawnableMonsterList.add(new Biome.SpawnListEntry(EntitySpider.class, 100, 4, 4));
this.spawnableMonsterList.add(new Biome.SpawnListEntry(EntityZombie.class, 95, 4, 4));
this.spawnableMonsterList.add(new Biome.SpawnListEntry(EntityZombieVillager.class, 5, 1, 1));
this.spawnableMonsterList.add(new Biome.SpawnListEntry(EntitySkeleton.class, 100, 4, 4));
this.spawnableMonsterList.add(new Biome.SpawnListEntry(EntityCreeper.class, 100, 4, 4));
this.spawnableMonsterList.add(new Biome.SpawnListEntry(EntitySlime.class, 100, 4, 4));
this.spawnableMonsterList.add(new Biome.SpawnListEntry(EntityEnderman.class, 10, 1, 4));
this.spawnableMonsterList.add(new Biome.SpawnListEntry(EntityWitch.class, 5, 1, 1));
this.spawnableWaterCreatureList.add(new Biome.SpawnListEntry(EntitySquid.class, 10, 4, 4));
this.spawnableCaveCreatureList.add(new Biome.SpawnListEntry(EntityBat.class, 10, 8, 8));
this.addDefaultFlowers();
}
/**
* Allocate a new BiomeDecorator for this BiomeGenBase
*/
public BiomeDecorator createBiomeDecorator()
{
return getModdedBiomeDecorator(new BiomeDecorator());
}
public boolean isMutation()
{
return this.baseBiomeRegName != null;
}
public WorldGenAbstractTree getRandomTreeFeature(Random rand)
{
return (WorldGenAbstractTree)(rand.nextInt(10) == 0 ? BIG_TREE_FEATURE : TREE_FEATURE);
}
/**
* Gets a WorldGen appropriate for this biome.
*/
public WorldGenerator getRandomWorldGenForGrass(Random rand)
{
return new WorldGenTallGrass(BlockTallGrass.EnumType.GRASS);
}
public BlockFlower.EnumFlowerType pickRandomFlower(Random rand, BlockPos pos)
{
return rand.nextInt(3) > 0 ? BlockFlower.EnumFlowerType.DANDELION : BlockFlower.EnumFlowerType.POPPY;
}
/**
* takes temperature, returns color
*/
@SideOnly(Side.CLIENT)
public int getSkyColorByTemp(float currentTemperature)
{
currentTemperature = currentTemperature / 3.0F;
currentTemperature = MathHelper.clamp(currentTemperature, -1.0F, 1.0F);
return MathHelper.hsvToRGB(0.62222224F - currentTemperature * 0.05F, 0.5F + currentTemperature * 0.1F, 1.0F);
}
/**
* Returns the correspondent list of the EnumCreatureType informed.
*/
public List<Biome.SpawnListEntry> getSpawnableList(EnumCreatureType creatureType)
{
switch (creatureType)
{
case MONSTER:
return this.spawnableMonsterList;
case CREATURE:
return this.spawnableCreatureList;
case WATER_CREATURE:
return this.spawnableWaterCreatureList;
case AMBIENT:
return this.spawnableCaveCreatureList;
default:
// Forge: Return a non-empty list for non-vanilla EnumCreatureTypes
if (!this.modSpawnableLists.containsKey(creatureType)) this.modSpawnableLists.put(creatureType, Lists.<Biome.SpawnListEntry>newArrayList());
return this.modSpawnableLists.get(creatureType);
}
}
/**
* Returns true if the biome have snowfall instead a normal rain.
*/
public boolean getEnableSnow()
{
return this.isSnowyBiome();
}
/**
* Check if rain can occur in biome
*/
public boolean canRain()
{
return this.isSnowyBiome() ? false : this.enableRain;
}
/**
* Checks to see if the rainfall level of the biome is extremely high
*/
public boolean isHighHumidity()
{
return this.getRainfall() > 0.85F;
}
/**
* returns the chance a creature has to spawn.
*/
public float getSpawningChance()
{
return 0.1F;
}
/**
* Gets the current temperature at the given location, based off of the default for this biome, the elevation of the
* position, and {@linkplain #TEMPERATURE_NOISE} some random perlin noise.
*/
public final float getTemperature(BlockPos pos)
{
if (pos.getY() > 64)
{
float f = (float)(TEMPERATURE_NOISE.getValue((double)((float)pos.getX() / 8.0F), (double)((float)pos.getZ() / 8.0F)) * 4.0D);
return this.getDefaultTemperature() - (f + (float)pos.getY() - 64.0F) * 0.05F / 30.0F;
}
else
{
return this.getDefaultTemperature();
}
}
public void decorate(World worldIn, Random rand, BlockPos pos)
{
this.decorator.decorate(worldIn, rand, this, pos);
}
public void genTerrainBlocks(World worldIn, Random rand, ChunkPrimer chunkPrimerIn, int x, int z, double noiseVal)
{
this.generateBiomeTerrain(worldIn, rand, chunkPrimerIn, x, z, noiseVal);
}
@SideOnly(Side.CLIENT)
public int getGrassColorAtPos(BlockPos pos)
{
double d0 = (double)MathHelper.clamp(this.getTemperature(pos), 0.0F, 1.0F);
double d1 = (double)MathHelper.clamp(this.getRainfall(), 0.0F, 1.0F);
return getModdedBiomeGrassColor(ColorizerGrass.getGrassColor(d0, d1));
}
/**
* Given x, z coordinates, we count down all the y positions starting at 255 and working our way down. When we hit a
* non-air block, we replace it with this.topBlock (default grass, descendants may set otherwise), and then a
* relatively shallow layer of blocks of type this.fillerBlock (default dirt). A random set of blocks below y == 5
* (but always including y == 0) is replaced with bedrock.
*
* If we don't hit non-air until somewhat below sea level, we top with gravel and fill down with stone.
*
* If this.fillerBlock is red sand, we replace some of that with red sandstone.
*/
public final void generateBiomeTerrain(World worldIn, Random rand, ChunkPrimer chunkPrimerIn, int x, int z, double noiseVal)
{
int i = worldIn.getSeaLevel();
IBlockState iblockstate = this.topBlock;
IBlockState iblockstate1 = this.fillerBlock;
int j = -1;
int k = (int)(noiseVal / 3.0D + 3.0D + rand.nextDouble() * 0.25D);
int l = x & 15;
int i1 = z & 15;
BlockPos.MutableBlockPos blockpos$mutableblockpos = new BlockPos.MutableBlockPos();
for (int j1 = 255; j1 >= 0; --j1)
{
if (j1 <= rand.nextInt(5))
{
chunkPrimerIn.setBlockState(i1, j1, l, BEDROCK);
}
else
{
IBlockState iblockstate2 = chunkPrimerIn.getBlockState(i1, j1, l);
if (iblockstate2.getMaterial() == Material.AIR)
{
j = -1;
}
else if (iblockstate2.getBlock() == Blocks.STONE)
{
if (j == -1)
{
if (k <= 0)
{
iblockstate = AIR;
iblockstate1 = STONE;
}
else if (j1 >= i - 4 && j1 <= i + 1)
{
iblockstate = this.topBlock;
iblockstate1 = this.fillerBlock;
}
if (j1 < i && (iblockstate == null || iblockstate.getMaterial() == Material.AIR))
{
if (this.getTemperature(blockpos$mutableblockpos.setPos(x, j1, z)) < 0.15F)
{
iblockstate = ICE;
}
else
{
iblockstate = WATER;
}
}
j = k;
if (j1 >= i - 1)
{
chunkPrimerIn.setBlockState(i1, j1, l, iblockstate);
}
else if (j1 < i - 7 - k)
{
iblockstate = AIR;
iblockstate1 = STONE;
chunkPrimerIn.setBlockState(i1, j1, l, GRAVEL);
}
else
{
chunkPrimerIn.setBlockState(i1, j1, l, iblockstate1);
}
}
else if (j > 0)
{
--j;
chunkPrimerIn.setBlockState(i1, j1, l, iblockstate1);
if (j == 0 && iblockstate1.getBlock() == Blocks.SAND && k > 1)
{
j = rand.nextInt(4) + Math.max(0, j1 - 63);
iblockstate1 = iblockstate1.getValue(BlockSand.VARIANT) == BlockSand.EnumType.RED_SAND ? RED_SANDSTONE : SANDSTONE;
}
}
}
}
}
}
@SideOnly(Side.CLIENT)
public int getFoliageColorAtPos(BlockPos pos)
{
double d0 = (double)MathHelper.clamp(this.getTemperature(pos), 0.0F, 1.0F);
double d1 = (double)MathHelper.clamp(this.getRainfall(), 0.0F, 1.0F);
return getModdedBiomeFoliageColor(ColorizerFoliage.getFoliageColor(d0, d1));
}
public Class <? extends Biome > getBiomeClass()
{
return this.getClass();
}
public Biome.TempCategory getTempCategory()
{
if ((double)this.getDefaultTemperature() < 0.2D)
{
return Biome.TempCategory.COLD;
}
else
{
return (double)this.getDefaultTemperature() < 1.0D ? Biome.TempCategory.MEDIUM : Biome.TempCategory.WARM;
}
}
/**
* return the biome specified by biomeID, or 0 (ocean) if out of bounds
*/
@Nullable
public static Biome getBiome(int id)
{
return getBiome(id, (Biome)null);
}
public static Biome getBiome(int biomeId, Biome fallback)
{
Biome biome = getBiomeForId(biomeId);
return biome == null ? fallback : biome;
}
public boolean ignorePlayerSpawnSuitability()
{
return false;
}
public final float getBaseHeight()
{
return this.baseHeight;
}
/**
* Gets a floating point representation of this biome's rainfall
*/
public final float getRainfall()
{
return this.rainfall;
}
@SideOnly(Side.CLIENT)
public final String getBiomeName()
{
return this.biomeName;
}
public final float getHeightVariation()
{
return this.heightVariation;
}
/**
* Gets the constant default temperature for this biome.
*/
public final float getDefaultTemperature()
{
return this.temperature;
}
@SideOnly(Side.CLIENT)
public final int getWaterColor()
{
return getWaterColorMultiplier();
}
public final boolean isSnowyBiome()
{
return this.enableSnow;
}
/* ========================================= FORGE START ======================================*/
protected List<FlowerEntry> flowers = new java.util.ArrayList<FlowerEntry>();
public BiomeDecorator getModdedBiomeDecorator(BiomeDecorator original)
{
return new net.minecraftforge.event.terraingen.DeferredBiomeDecorator(original);
}
public int getWaterColorMultiplier()
{
net.minecraftforge.event.terraingen.BiomeEvent.GetWaterColor event = new net.minecraftforge.event.terraingen.BiomeEvent.GetWaterColor(this, waterColor);
net.minecraftforge.common.MinecraftForge.EVENT_BUS.post(event);
return event.getNewColor();
}
public int getModdedBiomeGrassColor(int original)
{
net.minecraftforge.event.terraingen.BiomeEvent.GetGrassColor event = new net.minecraftforge.event.terraingen.BiomeEvent.GetGrassColor(this, original);
net.minecraftforge.common.MinecraftForge.EVENT_BUS.post(event);
return event.getNewColor();
}
public int getModdedBiomeFoliageColor(int original)
{
net.minecraftforge.event.terraingen.BiomeEvent.GetFoliageColor event = new net.minecraftforge.event.terraingen.BiomeEvent.GetFoliageColor(this, original);
net.minecraftforge.common.MinecraftForge.EVENT_BUS.post(event);
return event.getNewColor();
}
/**
* Weighted random holder class used to hold possible flowers
* that can spawn in this biome when bonemeal is used on grass.
*/
public static class FlowerEntry extends WeightedRandom.Item
{
public final net.minecraft.block.state.IBlockState state;
public FlowerEntry(net.minecraft.block.state.IBlockState state, int weight)
{
super(weight);
this.state = state;
}
}
/**
* Adds the default flowers, as of 1.7, it is 2 yellow, and 1 red. I chose 10 to allow some wiggle room in the numbers.
*/
public void addDefaultFlowers()
{
addFlower(Blocks.YELLOW_FLOWER.getDefaultState().withProperty(Blocks.YELLOW_FLOWER.getTypeProperty(), BlockFlower.EnumFlowerType.DANDELION), 20);
addFlower(Blocks.RED_FLOWER.getDefaultState().withProperty(Blocks.RED_FLOWER.getTypeProperty(), BlockFlower.EnumFlowerType.POPPY), 10);
}
/** Register a new plant to be planted when bonemeal is used on grass.
* @param state The block to place.
* @param weight The weight of the plant, where red flowers are
* 10 and yellow flowers are 20.
*/
public void addFlower(IBlockState state, int weight)
{
this.flowers.add(new FlowerEntry(state, weight));
}
public void plantFlower(World world, Random rand, BlockPos pos)
{
if (flowers.isEmpty()) return;
FlowerEntry flower = (FlowerEntry)WeightedRandom.getRandomItem(rand, flowers);
if (flower == null || flower.state == null ||
(flower.state.getBlock() instanceof net.minecraft.block.BlockBush &&
!((net.minecraft.block.BlockBush)flower.state.getBlock()).canBlockStay(world, pos, flower.state)))
{
return;
}
world.setBlockState(pos, flower.state, 3);
}
/* ========================================= FORGE END ======================================*/
/**
* Registers all of the vanilla biomes.
*/
public static void registerBiomes()
{
registerBiome(0, "ocean", new BiomeOcean((new Biome.BiomeProperties("Ocean")).setBaseHeight(-1.0F).setHeightVariation(0.1F)));
registerBiome(1, "plains", new BiomePlains(false, (new Biome.BiomeProperties("Plains")).setBaseHeight(0.125F).setHeightVariation(0.05F).setTemperature(0.8F).setRainfall(0.4F)));
registerBiome(2, "desert", new BiomeDesert((new Biome.BiomeProperties("Desert")).setBaseHeight(0.125F).setHeightVariation(0.05F).setTemperature(2.0F).setRainfall(0.0F).setRainDisabled()));
registerBiome(3, "extreme_hills", new BiomeHills(BiomeHills.Type.NORMAL, (new Biome.BiomeProperties("Extreme Hills")).setBaseHeight(1.0F).setHeightVariation(0.5F).setTemperature(0.2F).setRainfall(0.3F)));
registerBiome(4, "forest", new BiomeForest(BiomeForest.Type.NORMAL, (new Biome.BiomeProperties("Forest")).setTemperature(0.7F).setRainfall(0.8F)));
registerBiome(5, "taiga", new BiomeTaiga(BiomeTaiga.Type.NORMAL, (new Biome.BiomeProperties("Taiga")).setBaseHeight(0.2F).setHeightVariation(0.2F).setTemperature(0.25F).setRainfall(0.8F)));
registerBiome(6, "swampland", new BiomeSwamp((new Biome.BiomeProperties("Swampland")).setBaseHeight(-0.2F).setHeightVariation(0.1F).setTemperature(0.8F).setRainfall(0.9F).setWaterColor(14745518)));
registerBiome(7, "river", new BiomeRiver((new Biome.BiomeProperties("River")).setBaseHeight(-0.5F).setHeightVariation(0.0F)));
registerBiome(8, "hell", new BiomeHell((new Biome.BiomeProperties("Hell")).setTemperature(2.0F).setRainfall(0.0F).setRainDisabled()));
registerBiome(9, "sky", new BiomeEnd((new Biome.BiomeProperties("The End")).setRainDisabled()));
registerBiome(10, "frozen_ocean", new BiomeOcean((new Biome.BiomeProperties("FrozenOcean")).setBaseHeight(-1.0F).setHeightVariation(0.1F).setTemperature(0.0F).setRainfall(0.5F).setSnowEnabled()));
registerBiome(11, "frozen_river", new BiomeRiver((new Biome.BiomeProperties("FrozenRiver")).setBaseHeight(-0.5F).setHeightVariation(0.0F).setTemperature(0.0F).setRainfall(0.5F).setSnowEnabled()));
registerBiome(12, "ice_flats", new BiomeSnow(false, (new Biome.BiomeProperties("Ice Plains")).setBaseHeight(0.125F).setHeightVariation(0.05F).setTemperature(0.0F).setRainfall(0.5F).setSnowEnabled()));
registerBiome(13, "ice_mountains", new BiomeSnow(false, (new Biome.BiomeProperties("Ice Mountains")).setBaseHeight(0.45F).setHeightVariation(0.3F).setTemperature(0.0F).setRainfall(0.5F).setSnowEnabled()));
registerBiome(14, "mushroom_island", new BiomeMushroomIsland((new Biome.BiomeProperties("MushroomIsland")).setBaseHeight(0.2F).setHeightVariation(0.3F).setTemperature(0.9F).setRainfall(1.0F)));
registerBiome(15, "mushroom_island_shore", new BiomeMushroomIsland((new Biome.BiomeProperties("MushroomIslandShore")).setBaseHeight(0.0F).setHeightVariation(0.025F).setTemperature(0.9F).setRainfall(1.0F)));
registerBiome(16, "beaches", new BiomeBeach((new Biome.BiomeProperties("Beach")).setBaseHeight(0.0F).setHeightVariation(0.025F).setTemperature(0.8F).setRainfall(0.4F)));
registerBiome(17, "desert_hills", new BiomeDesert((new Biome.BiomeProperties("DesertHills")).setBaseHeight(0.45F).setHeightVariation(0.3F).setTemperature(2.0F).setRainfall(0.0F).setRainDisabled()));
registerBiome(18, "forest_hills", new BiomeForest(BiomeForest.Type.NORMAL, (new Biome.BiomeProperties("ForestHills")).setBaseHeight(0.45F).setHeightVariation(0.3F).setTemperature(0.7F).setRainfall(0.8F)));
registerBiome(19, "taiga_hills", new BiomeTaiga(BiomeTaiga.Type.NORMAL, (new Biome.BiomeProperties("TaigaHills")).setTemperature(0.25F).setRainfall(0.8F).setBaseHeight(0.45F).setHeightVariation(0.3F)));
registerBiome(20, "smaller_extreme_hills", new BiomeHills(BiomeHills.Type.EXTRA_TREES, (new Biome.BiomeProperties("Extreme Hills Edge")).setBaseHeight(0.8F).setHeightVariation(0.3F).setTemperature(0.2F).setRainfall(0.3F)));
registerBiome(21, "jungle", new BiomeJungle(false, (new Biome.BiomeProperties("Jungle")).setTemperature(0.95F).setRainfall(0.9F)));
registerBiome(22, "jungle_hills", new BiomeJungle(false, (new Biome.BiomeProperties("JungleHills")).setBaseHeight(0.45F).setHeightVariation(0.3F).setTemperature(0.95F).setRainfall(0.9F)));
registerBiome(23, "jungle_edge", new BiomeJungle(true, (new Biome.BiomeProperties("JungleEdge")).setTemperature(0.95F).setRainfall(0.8F)));
registerBiome(24, "deep_ocean", new BiomeOcean((new Biome.BiomeProperties("Deep Ocean")).setBaseHeight(-1.8F).setHeightVariation(0.1F)));
registerBiome(25, "stone_beach", new BiomeStoneBeach((new Biome.BiomeProperties("Stone Beach")).setBaseHeight(0.1F).setHeightVariation(0.8F).setTemperature(0.2F).setRainfall(0.3F)));
registerBiome(26, "cold_beach", new BiomeBeach((new Biome.BiomeProperties("Cold Beach")).setBaseHeight(0.0F).setHeightVariation(0.025F).setTemperature(0.05F).setRainfall(0.3F).setSnowEnabled()));
registerBiome(27, "birch_forest", new BiomeForest(BiomeForest.Type.BIRCH, (new Biome.BiomeProperties("Birch Forest")).setTemperature(0.6F).setRainfall(0.6F)));
registerBiome(28, "birch_forest_hills", new BiomeForest(BiomeForest.Type.BIRCH, (new Biome.BiomeProperties("Birch Forest Hills")).setBaseHeight(0.45F).setHeightVariation(0.3F).setTemperature(0.6F).setRainfall(0.6F)));
registerBiome(29, "roofed_forest", new BiomeForest(BiomeForest.Type.ROOFED, (new Biome.BiomeProperties("Roofed Forest")).setTemperature(0.7F).setRainfall(0.8F)));
registerBiome(30, "taiga_cold", new BiomeTaiga(BiomeTaiga.Type.NORMAL, (new Biome.BiomeProperties("Cold Taiga")).setBaseHeight(0.2F).setHeightVariation(0.2F).setTemperature(-0.5F).setRainfall(0.4F).setSnowEnabled()));
registerBiome(31, "taiga_cold_hills", new BiomeTaiga(BiomeTaiga.Type.NORMAL, (new Biome.BiomeProperties("Cold Taiga Hills")).setBaseHeight(0.45F).setHeightVariation(0.3F).setTemperature(-0.5F).setRainfall(0.4F).setSnowEnabled()));
registerBiome(32, "redwood_taiga", new BiomeTaiga(BiomeTaiga.Type.MEGA, (new Biome.BiomeProperties("Mega Taiga")).setTemperature(0.3F).setRainfall(0.8F).setBaseHeight(0.2F).setHeightVariation(0.2F)));
registerBiome(33, "redwood_taiga_hills", new BiomeTaiga(BiomeTaiga.Type.MEGA, (new Biome.BiomeProperties("Mega Taiga Hills")).setBaseHeight(0.45F).setHeightVariation(0.3F).setTemperature(0.3F).setRainfall(0.8F)));
registerBiome(34, "extreme_hills_with_trees", new BiomeHills(BiomeHills.Type.EXTRA_TREES, (new Biome.BiomeProperties("Extreme Hills+")).setBaseHeight(1.0F).setHeightVariation(0.5F).setTemperature(0.2F).setRainfall(0.3F)));
registerBiome(35, "savanna", new BiomeSavanna((new Biome.BiomeProperties("Savanna")).setBaseHeight(0.125F).setHeightVariation(0.05F).setTemperature(1.2F).setRainfall(0.0F).setRainDisabled()));
registerBiome(36, "savanna_rock", new BiomeSavanna((new Biome.BiomeProperties("Savanna Plateau")).setBaseHeight(1.5F).setHeightVariation(0.025F).setTemperature(1.0F).setRainfall(0.0F).setRainDisabled()));
registerBiome(37, "mesa", new BiomeMesa(false, false, (new Biome.BiomeProperties("Mesa")).setTemperature(2.0F).setRainfall(0.0F).setRainDisabled()));
registerBiome(38, "mesa_rock", new BiomeMesa(false, true, (new Biome.BiomeProperties("Mesa Plateau F")).setBaseHeight(1.5F).setHeightVariation(0.025F).setTemperature(2.0F).setRainfall(0.0F).setRainDisabled()));
registerBiome(39, "mesa_clear_rock", new BiomeMesa(false, false, (new Biome.BiomeProperties("Mesa Plateau")).setBaseHeight(1.5F).setHeightVariation(0.025F).setTemperature(2.0F).setRainfall(0.0F).setRainDisabled()));
registerBiome(127, "void", new BiomeVoid((new Biome.BiomeProperties("The Void")).setRainDisabled()));
registerBiome(129, "mutated_plains", new BiomePlains(true, (new Biome.BiomeProperties("Sunflower Plains")).setBaseBiome("plains").setBaseHeight(0.125F).setHeightVariation(0.05F).setTemperature(0.8F).setRainfall(0.4F)));
registerBiome(130, "mutated_desert", new BiomeDesert((new Biome.BiomeProperties("Desert M")).setBaseBiome("desert").setBaseHeight(0.225F).setHeightVariation(0.25F).setTemperature(2.0F).setRainfall(0.0F).setRainDisabled()));
registerBiome(131, "mutated_extreme_hills", new BiomeHills(BiomeHills.Type.MUTATED, (new Biome.BiomeProperties("Extreme Hills M")).setBaseBiome("extreme_hills").setBaseHeight(1.0F).setHeightVariation(0.5F).setTemperature(0.2F).setRainfall(0.3F)));
registerBiome(132, "mutated_forest", new BiomeForest(BiomeForest.Type.FLOWER, (new Biome.BiomeProperties("Flower Forest")).setBaseBiome("forest").setHeightVariation(0.4F).setTemperature(0.7F).setRainfall(0.8F)));
registerBiome(133, "mutated_taiga", new BiomeTaiga(BiomeTaiga.Type.NORMAL, (new Biome.BiomeProperties("Taiga M")).setBaseBiome("taiga").setBaseHeight(0.3F).setHeightVariation(0.4F).setTemperature(0.25F).setRainfall(0.8F)));
registerBiome(134, "mutated_swampland", new BiomeSwamp((new Biome.BiomeProperties("Swampland M")).setBaseBiome("swampland").setBaseHeight(-0.1F).setHeightVariation(0.3F).setTemperature(0.8F).setRainfall(0.9F).setWaterColor(14745518)));
registerBiome(140, "mutated_ice_flats", new BiomeSnow(true, (new Biome.BiomeProperties("Ice Plains Spikes")).setBaseBiome("ice_flats").setBaseHeight(0.425F).setHeightVariation(0.45000002F).setTemperature(0.0F).setRainfall(0.5F).setSnowEnabled()));
registerBiome(149, "mutated_jungle", new BiomeJungle(false, (new Biome.BiomeProperties("Jungle M")).setBaseBiome("jungle").setBaseHeight(0.2F).setHeightVariation(0.4F).setTemperature(0.95F).setRainfall(0.9F)));
registerBiome(151, "mutated_jungle_edge", new BiomeJungle(true, (new Biome.BiomeProperties("JungleEdge M")).setBaseBiome("jungle_edge").setBaseHeight(0.2F).setHeightVariation(0.4F).setTemperature(0.95F).setRainfall(0.8F)));
registerBiome(155, "mutated_birch_forest", new BiomeForestMutated((new Biome.BiomeProperties("Birch Forest M")).setBaseBiome("birch_forest").setBaseHeight(0.2F).setHeightVariation(0.4F).setTemperature(0.6F).setRainfall(0.6F)));
registerBiome(156, "mutated_birch_forest_hills", new BiomeForestMutated((new Biome.BiomeProperties("Birch Forest Hills M")).setBaseBiome("birch_forest_hills").setBaseHeight(0.55F).setHeightVariation(0.5F).setTemperature(0.6F).setRainfall(0.6F)));
registerBiome(157, "mutated_roofed_forest", new BiomeForest(BiomeForest.Type.ROOFED, (new Biome.BiomeProperties("Roofed Forest M")).setBaseBiome("roofed_forest").setBaseHeight(0.2F).setHeightVariation(0.4F).setTemperature(0.7F).setRainfall(0.8F)));
registerBiome(158, "mutated_taiga_cold", new BiomeTaiga(BiomeTaiga.Type.NORMAL, (new Biome.BiomeProperties("Cold Taiga M")).setBaseBiome("taiga_cold").setBaseHeight(0.3F).setHeightVariation(0.4F).setTemperature(-0.5F).setRainfall(0.4F).setSnowEnabled()));
registerBiome(160, "mutated_redwood_taiga", new BiomeTaiga(BiomeTaiga.Type.MEGA_SPRUCE, (new Biome.BiomeProperties("Mega Spruce Taiga")).setBaseBiome("redwood_taiga").setBaseHeight(0.2F).setHeightVariation(0.2F).setTemperature(0.25F).setRainfall(0.8F)));
registerBiome(161, "mutated_redwood_taiga_hills", new BiomeTaiga(BiomeTaiga.Type.MEGA_SPRUCE, (new Biome.BiomeProperties("Redwood Taiga Hills M")).setBaseBiome("redwood_taiga_hills").setBaseHeight(0.2F).setHeightVariation(0.2F).setTemperature(0.25F).setRainfall(0.8F)));
registerBiome(162, "mutated_extreme_hills_with_trees", new BiomeHills(BiomeHills.Type.MUTATED, (new Biome.BiomeProperties("Extreme Hills+ M")).setBaseBiome("extreme_hills_with_trees").setBaseHeight(1.0F).setHeightVariation(0.5F).setTemperature(0.2F).setRainfall(0.3F)));
registerBiome(163, "mutated_savanna", new BiomeSavannaMutated((new Biome.BiomeProperties("Savanna M")).setBaseBiome("savanna").setBaseHeight(0.3625F).setHeightVariation(1.225F).setTemperature(1.1F).setRainfall(0.0F).setRainDisabled()));
registerBiome(164, "mutated_savanna_rock", new BiomeSavannaMutated((new Biome.BiomeProperties("Savanna Plateau M")).setBaseBiome("savanna_rock").setBaseHeight(1.05F).setHeightVariation(1.2125001F).setTemperature(1.0F).setRainfall(0.0F).setRainDisabled()));
registerBiome(165, "mutated_mesa", new BiomeMesa(true, false, (new Biome.BiomeProperties("Mesa (Bryce)")).setBaseBiome("mesa").setTemperature(2.0F).setRainfall(0.0F).setRainDisabled()));
registerBiome(166, "mutated_mesa_rock", new BiomeMesa(false, true, (new Biome.BiomeProperties("Mesa Plateau F M")).setBaseBiome("mesa_rock").setBaseHeight(0.45F).setHeightVariation(0.3F).setTemperature(2.0F).setRainfall(0.0F).setRainDisabled()));
registerBiome(167, "mutated_mesa_clear_rock", new BiomeMesa(false, false, (new Biome.BiomeProperties("Mesa Plateau M")).setBaseBiome("mesa_clear_rock").setBaseHeight(0.45F).setHeightVariation(0.3F).setTemperature(2.0F).setRainfall(0.0F).setRainDisabled()));
}
/**
* Registers a new biome into the registry.
*/
public static void registerBiome(int id, String name, Biome biome)
{
REGISTRY.register(id, new ResourceLocation(name), biome);
if (biome.isMutation())
{
MUTATION_TO_BASE_ID_MAP.put(biome, getIdForBiome(REGISTRY.getObject(new ResourceLocation(biome.baseBiomeRegName))));
}
}
public static class BiomeProperties
{
private final String biomeName;
private float baseHeight = 0.1F;
private float heightVariation = 0.2F;
private float temperature = 0.5F;
private float rainfall = 0.5F;
private int waterColor = 16777215;
private boolean enableSnow;
private boolean enableRain = true;
@Nullable
private String baseBiomeRegName;
public BiomeProperties(String nameIn)
{
this.biomeName = nameIn;
}
public Biome.BiomeProperties setTemperature(float temperatureIn)
{
if (temperatureIn > 0.1F && temperatureIn < 0.2F)
{
throw new IllegalArgumentException("Please avoid temperatures in the range 0.1 - 0.2 because of snow");
}
else
{
this.temperature = temperatureIn;
return this;
}
}
public Biome.BiomeProperties setRainfall(float rainfallIn)
{
this.rainfall = rainfallIn;
return this;
}
public Biome.BiomeProperties setBaseHeight(float baseHeightIn)
{
this.baseHeight = baseHeightIn;
return this;
}
public Biome.BiomeProperties setHeightVariation(float heightVariationIn)
{
this.heightVariation = heightVariationIn;
return this;
}
public Biome.BiomeProperties setRainDisabled()
{
this.enableRain = false;
return this;
}
public Biome.BiomeProperties setSnowEnabled()
{
this.enableSnow = true;
return this;
}
public Biome.BiomeProperties setWaterColor(int waterColorIn)
{
this.waterColor = waterColorIn;
return this;
}
public Biome.BiomeProperties setBaseBiome(String nameIn)
{
this.baseBiomeRegName = nameIn;
return this;
}
}
public static class SpawnListEntry extends WeightedRandom.Item
{
public Class <? extends EntityLiving > entityClass;
public int minGroupCount;
public int maxGroupCount;
private final java.lang.reflect.Constructor<? extends EntityLiving> ctr;
public SpawnListEntry(Class <? extends EntityLiving > entityclassIn, int weight, int groupCountMin, int groupCountMax)
{
super(weight);
this.entityClass = entityclassIn;
this.minGroupCount = groupCountMin;
this.maxGroupCount = groupCountMax;
try
{
ctr = entityclassIn.getConstructor(World.class);
}
catch (NoSuchMethodException e)
{
throw new RuntimeException(e);
}
}
public String toString()
{
return this.entityClass.getSimpleName() + "*(" + this.minGroupCount + "-" + this.maxGroupCount + "):" + this.itemWeight;
}
public EntityLiving newInstance(World world) throws Exception
{
return ctr.newInstance(world);
}
}
public static enum TempCategory
{
OCEAN,
COLD,
MEDIUM,
WARM;
}
}

View File

@@ -0,0 +1,18 @@
package net.minecraft.world.biome;
import net.minecraft.init.Blocks;
public class BiomeBeach extends Biome
{
public BiomeBeach(Biome.BiomeProperties properties)
{
super(properties);
this.spawnableCreatureList.clear();
this.topBlock = Blocks.SAND.getDefaultState();
this.fillerBlock = Blocks.SAND.getDefaultState();
this.decorator.treesPerChunk = -999;
this.decorator.deadBushPerChunk = 0;
this.decorator.reedsPerChunk = 0;
this.decorator.cactiPerChunk = 0;
}
}

View File

@@ -0,0 +1,113 @@
package net.minecraft.world.biome;
import com.google.common.collect.Lists;
import it.unimi.dsi.fastutil.longs.Long2ObjectMap;
import it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap;
import java.util.List;
import net.minecraft.server.MinecraftServer;
public class BiomeCache
{
/** Reference to the WorldChunkManager */
private final BiomeProvider provider;
/** The last time this BiomeCache was cleaned, in milliseconds. */
private long lastCleanupTime;
/** The map of keys to BiomeCacheBlocks. Keys are based on the chunk x, z coordinates as (x | z << 32). */
private final Long2ObjectMap<BiomeCache.Block> cacheMap = new Long2ObjectOpenHashMap<BiomeCache.Block>(4096);
/** The list of cached BiomeCacheBlocks */
private final List<BiomeCache.Block> cache = Lists.<BiomeCache.Block>newArrayList();
public BiomeCache(BiomeProvider provider)
{
this.provider = provider;
}
/**
* Returns a biome cache block at location specified.
*/
public BiomeCache.Block getEntry(int x, int z)
{
x = x >> 4;
z = z >> 4;
long i = (long)x & 4294967295L | ((long)z & 4294967295L) << 32;
BiomeCache.Block biomecache$block = (BiomeCache.Block)this.cacheMap.get(i);
if (biomecache$block == null)
{
biomecache$block = new BiomeCache.Block(x, z);
this.cacheMap.put(i, biomecache$block);
this.cache.add(biomecache$block);
}
biomecache$block.lastAccessTime = MinecraftServer.getCurrentTimeMillis();
return biomecache$block;
}
public Biome getBiome(int x, int z, Biome defaultValue)
{
Biome biome = this.getEntry(x, z).getBiome(x, z);
return biome == null ? defaultValue : biome;
}
/**
* Removes BiomeCacheBlocks from this cache that haven't been accessed in at least 30 seconds.
*/
public void cleanupCache()
{
long i = MinecraftServer.getCurrentTimeMillis();
long j = i - this.lastCleanupTime;
if (j > 7500L || j < 0L)
{
this.lastCleanupTime = i;
for (int k = 0; k < this.cache.size(); ++k)
{
BiomeCache.Block biomecache$block = this.cache.get(k);
long l = i - biomecache$block.lastAccessTime;
if (l > 30000L || l < 0L)
{
this.cache.remove(k--);
long i1 = (long)biomecache$block.x & 4294967295L | ((long)biomecache$block.z & 4294967295L) << 32;
this.cacheMap.remove(i1);
}
}
}
}
/**
* Returns the array of cached biome types in the BiomeCacheBlock at the given location.
*/
public Biome[] getCachedBiomes(int x, int z)
{
return this.getEntry(x, z).biomes;
}
public class Block
{
/** Flattened 16 * 16 array of the biomes in this chunk */
public Biome[] biomes = new Biome[256];
/** World x coordinate of this entry, rounded down to nearest chunk */
public int x;
/** World z coordinate of this entry, rounded down to nearest chunk */
public int z;
/** The last time this BiomeCacheBlock was accessed, in milliseconds. */
public long lastAccessTime;
public Block(int x, int z)
{
this.x = x;
this.z = z;
BiomeCache.this.provider.getBiomes(this.biomes, x << 4, z << 4, 16, 16, false);
}
/**
* Returns the BiomeGenBase related to the x, z position from the cache block.
*/
public Biome getBiome(int x, int z)
{
return this.biomes[x & 15 | (z & 15) << 4];
}
}
}

View File

@@ -0,0 +1,70 @@
package net.minecraft.world.biome;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.IBlockAccess;
import net.minecraftforge.fml.relauncher.Side;
import net.minecraftforge.fml.relauncher.SideOnly;
@SideOnly(Side.CLIENT)
public class BiomeColorHelper
{
private static final BiomeColorHelper.ColorResolver GRASS_COLOR = new BiomeColorHelper.ColorResolver()
{
public int getColorAtPos(Biome biome, BlockPos blockPosition)
{
return biome.getGrassColorAtPos(blockPosition);
}
};
private static final BiomeColorHelper.ColorResolver FOLIAGE_COLOR = new BiomeColorHelper.ColorResolver()
{
public int getColorAtPos(Biome biome, BlockPos blockPosition)
{
return biome.getFoliageColorAtPos(blockPosition);
}
};
private static final BiomeColorHelper.ColorResolver WATER_COLOR = new BiomeColorHelper.ColorResolver()
{
public int getColorAtPos(Biome biome, BlockPos blockPosition)
{
return biome.getWaterColor();
}
};
private static int getColorAtPos(IBlockAccess blockAccess, BlockPos pos, BiomeColorHelper.ColorResolver colorResolver)
{
int i = 0;
int j = 0;
int k = 0;
for (BlockPos.MutableBlockPos blockpos$mutableblockpos : BlockPos.getAllInBoxMutable(pos.add(-1, 0, -1), pos.add(1, 0, 1)))
{
int l = colorResolver.getColorAtPos(blockAccess.getBiome(blockpos$mutableblockpos), blockpos$mutableblockpos);
i += (l & 16711680) >> 16;
j += (l & 65280) >> 8;
k += l & 255;
}
return (i / 9 & 255) << 16 | (j / 9 & 255) << 8 | k / 9 & 255;
}
public static int getGrassColorAtPos(IBlockAccess blockAccess, BlockPos pos)
{
return getColorAtPos(blockAccess, pos, GRASS_COLOR);
}
public static int getFoliageColorAtPos(IBlockAccess blockAccess, BlockPos pos)
{
return getColorAtPos(blockAccess, pos, FOLIAGE_COLOR);
}
public static int getWaterColorAtPos(IBlockAccess blockAccess, BlockPos pos)
{
return getColorAtPos(blockAccess, pos, WATER_COLOR);
}
@SideOnly(Side.CLIENT)
interface ColorResolver
{
int getColorAtPos(Biome biome, BlockPos blockPosition);
}
}

View File

@@ -0,0 +1,476 @@
package net.minecraft.world.biome;
import java.util.Random;
import net.minecraft.block.BlockFlower;
import net.minecraft.block.BlockStone;
import net.minecraft.block.material.Material;
import net.minecraft.init.Blocks;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.World;
import net.minecraft.world.gen.ChunkGeneratorSettings;
import net.minecraft.world.gen.feature.WorldGenAbstractTree;
import net.minecraft.world.gen.feature.WorldGenBigMushroom;
import net.minecraft.world.gen.feature.WorldGenBush;
import net.minecraft.world.gen.feature.WorldGenCactus;
import net.minecraft.world.gen.feature.WorldGenClay;
import net.minecraft.world.gen.feature.WorldGenDeadBush;
import net.minecraft.world.gen.feature.WorldGenFlowers;
import net.minecraft.world.gen.feature.WorldGenLiquids;
import net.minecraft.world.gen.feature.WorldGenMinable;
import net.minecraft.world.gen.feature.WorldGenPumpkin;
import net.minecraft.world.gen.feature.WorldGenReed;
import net.minecraft.world.gen.feature.WorldGenSand;
import net.minecraft.world.gen.feature.WorldGenWaterlily;
import net.minecraft.world.gen.feature.WorldGenerator;
public class BiomeDecorator
{
public boolean decorating;
public BlockPos chunkPos;
public ChunkGeneratorSettings chunkProviderSettings;
/** The clay generator. */
public WorldGenerator clayGen = new WorldGenClay(4);
/** The sand generator. */
public WorldGenerator sandGen = new WorldGenSand(Blocks.SAND, 7);
/** The gravel generator. */
public WorldGenerator gravelGen = new WorldGenSand(Blocks.GRAVEL, 6);
/** The dirt generator. */
public WorldGenerator dirtGen;
public WorldGenerator gravelOreGen;
public WorldGenerator graniteGen;
public WorldGenerator dioriteGen;
public WorldGenerator andesiteGen;
public WorldGenerator coalGen;
public WorldGenerator ironGen;
/** Field that holds gold WorldGenMinable */
public WorldGenerator goldGen;
public WorldGenerator redstoneGen;
public WorldGenerator diamondGen;
/** Field that holds Lapis WorldGenMinable */
public WorldGenerator lapisGen;
public WorldGenFlowers flowerGen = new WorldGenFlowers(Blocks.YELLOW_FLOWER, BlockFlower.EnumFlowerType.DANDELION);
/** Field that holds mushroomBrown WorldGenFlowers */
public WorldGenerator mushroomBrownGen = new WorldGenBush(Blocks.BROWN_MUSHROOM);
/** Field that holds mushroomRed WorldGenFlowers */
public WorldGenerator mushroomRedGen = new WorldGenBush(Blocks.RED_MUSHROOM);
/** Field that holds big mushroom generator */
public WorldGenerator bigMushroomGen = new WorldGenBigMushroom();
/** Field that holds WorldGenReed */
public WorldGenerator reedGen = new WorldGenReed();
/** Field that holds WorldGenCactus */
public WorldGenerator cactusGen = new WorldGenCactus();
/** The water lily generation! */
public WorldGenerator waterlilyGen = new WorldGenWaterlily();
/** Amount of waterlilys per chunk. */
public int waterlilyPerChunk;
/** The number of trees to attempt to generate per chunk. Up to 10 in forests, none in deserts. */
public int treesPerChunk;
public float extraTreeChance = 0.1F;
/**
* The number of yellow flower patches to generate per chunk. The game generates much less than this number, since
* it attempts to generate them at a random altitude.
*/
public int flowersPerChunk = 2;
/** The amount of tall grass to generate per chunk. */
public int grassPerChunk = 1;
/** The number of dead bushes to generate per chunk. Used in deserts and swamps. */
public int deadBushPerChunk;
/**
* The number of extra mushroom patches per chunk. It generates 1/4 this number in brown mushroom patches, and 1/8
* this number in red mushroom patches. These mushrooms go beyond the default base number of mushrooms.
*/
public int mushroomsPerChunk;
/** The number of reeds to generate per chunk. Reeds won't generate if the randomly selected placement is unsuitable. */
public int reedsPerChunk;
/** The number of cactus plants to generate per chunk. Cacti only work on sand. */
public int cactiPerChunk;
/** The number of gravel patches to generate per chunk. */
public int gravelPatchesPerChunk = 1;
/** The number of sand patches to generate per chunk. Sand patches only generate when part of it is underwater. */
public int sandPatchesPerChunk = 3;
/** The number of clay patches to generate per chunk. Only generates when part of it is underwater. */
public int clayPerChunk = 1;
/** Amount of big mushrooms per chunk */
public int bigMushroomsPerChunk;
/** True if decorator should generate surface lava & water */
public boolean generateFalls = true;
public void decorate(World worldIn, Random random, Biome biome, BlockPos pos)
{
if (this.decorating)
{
throw new RuntimeException("Already decorating");
}
else
{
this.chunkProviderSettings = ChunkGeneratorSettings.Factory.jsonToFactory(worldIn.getWorldInfo().getGeneratorOptions()).build();
this.chunkPos = pos;
this.dirtGen = new WorldGenMinable(Blocks.DIRT.getDefaultState(), this.chunkProviderSettings.dirtSize);
this.gravelOreGen = new WorldGenMinable(Blocks.GRAVEL.getDefaultState(), this.chunkProviderSettings.gravelSize);
this.graniteGen = new WorldGenMinable(Blocks.STONE.getDefaultState().withProperty(BlockStone.VARIANT, BlockStone.EnumType.GRANITE), this.chunkProviderSettings.graniteSize);
this.dioriteGen = new WorldGenMinable(Blocks.STONE.getDefaultState().withProperty(BlockStone.VARIANT, BlockStone.EnumType.DIORITE), this.chunkProviderSettings.dioriteSize);
this.andesiteGen = new WorldGenMinable(Blocks.STONE.getDefaultState().withProperty(BlockStone.VARIANT, BlockStone.EnumType.ANDESITE), this.chunkProviderSettings.andesiteSize);
this.coalGen = new WorldGenMinable(Blocks.COAL_ORE.getDefaultState(), this.chunkProviderSettings.coalSize);
this.ironGen = new WorldGenMinable(Blocks.IRON_ORE.getDefaultState(), this.chunkProviderSettings.ironSize);
this.goldGen = new WorldGenMinable(Blocks.GOLD_ORE.getDefaultState(), this.chunkProviderSettings.goldSize);
this.redstoneGen = new WorldGenMinable(Blocks.REDSTONE_ORE.getDefaultState(), this.chunkProviderSettings.redstoneSize);
this.diamondGen = new WorldGenMinable(Blocks.DIAMOND_ORE.getDefaultState(), this.chunkProviderSettings.diamondSize);
this.lapisGen = new WorldGenMinable(Blocks.LAPIS_ORE.getDefaultState(), this.chunkProviderSettings.lapisSize);
this.genDecorations(biome, worldIn, random);
this.decorating = false;
}
}
protected void genDecorations(Biome biomeIn, World worldIn, Random random)
{
net.minecraft.util.math.ChunkPos forgeChunkPos = new net.minecraft.util.math.ChunkPos(chunkPos); // actual ChunkPos instead of BlockPos, used for events
net.minecraftforge.common.MinecraftForge.EVENT_BUS.post(new net.minecraftforge.event.terraingen.DecorateBiomeEvent.Pre(worldIn, random, forgeChunkPos));
this.generateOres(worldIn, random);
if(net.minecraftforge.event.terraingen.TerrainGen.decorate(worldIn, random, forgeChunkPos, net.minecraftforge.event.terraingen.DecorateBiomeEvent.Decorate.EventType.SAND))
for (int i = 0; i < this.sandPatchesPerChunk; ++i)
{
int j = random.nextInt(16) + 8;
int k = random.nextInt(16) + 8;
this.sandGen.generate(worldIn, random, worldIn.getTopSolidOrLiquidBlock(this.chunkPos.add(j, 0, k)));
}
if(net.minecraftforge.event.terraingen.TerrainGen.decorate(worldIn, random, forgeChunkPos, net.minecraftforge.event.terraingen.DecorateBiomeEvent.Decorate.EventType.CLAY))
for (int i1 = 0; i1 < this.clayPerChunk; ++i1)
{
int l1 = random.nextInt(16) + 8;
int i6 = random.nextInt(16) + 8;
this.clayGen.generate(worldIn, random, worldIn.getTopSolidOrLiquidBlock(this.chunkPos.add(l1, 0, i6)));
}
if(net.minecraftforge.event.terraingen.TerrainGen.decorate(worldIn, random, forgeChunkPos, net.minecraftforge.event.terraingen.DecorateBiomeEvent.Decorate.EventType.SAND_PASS2))
for (int j1 = 0; j1 < this.gravelPatchesPerChunk; ++j1)
{
int i2 = random.nextInt(16) + 8;
int j6 = random.nextInt(16) + 8;
this.gravelGen.generate(worldIn, random, worldIn.getTopSolidOrLiquidBlock(this.chunkPos.add(i2, 0, j6)));
}
int k1 = this.treesPerChunk;
if (random.nextFloat() < this.extraTreeChance)
{
++k1;
}
if(net.minecraftforge.event.terraingen.TerrainGen.decorate(worldIn, random, forgeChunkPos, net.minecraftforge.event.terraingen.DecorateBiomeEvent.Decorate.EventType.TREE))
for (int j2 = 0; j2 < k1; ++j2)
{
int k6 = random.nextInt(16) + 8;
int l = random.nextInt(16) + 8;
WorldGenAbstractTree worldgenabstracttree = biomeIn.getRandomTreeFeature(random);
worldgenabstracttree.setDecorationDefaults();
BlockPos blockpos = worldIn.getHeight(this.chunkPos.add(k6, 0, l));
if (worldgenabstracttree.generate(worldIn, random, blockpos))
{
worldgenabstracttree.generateSaplings(worldIn, random, blockpos);
}
}
if(net.minecraftforge.event.terraingen.TerrainGen.decorate(worldIn, random, forgeChunkPos, net.minecraftforge.event.terraingen.DecorateBiomeEvent.Decorate.EventType.BIG_SHROOM))
for (int k2 = 0; k2 < this.bigMushroomsPerChunk; ++k2)
{
int l6 = random.nextInt(16) + 8;
int k10 = random.nextInt(16) + 8;
this.bigMushroomGen.generate(worldIn, random, worldIn.getHeight(this.chunkPos.add(l6, 0, k10)));
}
if(net.minecraftforge.event.terraingen.TerrainGen.decorate(worldIn, random, forgeChunkPos, net.minecraftforge.event.terraingen.DecorateBiomeEvent.Decorate.EventType.FLOWERS))
for (int l2 = 0; l2 < this.flowersPerChunk; ++l2)
{
int i7 = random.nextInt(16) + 8;
int l10 = random.nextInt(16) + 8;
int j14 = worldIn.getHeight(this.chunkPos.add(i7, 0, l10)).getY() + 32;
if (j14 > 0)
{
int k17 = random.nextInt(j14);
BlockPos blockpos1 = this.chunkPos.add(i7, k17, l10);
BlockFlower.EnumFlowerType blockflower$enumflowertype = biomeIn.pickRandomFlower(random, blockpos1);
BlockFlower blockflower = blockflower$enumflowertype.getBlockType().getBlock();
if (blockflower.getDefaultState().getMaterial() != Material.AIR)
{
this.flowerGen.setGeneratedBlock(blockflower, blockflower$enumflowertype);
this.flowerGen.generate(worldIn, random, blockpos1);
}
}
}
if(net.minecraftforge.event.terraingen.TerrainGen.decorate(worldIn, random, forgeChunkPos, net.minecraftforge.event.terraingen.DecorateBiomeEvent.Decorate.EventType.GRASS))
for (int i3 = 0; i3 < this.grassPerChunk; ++i3)
{
int j7 = random.nextInt(16) + 8;
int i11 = random.nextInt(16) + 8;
int k14 = worldIn.getHeight(this.chunkPos.add(j7, 0, i11)).getY() * 2;
if (k14 > 0)
{
int l17 = random.nextInt(k14);
biomeIn.getRandomWorldGenForGrass(random).generate(worldIn, random, this.chunkPos.add(j7, l17, i11));
}
}
if(net.minecraftforge.event.terraingen.TerrainGen.decorate(worldIn, random, forgeChunkPos, net.minecraftforge.event.terraingen.DecorateBiomeEvent.Decorate.EventType.DEAD_BUSH))
for (int j3 = 0; j3 < this.deadBushPerChunk; ++j3)
{
int k7 = random.nextInt(16) + 8;
int j11 = random.nextInt(16) + 8;
int l14 = worldIn.getHeight(this.chunkPos.add(k7, 0, j11)).getY() * 2;
if (l14 > 0)
{
int i18 = random.nextInt(l14);
(new WorldGenDeadBush()).generate(worldIn, random, this.chunkPos.add(k7, i18, j11));
}
}
if(net.minecraftforge.event.terraingen.TerrainGen.decorate(worldIn, random, forgeChunkPos, net.minecraftforge.event.terraingen.DecorateBiomeEvent.Decorate.EventType.LILYPAD))
for (int k3 = 0; k3 < this.waterlilyPerChunk; ++k3)
{
int l7 = random.nextInt(16) + 8;
int k11 = random.nextInt(16) + 8;
int i15 = worldIn.getHeight(this.chunkPos.add(l7, 0, k11)).getY() * 2;
if (i15 > 0)
{
int j18 = random.nextInt(i15);
BlockPos blockpos4;
BlockPos blockpos7;
for (blockpos4 = this.chunkPos.add(l7, j18, k11); blockpos4.getY() > 0; blockpos4 = blockpos7)
{
blockpos7 = blockpos4.down();
if (!worldIn.isAirBlock(blockpos7))
{
break;
}
}
this.waterlilyGen.generate(worldIn, random, blockpos4);
}
}
if(net.minecraftforge.event.terraingen.TerrainGen.decorate(worldIn, random, forgeChunkPos, net.minecraftforge.event.terraingen.DecorateBiomeEvent.Decorate.EventType.SHROOM))
{
for (int l3 = 0; l3 < this.mushroomsPerChunk; ++l3)
{
if (random.nextInt(4) == 0)
{
int i8 = random.nextInt(16) + 8;
int l11 = random.nextInt(16) + 8;
BlockPos blockpos2 = worldIn.getHeight(this.chunkPos.add(i8, 0, l11));
this.mushroomBrownGen.generate(worldIn, random, blockpos2);
}
if (random.nextInt(8) == 0)
{
int j8 = random.nextInt(16) + 8;
int i12 = random.nextInt(16) + 8;
int j15 = worldIn.getHeight(this.chunkPos.add(j8, 0, i12)).getY() * 2;
if (j15 > 0)
{
int k18 = random.nextInt(j15);
BlockPos blockpos5 = this.chunkPos.add(j8, k18, i12);
this.mushroomRedGen.generate(worldIn, random, blockpos5);
}
}
}
if (random.nextInt(4) == 0)
{
int i4 = random.nextInt(16) + 8;
int k8 = random.nextInt(16) + 8;
int j12 = worldIn.getHeight(this.chunkPos.add(i4, 0, k8)).getY() * 2;
if (j12 > 0)
{
int k15 = random.nextInt(j12);
this.mushroomBrownGen.generate(worldIn, random, this.chunkPos.add(i4, k15, k8));
}
}
if (random.nextInt(8) == 0)
{
int j4 = random.nextInt(16) + 8;
int l8 = random.nextInt(16) + 8;
int k12 = worldIn.getHeight(this.chunkPos.add(j4, 0, l8)).getY() * 2;
if (k12 > 0)
{
int l15 = random.nextInt(k12);
this.mushroomRedGen.generate(worldIn, random, this.chunkPos.add(j4, l15, l8));
}
}
} // End of Mushroom generation
if(net.minecraftforge.event.terraingen.TerrainGen.decorate(worldIn, random, forgeChunkPos, net.minecraftforge.event.terraingen.DecorateBiomeEvent.Decorate.EventType.REED))
{
for (int k4 = 0; k4 < this.reedsPerChunk; ++k4)
{
int i9 = random.nextInt(16) + 8;
int l12 = random.nextInt(16) + 8;
int i16 = worldIn.getHeight(this.chunkPos.add(i9, 0, l12)).getY() * 2;
if (i16 > 0)
{
int l18 = random.nextInt(i16);
this.reedGen.generate(worldIn, random, this.chunkPos.add(i9, l18, l12));
}
}
for (int l4 = 0; l4 < 10; ++l4)
{
int j9 = random.nextInt(16) + 8;
int i13 = random.nextInt(16) + 8;
int j16 = worldIn.getHeight(this.chunkPos.add(j9, 0, i13)).getY() * 2;
if (j16 > 0)
{
int i19 = random.nextInt(j16);
this.reedGen.generate(worldIn, random, this.chunkPos.add(j9, i19, i13));
}
}
} // End of Reed generation
if(net.minecraftforge.event.terraingen.TerrainGen.decorate(worldIn, random, forgeChunkPos, net.minecraftforge.event.terraingen.DecorateBiomeEvent.Decorate.EventType.PUMPKIN))
if (random.nextInt(32) == 0)
{
int i5 = random.nextInt(16) + 8;
int k9 = random.nextInt(16) + 8;
int j13 = worldIn.getHeight(this.chunkPos.add(i5, 0, k9)).getY() * 2;
if (j13 > 0)
{
int k16 = random.nextInt(j13);
(new WorldGenPumpkin()).generate(worldIn, random, this.chunkPos.add(i5, k16, k9));
}
}
if(net.minecraftforge.event.terraingen.TerrainGen.decorate(worldIn, random, forgeChunkPos, net.minecraftforge.event.terraingen.DecorateBiomeEvent.Decorate.EventType.CACTUS))
for (int j5 = 0; j5 < this.cactiPerChunk; ++j5)
{
int l9 = random.nextInt(16) + 8;
int k13 = random.nextInt(16) + 8;
int l16 = worldIn.getHeight(this.chunkPos.add(l9, 0, k13)).getY() * 2;
if (l16 > 0)
{
int j19 = random.nextInt(l16);
this.cactusGen.generate(worldIn, random, this.chunkPos.add(l9, j19, k13));
}
}
if (this.generateFalls)
{
if(net.minecraftforge.event.terraingen.TerrainGen.decorate(worldIn, random, forgeChunkPos, net.minecraftforge.event.terraingen.DecorateBiomeEvent.Decorate.EventType.LAKE_WATER))
for (int k5 = 0; k5 < 50; ++k5)
{
int i10 = random.nextInt(16) + 8;
int l13 = random.nextInt(16) + 8;
int i17 = random.nextInt(248) + 8;
if (i17 > 0)
{
int k19 = random.nextInt(i17);
BlockPos blockpos6 = this.chunkPos.add(i10, k19, l13);
(new WorldGenLiquids(Blocks.FLOWING_WATER)).generate(worldIn, random, blockpos6);
}
}
if(net.minecraftforge.event.terraingen.TerrainGen.decorate(worldIn, random, forgeChunkPos, net.minecraftforge.event.terraingen.DecorateBiomeEvent.Decorate.EventType.LAKE_LAVA))
for (int l5 = 0; l5 < 20; ++l5)
{
int j10 = random.nextInt(16) + 8;
int i14 = random.nextInt(16) + 8;
int j17 = random.nextInt(random.nextInt(random.nextInt(240) + 8) + 8);
BlockPos blockpos3 = this.chunkPos.add(j10, j17, i14);
(new WorldGenLiquids(Blocks.FLOWING_LAVA)).generate(worldIn, random, blockpos3);
}
}
net.minecraftforge.common.MinecraftForge.EVENT_BUS.post(new net.minecraftforge.event.terraingen.DecorateBiomeEvent.Post(worldIn, random, forgeChunkPos));
}
/**
* Generates ores in the current chunk
*/
protected void generateOres(World worldIn, Random random)
{
net.minecraftforge.common.MinecraftForge.ORE_GEN_BUS.post(new net.minecraftforge.event.terraingen.OreGenEvent.Pre(worldIn, random, chunkPos));
if (net.minecraftforge.event.terraingen.TerrainGen.generateOre(worldIn, random, dirtGen, chunkPos, net.minecraftforge.event.terraingen.OreGenEvent.GenerateMinable.EventType.DIRT))
this.genStandardOre1(worldIn, random, this.chunkProviderSettings.dirtCount, this.dirtGen, this.chunkProviderSettings.dirtMinHeight, this.chunkProviderSettings.dirtMaxHeight);
if (net.minecraftforge.event.terraingen.TerrainGen.generateOre(worldIn, random, gravelOreGen, chunkPos, net.minecraftforge.event.terraingen.OreGenEvent.GenerateMinable.EventType.GRAVEL))
this.genStandardOre1(worldIn, random, this.chunkProviderSettings.gravelCount, this.gravelOreGen, this.chunkProviderSettings.gravelMinHeight, this.chunkProviderSettings.gravelMaxHeight);
if (net.minecraftforge.event.terraingen.TerrainGen.generateOre(worldIn, random, dioriteGen, chunkPos, net.minecraftforge.event.terraingen.OreGenEvent.GenerateMinable.EventType.DIORITE))
this.genStandardOre1(worldIn, random, this.chunkProviderSettings.dioriteCount, this.dioriteGen, this.chunkProviderSettings.dioriteMinHeight, this.chunkProviderSettings.dioriteMaxHeight);
if (net.minecraftforge.event.terraingen.TerrainGen.generateOre(worldIn, random, graniteGen, chunkPos, net.minecraftforge.event.terraingen.OreGenEvent.GenerateMinable.EventType.GRANITE))
this.genStandardOre1(worldIn, random, this.chunkProviderSettings.graniteCount, this.graniteGen, this.chunkProviderSettings.graniteMinHeight, this.chunkProviderSettings.graniteMaxHeight);
if (net.minecraftforge.event.terraingen.TerrainGen.generateOre(worldIn, random, andesiteGen, chunkPos, net.minecraftforge.event.terraingen.OreGenEvent.GenerateMinable.EventType.ANDESITE))
this.genStandardOre1(worldIn, random, this.chunkProviderSettings.andesiteCount, this.andesiteGen, this.chunkProviderSettings.andesiteMinHeight, this.chunkProviderSettings.andesiteMaxHeight);
if (net.minecraftforge.event.terraingen.TerrainGen.generateOre(worldIn, random, coalGen, chunkPos, net.minecraftforge.event.terraingen.OreGenEvent.GenerateMinable.EventType.COAL))
this.genStandardOre1(worldIn, random, this.chunkProviderSettings.coalCount, this.coalGen, this.chunkProviderSettings.coalMinHeight, this.chunkProviderSettings.coalMaxHeight);
if (net.minecraftforge.event.terraingen.TerrainGen.generateOre(worldIn, random, ironGen, chunkPos, net.minecraftforge.event.terraingen.OreGenEvent.GenerateMinable.EventType.IRON))
this.genStandardOre1(worldIn, random, this.chunkProviderSettings.ironCount, this.ironGen, this.chunkProviderSettings.ironMinHeight, this.chunkProviderSettings.ironMaxHeight);
if (net.minecraftforge.event.terraingen.TerrainGen.generateOre(worldIn, random, goldGen, chunkPos, net.minecraftforge.event.terraingen.OreGenEvent.GenerateMinable.EventType.GOLD))
this.genStandardOre1(worldIn, random, this.chunkProviderSettings.goldCount, this.goldGen, this.chunkProviderSettings.goldMinHeight, this.chunkProviderSettings.goldMaxHeight);
if (net.minecraftforge.event.terraingen.TerrainGen.generateOre(worldIn, random, redstoneGen, chunkPos, net.minecraftforge.event.terraingen.OreGenEvent.GenerateMinable.EventType.REDSTONE))
this.genStandardOre1(worldIn, random, this.chunkProviderSettings.redstoneCount, this.redstoneGen, this.chunkProviderSettings.redstoneMinHeight, this.chunkProviderSettings.redstoneMaxHeight);
if (net.minecraftforge.event.terraingen.TerrainGen.generateOre(worldIn, random, diamondGen, chunkPos, net.minecraftforge.event.terraingen.OreGenEvent.GenerateMinable.EventType.DIAMOND))
this.genStandardOre1(worldIn, random, this.chunkProviderSettings.diamondCount, this.diamondGen, this.chunkProviderSettings.diamondMinHeight, this.chunkProviderSettings.diamondMaxHeight);
if (net.minecraftforge.event.terraingen.TerrainGen.generateOre(worldIn, random, lapisGen, chunkPos, net.minecraftforge.event.terraingen.OreGenEvent.GenerateMinable.EventType.LAPIS))
this.genStandardOre2(worldIn, random, this.chunkProviderSettings.lapisCount, this.lapisGen, this.chunkProviderSettings.lapisCenterHeight, this.chunkProviderSettings.lapisSpread);
net.minecraftforge.common.MinecraftForge.ORE_GEN_BUS.post(new net.minecraftforge.event.terraingen.OreGenEvent.Post(worldIn, random, chunkPos));
}
/**
* Standard ore generation helper. Vanilla uses this to generate most ores.
* The main difference between this and {@link #genStandardOre2} is that this takes min and max heights, while
* genStandardOre2 takes center and spread.
*/
protected void genStandardOre1(World worldIn, Random random, int blockCount, WorldGenerator generator, int minHeight, int maxHeight)
{
if (maxHeight < minHeight)
{
int i = minHeight;
minHeight = maxHeight;
maxHeight = i;
}
else if (maxHeight == minHeight)
{
if (minHeight < 255)
{
++maxHeight;
}
else
{
--minHeight;
}
}
for (int j = 0; j < blockCount; ++j)
{
BlockPos blockpos = this.chunkPos.add(random.nextInt(16), random.nextInt(maxHeight - minHeight) + minHeight, random.nextInt(16));
generator.generate(worldIn, random, blockpos);
}
}
/**
* Standard ore generation helper. Vanilla uses this to generate Lapis Lazuli.
* The main difference between this and {@link #genStandardOre1} is that this takes takes center and spread, while
* genStandardOre1 takes min and max heights.
*/
protected void genStandardOre2(World worldIn, Random random, int blockCount, WorldGenerator generator, int centerHeight, int spread)
{
for (int i = 0; i < blockCount; ++i)
{
BlockPos blockpos = this.chunkPos.add(random.nextInt(16), random.nextInt(spread) + random.nextInt(spread) + centerHeight - spread, random.nextInt(16));
generator.generate(worldIn, random, blockpos);
}
}
}

View File

@@ -0,0 +1,65 @@
package net.minecraft.world.biome;
import java.util.Iterator;
import java.util.Random;
import net.minecraft.entity.monster.EntityHusk;
import net.minecraft.entity.monster.EntityZombie;
import net.minecraft.entity.monster.EntityZombieVillager;
import net.minecraft.entity.passive.EntityRabbit;
import net.minecraft.init.Blocks;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.World;
import net.minecraft.world.gen.feature.WorldGenDesertWells;
import net.minecraft.world.gen.feature.WorldGenFossils;
public class BiomeDesert extends Biome
{
public BiomeDesert(Biome.BiomeProperties properties)
{
super(properties);
this.spawnableCreatureList.clear();
this.topBlock = Blocks.SAND.getDefaultState();
this.fillerBlock = Blocks.SAND.getDefaultState();
this.decorator.treesPerChunk = -999;
this.decorator.deadBushPerChunk = 2;
this.decorator.reedsPerChunk = 50;
this.decorator.cactiPerChunk = 10;
this.spawnableCreatureList.clear();
this.spawnableCreatureList.add(new Biome.SpawnListEntry(EntityRabbit.class, 4, 2, 3));
Iterator<Biome.SpawnListEntry> iterator = this.spawnableMonsterList.iterator();
while (iterator.hasNext())
{
Biome.SpawnListEntry biome$spawnlistentry = iterator.next();
if (biome$spawnlistentry.entityClass == EntityZombie.class || biome$spawnlistentry.entityClass == EntityZombieVillager.class)
{
iterator.remove();
}
}
this.spawnableMonsterList.add(new Biome.SpawnListEntry(EntityZombie.class, 19, 4, 4));
this.spawnableMonsterList.add(new Biome.SpawnListEntry(EntityZombieVillager.class, 1, 1, 1));
this.spawnableMonsterList.add(new Biome.SpawnListEntry(EntityHusk.class, 80, 4, 4));
}
public void decorate(World worldIn, Random rand, BlockPos pos)
{
super.decorate(worldIn, rand, pos);
if(net.minecraftforge.event.terraingen.TerrainGen.decorate(worldIn, rand, new net.minecraft.util.math.ChunkPos(pos), net.minecraftforge.event.terraingen.DecorateBiomeEvent.Decorate.EventType.DESERT_WELL))
if (rand.nextInt(1000) == 0)
{
int i = rand.nextInt(16) + 8;
int j = rand.nextInt(16) + 8;
BlockPos blockpos = worldIn.getHeight(pos.add(i, 0, j)).up();
(new WorldGenDesertWells()).generate(worldIn, rand, blockpos);
}
if(net.minecraftforge.event.terraingen.TerrainGen.decorate(worldIn, rand, new net.minecraft.util.math.ChunkPos(pos), net.minecraftforge.event.terraingen.DecorateBiomeEvent.Decorate.EventType.FOSSIL))
if (rand.nextInt(64) == 0)
{
(new WorldGenFossils()).generate(worldIn, rand, pos);
}
}
}

View File

@@ -0,0 +1,31 @@
package net.minecraft.world.biome;
import net.minecraft.entity.monster.EntityEnderman;
import net.minecraft.init.Blocks;
import net.minecraftforge.fml.relauncher.Side;
import net.minecraftforge.fml.relauncher.SideOnly;
public class BiomeEnd extends Biome
{
public BiomeEnd(Biome.BiomeProperties properties)
{
super(properties);
this.spawnableMonsterList.clear();
this.spawnableCreatureList.clear();
this.spawnableWaterCreatureList.clear();
this.spawnableCaveCreatureList.clear();
this.spawnableMonsterList.add(new Biome.SpawnListEntry(EntityEnderman.class, 10, 4, 4));
this.topBlock = Blocks.DIRT.getDefaultState();
this.fillerBlock = Blocks.DIRT.getDefaultState();
this.decorator = new BiomeEndDecorator();
}
/**
* takes temperature, returns color
*/
@SideOnly(Side.CLIENT)
public int getSkyColorByTemp(float currentTemperature)
{
return 0;
}
}

View File

@@ -0,0 +1,71 @@
package net.minecraft.world.biome;
import com.google.common.cache.CacheBuilder;
import com.google.common.cache.CacheLoader;
import com.google.common.cache.LoadingCache;
import com.google.common.collect.ContiguousSet;
import com.google.common.collect.DiscreteDomain;
import com.google.common.collect.Lists;
import com.google.common.collect.Range;
import java.util.Collections;
import java.util.List;
import java.util.Random;
import java.util.concurrent.TimeUnit;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.World;
import net.minecraft.world.gen.feature.WorldGenSpikes;
public class BiomeEndDecorator extends BiomeDecorator
{
private static final LoadingCache<Long, WorldGenSpikes.EndSpike[]> SPIKE_CACHE = CacheBuilder.newBuilder().expireAfterWrite(5L, TimeUnit.MINUTES).<Long, WorldGenSpikes.EndSpike[]>build(new BiomeEndDecorator.SpikeCacheLoader());
private final WorldGenSpikes spikeGen = new WorldGenSpikes();
protected void genDecorations(Biome biomeIn, World worldIn, Random random)
{
this.generateOres(worldIn, random);
WorldGenSpikes.EndSpike[] aworldgenspikes$endspike = getSpikesForWorld(worldIn);
for (WorldGenSpikes.EndSpike worldgenspikes$endspike : aworldgenspikes$endspike)
{
if (worldgenspikes$endspike.doesStartInChunk(this.chunkPos))
{
this.spikeGen.setSpike(worldgenspikes$endspike);
this.spikeGen.generate(worldIn, random, new BlockPos(worldgenspikes$endspike.getCenterX(), 45, worldgenspikes$endspike.getCenterZ()));
}
}
}
public static WorldGenSpikes.EndSpike[] getSpikesForWorld(World p_185426_0_)
{
Random random = new Random(p_185426_0_.getSeed());
long i = random.nextLong() & 65535L;
return SPIKE_CACHE.getUnchecked(Long.valueOf(i));
}
static class SpikeCacheLoader extends CacheLoader<Long, WorldGenSpikes.EndSpike[]>
{
private SpikeCacheLoader()
{
}
public WorldGenSpikes.EndSpike[] load(Long p_load_1_) throws Exception
{
List<Integer> list = Lists.newArrayList(ContiguousSet.create(Range.closedOpen(Integer.valueOf(0), Integer.valueOf(10)), DiscreteDomain.integers()));
Collections.shuffle(list, new Random(p_load_1_.longValue()));
WorldGenSpikes.EndSpike[] aworldgenspikes$endspike = new WorldGenSpikes.EndSpike[10];
for (int i = 0; i < 10; ++i)
{
int j = (int)(42.0D * Math.cos(2.0D * (-Math.PI + (Math.PI / 10D) * (double)i)));
int k = (int)(42.0D * Math.sin(2.0D * (-Math.PI + (Math.PI / 10D) * (double)i)));
int l = ((Integer)list.get(i)).intValue();
int i1 = 2 + l / 3;
int j1 = 76 + l * 3;
boolean flag = l == 1 || l == 2;
aworldgenspikes$endspike[i] = new WorldGenSpikes.EndSpike(j, k, i1, j1, flag);
}
return aworldgenspikes$endspike;
}
}
}

View File

@@ -0,0 +1,195 @@
package net.minecraft.world.biome;
import java.util.Random;
import net.minecraft.block.BlockDoublePlant;
import net.minecraft.block.BlockFlower;
import net.minecraft.entity.passive.EntityRabbit;
import net.minecraft.entity.passive.EntityWolf;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.MathHelper;
import net.minecraft.world.World;
import net.minecraft.world.gen.feature.WorldGenAbstractTree;
import net.minecraft.world.gen.feature.WorldGenBigMushroom;
import net.minecraft.world.gen.feature.WorldGenBirchTree;
import net.minecraft.world.gen.feature.WorldGenCanopyTree;
import net.minecraftforge.fml.relauncher.Side;
import net.minecraftforge.fml.relauncher.SideOnly;
public class BiomeForest extends Biome
{
protected static final WorldGenBirchTree SUPER_BIRCH_TREE = new WorldGenBirchTree(false, true);
protected static final WorldGenBirchTree BIRCH_TREE = new WorldGenBirchTree(false, false);
protected static final WorldGenCanopyTree ROOF_TREE = new WorldGenCanopyTree(false);
private final BiomeForest.Type type;
public BiomeForest(BiomeForest.Type typeIn, Biome.BiomeProperties properties)
{
super(properties);
this.type = typeIn;
this.decorator.treesPerChunk = 10;
this.decorator.grassPerChunk = 2;
if (this.type == BiomeForest.Type.FLOWER)
{
this.decorator.treesPerChunk = 6;
this.decorator.flowersPerChunk = 100;
this.decorator.grassPerChunk = 1;
this.spawnableCreatureList.add(new Biome.SpawnListEntry(EntityRabbit.class, 4, 2, 3));
}
if (this.type == BiomeForest.Type.NORMAL)
{
this.spawnableCreatureList.add(new Biome.SpawnListEntry(EntityWolf.class, 5, 4, 4));
}
if (this.type == BiomeForest.Type.ROOFED)
{
this.decorator.treesPerChunk = -999;
}
if (this.type == BiomeForest.Type.FLOWER) //Needs to be done here so we have access to this.type
{
this.flowers.clear();
for (BlockFlower.EnumFlowerType type : BlockFlower.EnumFlowerType.values())
{
if (type.getBlockType() == BlockFlower.EnumFlowerColor.YELLOW) continue;
if (type == BlockFlower.EnumFlowerType.BLUE_ORCHID) type = BlockFlower.EnumFlowerType.POPPY;
addFlower(net.minecraft.init.Blocks.RED_FLOWER.getDefaultState().withProperty(net.minecraft.init.Blocks.RED_FLOWER.getTypeProperty(), type), 10);
}
}
}
public WorldGenAbstractTree getRandomTreeFeature(Random rand)
{
if (this.type == BiomeForest.Type.ROOFED && rand.nextInt(3) > 0)
{
return ROOF_TREE;
}
else if (this.type != BiomeForest.Type.BIRCH && rand.nextInt(5) != 0)
{
return (WorldGenAbstractTree)(rand.nextInt(10) == 0 ? BIG_TREE_FEATURE : TREE_FEATURE);
}
else
{
return BIRCH_TREE;
}
}
public BlockFlower.EnumFlowerType pickRandomFlower(Random rand, BlockPos pos)
{
if (this.type == BiomeForest.Type.FLOWER)
{
double d0 = MathHelper.clamp((1.0D + GRASS_COLOR_NOISE.getValue((double)pos.getX() / 48.0D, (double)pos.getZ() / 48.0D)) / 2.0D, 0.0D, 0.9999D);
BlockFlower.EnumFlowerType blockflower$enumflowertype = BlockFlower.EnumFlowerType.values()[(int)(d0 * (double)BlockFlower.EnumFlowerType.values().length)];
return blockflower$enumflowertype == BlockFlower.EnumFlowerType.BLUE_ORCHID ? BlockFlower.EnumFlowerType.POPPY : blockflower$enumflowertype;
}
else
{
return super.pickRandomFlower(rand, pos);
}
}
public void decorate(World worldIn, Random rand, BlockPos pos)
{
if (this.type == BiomeForest.Type.ROOFED)
{
this.addMushrooms(worldIn, rand, pos);
}
if(net.minecraftforge.event.terraingen.TerrainGen.decorate(worldIn, rand, new net.minecraft.util.math.ChunkPos(pos), net.minecraftforge.event.terraingen.DecorateBiomeEvent.Decorate.EventType.FLOWERS))
{ // no tab for patch
int i = rand.nextInt(5) - 3;
if (this.type == BiomeForest.Type.FLOWER)
{
i += 2;
}
this.addDoublePlants(worldIn, rand, pos, i);
}
super.decorate(worldIn, rand, pos);
}
public void addMushrooms(World p_185379_1_, Random p_185379_2_, BlockPos p_185379_3_)
{
for (int i = 0; i < 4; ++i)
{
for (int j = 0; j < 4; ++j)
{
int k = i * 4 + 1 + 8 + p_185379_2_.nextInt(3);
int l = j * 4 + 1 + 8 + p_185379_2_.nextInt(3);
BlockPos blockpos = p_185379_1_.getHeight(p_185379_3_.add(k, 0, l));
if (p_185379_2_.nextInt(20) == 0 && net.minecraftforge.event.terraingen.TerrainGen.decorate(p_185379_1_, p_185379_2_, new net.minecraft.util.math.ChunkPos(p_185379_3_), blockpos, net.minecraftforge.event.terraingen.DecorateBiomeEvent.Decorate.EventType.BIG_SHROOM))
{
WorldGenBigMushroom worldgenbigmushroom = new WorldGenBigMushroom();
worldgenbigmushroom.generate(p_185379_1_, p_185379_2_, blockpos);
}
else if (net.minecraftforge.event.terraingen.TerrainGen.decorate(p_185379_1_, p_185379_2_, new net.minecraft.util.math.ChunkPos(p_185379_3_), blockpos, net.minecraftforge.event.terraingen.DecorateBiomeEvent.Decorate.EventType.TREE))
{
WorldGenAbstractTree worldgenabstracttree = this.getRandomTreeFeature(p_185379_2_);
worldgenabstracttree.setDecorationDefaults();
if (worldgenabstracttree.generate(p_185379_1_, p_185379_2_, blockpos))
{
worldgenabstracttree.generateSaplings(p_185379_1_, p_185379_2_, blockpos);
}
}
}
}
}
public void addDoublePlants(World p_185378_1_, Random p_185378_2_, BlockPos p_185378_3_, int p_185378_4_)
{
for (int i = 0; i < p_185378_4_; ++i)
{
int j = p_185378_2_.nextInt(3);
if (j == 0)
{
DOUBLE_PLANT_GENERATOR.setPlantType(BlockDoublePlant.EnumPlantType.SYRINGA);
}
else if (j == 1)
{
DOUBLE_PLANT_GENERATOR.setPlantType(BlockDoublePlant.EnumPlantType.ROSE);
}
else if (j == 2)
{
DOUBLE_PLANT_GENERATOR.setPlantType(BlockDoublePlant.EnumPlantType.PAEONIA);
}
for (int k = 0; k < 5; ++k)
{
int l = p_185378_2_.nextInt(16) + 8;
int i1 = p_185378_2_.nextInt(16) + 8;
int j1 = p_185378_2_.nextInt(p_185378_1_.getHeight(p_185378_3_.add(l, 0, i1)).getY() + 32);
if (DOUBLE_PLANT_GENERATOR.generate(p_185378_1_, p_185378_2_, new BlockPos(p_185378_3_.getX() + l, j1, p_185378_3_.getZ() + i1)))
{
break;
}
}
}
}
public Class <? extends Biome > getBiomeClass()
{
return BiomeForest.class;
}
@SideOnly(Side.CLIENT)
public int getGrassColorAtPos(BlockPos pos)
{
int i = super.getGrassColorAtPos(pos);
return this.type == BiomeForest.Type.ROOFED ? (i & 16711422) + 2634762 >> 1 : i;
}
public static enum Type
{
NORMAL,
FLOWER,
BIRCH,
ROOFED;
}
}

View File

@@ -0,0 +1,17 @@
package net.minecraft.world.biome;
import java.util.Random;
import net.minecraft.world.gen.feature.WorldGenAbstractTree;
public class BiomeForestMutated extends BiomeForest
{
public BiomeForestMutated(Biome.BiomeProperties properties)
{
super(BiomeForest.Type.BIRCH, properties);
}
public WorldGenAbstractTree getRandomTreeFeature(Random rand)
{
return rand.nextBoolean() ? BiomeForest.SUPER_BIRCH_TREE : BiomeForest.BIRCH_TREE;
}
}

View File

@@ -0,0 +1,23 @@
package net.minecraft.world.biome;
import net.minecraft.entity.monster.EntityEnderman;
import net.minecraft.entity.monster.EntityGhast;
import net.minecraft.entity.monster.EntityMagmaCube;
import net.minecraft.entity.monster.EntityPigZombie;
public class BiomeHell extends Biome
{
public BiomeHell(Biome.BiomeProperties properties)
{
super(properties);
this.spawnableMonsterList.clear();
this.spawnableCreatureList.clear();
this.spawnableWaterCreatureList.clear();
this.spawnableCaveCreatureList.clear();
this.spawnableMonsterList.add(new Biome.SpawnListEntry(EntityGhast.class, 50, 4, 4));
this.spawnableMonsterList.add(new Biome.SpawnListEntry(EntityPigZombie.class, 100, 4, 4));
this.spawnableMonsterList.add(new Biome.SpawnListEntry(EntityMagmaCube.class, 2, 4, 4));
this.spawnableMonsterList.add(new Biome.SpawnListEntry(EntityEnderman.class, 1, 4, 4));
this.decorator = new BiomeHellDecorator();
}
}

View File

@@ -0,0 +1,12 @@
package net.minecraft.world.biome;
import java.util.Random;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.World;
public class BiomeHellDecorator extends BiomeDecorator
{
public void decorate(World worldIn, Random random, Biome biome, BlockPos pos)
{
}
}

View File

@@ -0,0 +1,105 @@
package net.minecraft.world.biome;
import java.util.Random;
import net.minecraft.block.BlockSilverfish;
import net.minecraft.entity.passive.EntityLlama;
import net.minecraft.init.Blocks;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.World;
import net.minecraft.world.chunk.ChunkPrimer;
import net.minecraft.world.gen.feature.WorldGenAbstractTree;
import net.minecraft.world.gen.feature.WorldGenMinable;
import net.minecraft.world.gen.feature.WorldGenTaiga2;
import net.minecraft.world.gen.feature.WorldGenerator;
public class BiomeHills extends Biome
{
private final WorldGenerator silverfishSpawner = new WorldGenMinable(Blocks.MONSTER_EGG.getDefaultState().withProperty(BlockSilverfish.VARIANT, BlockSilverfish.EnumType.STONE), 9);
private final WorldGenTaiga2 spruceGenerator = new WorldGenTaiga2(false);
private final BiomeHills.Type type;
public BiomeHills(BiomeHills.Type p_i46710_1_, Biome.BiomeProperties properties)
{
super(properties);
if (p_i46710_1_ == BiomeHills.Type.EXTRA_TREES)
{
this.decorator.treesPerChunk = 3;
}
this.spawnableCreatureList.add(new Biome.SpawnListEntry(EntityLlama.class, 5, 4, 6));
this.type = p_i46710_1_;
}
public WorldGenAbstractTree getRandomTreeFeature(Random rand)
{
return (WorldGenAbstractTree)(rand.nextInt(3) > 0 ? this.spruceGenerator : super.getRandomTreeFeature(rand));
}
public void decorate(World worldIn, Random rand, BlockPos pos)
{
super.decorate(worldIn, rand, pos);
net.minecraftforge.common.MinecraftForge.ORE_GEN_BUS.post(new net.minecraftforge.event.terraingen.OreGenEvent.Pre(worldIn, rand, pos));
WorldGenerator emeralds = new EmeraldGenerator();
if (net.minecraftforge.event.terraingen.TerrainGen.generateOre(worldIn, rand, emeralds, pos, net.minecraftforge.event.terraingen.OreGenEvent.GenerateMinable.EventType.EMERALD))
emeralds.generate(worldIn, rand, pos);
for (int j1 = 0; j1 < 7; ++j1)
{
int k1 = rand.nextInt(16);
int l1 = rand.nextInt(64);
int i2 = rand.nextInt(16);
if (net.minecraftforge.event.terraingen.TerrainGen.generateOre(worldIn, rand, silverfishSpawner, pos.add(j1, k1, l1), net.minecraftforge.event.terraingen.OreGenEvent.GenerateMinable.EventType.SILVERFISH))
this.silverfishSpawner.generate(worldIn, rand, pos.add(k1, l1, i2));
}
net.minecraftforge.common.MinecraftForge.ORE_GEN_BUS.post(new net.minecraftforge.event.terraingen.OreGenEvent.Post(worldIn, rand, pos));
}
public void genTerrainBlocks(World worldIn, Random rand, ChunkPrimer chunkPrimerIn, int x, int z, double noiseVal)
{
this.topBlock = Blocks.GRASS.getDefaultState();
this.fillerBlock = Blocks.DIRT.getDefaultState();
if ((noiseVal < -1.0D || noiseVal > 2.0D) && this.type == BiomeHills.Type.MUTATED)
{
this.topBlock = Blocks.GRAVEL.getDefaultState();
this.fillerBlock = Blocks.GRAVEL.getDefaultState();
}
else if (noiseVal > 1.0D && this.type != BiomeHills.Type.EXTRA_TREES)
{
this.topBlock = Blocks.STONE.getDefaultState();
this.fillerBlock = Blocks.STONE.getDefaultState();
}
this.generateBiomeTerrain(worldIn, rand, chunkPrimerIn, x, z, noiseVal);
}
public static enum Type
{
NORMAL,
EXTRA_TREES,
MUTATED;
}
private static class EmeraldGenerator extends WorldGenerator
{
@Override
public boolean generate(World worldIn, Random rand, BlockPos pos)
{
int count = 3 + rand.nextInt(6);
for (int i = 0; i < count; i++)
{
int offset = net.minecraftforge.common.ForgeModContainer.fixVanillaCascading ? 8 : 0; // MC-114332
BlockPos blockpos = pos.add(rand.nextInt(16) + offset, rand.nextInt(28) + 4, rand.nextInt(16) + offset);
net.minecraft.block.state.IBlockState state = worldIn.getBlockState(blockpos);
if (state.getBlock().isReplaceableOreGen(state, worldIn, blockpos, net.minecraft.block.state.pattern.BlockMatcher.forBlock(Blocks.STONE)))
{
worldIn.setBlockState(blockpos, Blocks.EMERALD_ORE.getDefaultState(), 16 | 2);
}
}
return true;
}
}
}

View File

@@ -0,0 +1,104 @@
package net.minecraft.world.biome;
import java.util.Random;
import net.minecraft.block.BlockLeaves;
import net.minecraft.block.BlockOldLeaf;
import net.minecraft.block.BlockOldLog;
import net.minecraft.block.BlockPlanks;
import net.minecraft.block.BlockTallGrass;
import net.minecraft.block.state.IBlockState;
import net.minecraft.entity.passive.EntityChicken;
import net.minecraft.entity.passive.EntityOcelot;
import net.minecraft.entity.passive.EntityParrot;
import net.minecraft.init.Blocks;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.World;
import net.minecraft.world.gen.feature.WorldGenAbstractTree;
import net.minecraft.world.gen.feature.WorldGenMegaJungle;
import net.minecraft.world.gen.feature.WorldGenMelon;
import net.minecraft.world.gen.feature.WorldGenShrub;
import net.minecraft.world.gen.feature.WorldGenTallGrass;
import net.minecraft.world.gen.feature.WorldGenTrees;
import net.minecraft.world.gen.feature.WorldGenVines;
import net.minecraft.world.gen.feature.WorldGenerator;
public class BiomeJungle extends Biome
{
private final boolean isEdge;
private static final IBlockState JUNGLE_LOG = Blocks.LOG.getDefaultState().withProperty(BlockOldLog.VARIANT, BlockPlanks.EnumType.JUNGLE);
private static final IBlockState JUNGLE_LEAF = Blocks.LEAVES.getDefaultState().withProperty(BlockOldLeaf.VARIANT, BlockPlanks.EnumType.JUNGLE).withProperty(BlockLeaves.CHECK_DECAY, Boolean.valueOf(false));
/** The block state for the Oak leaf */
private static final IBlockState OAK_LEAF = Blocks.LEAVES.getDefaultState().withProperty(BlockOldLeaf.VARIANT, BlockPlanks.EnumType.OAK).withProperty(BlockLeaves.CHECK_DECAY, Boolean.valueOf(false));
public BiomeJungle(boolean isEdgeIn, Biome.BiomeProperties properties)
{
super(properties);
this.isEdge = isEdgeIn;
if (isEdgeIn)
{
this.decorator.treesPerChunk = 2;
}
else
{
this.decorator.treesPerChunk = 50;
}
this.decorator.grassPerChunk = 25;
this.decorator.flowersPerChunk = 4;
if (!isEdgeIn)
{
this.spawnableMonsterList.add(new Biome.SpawnListEntry(EntityOcelot.class, 2, 1, 1));
}
this.spawnableCreatureList.add(new Biome.SpawnListEntry(EntityParrot.class, 40, 1, 2));
this.spawnableCreatureList.add(new Biome.SpawnListEntry(EntityChicken.class, 10, 4, 4));
}
public WorldGenAbstractTree getRandomTreeFeature(Random rand)
{
if (rand.nextInt(10) == 0)
{
return BIG_TREE_FEATURE;
}
else if (rand.nextInt(2) == 0)
{
return new WorldGenShrub(JUNGLE_LOG, OAK_LEAF);
}
else
{
return (WorldGenAbstractTree)(!this.isEdge && rand.nextInt(3) == 0 ? new WorldGenMegaJungle(false, 10, 20, JUNGLE_LOG, JUNGLE_LEAF) : new WorldGenTrees(false, 4 + rand.nextInt(7), JUNGLE_LOG, JUNGLE_LEAF, true));
}
}
/**
* Gets a WorldGen appropriate for this biome.
*/
public WorldGenerator getRandomWorldGenForGrass(Random rand)
{
return rand.nextInt(4) == 0 ? new WorldGenTallGrass(BlockTallGrass.EnumType.FERN) : new WorldGenTallGrass(BlockTallGrass.EnumType.GRASS);
}
public void decorate(World worldIn, Random rand, BlockPos pos)
{
super.decorate(worldIn, rand, pos);
int i = rand.nextInt(16) + 8;
int j = rand.nextInt(16) + 8;
int height = worldIn.getHeight(pos.add(i, 0, j)).getY() * 2; // could == 0, which crashes nextInt
if (height < 1) height = 1;
int k = rand.nextInt(height);
if(net.minecraftforge.event.terraingen.TerrainGen.decorate(worldIn, rand, new net.minecraft.util.math.ChunkPos(pos), pos.add(i, k, j), net.minecraftforge.event.terraingen.DecorateBiomeEvent.Decorate.EventType.PUMPKIN))
(new WorldGenMelon()).generate(worldIn, rand, pos.add(i, k, j));
WorldGenVines worldgenvines = new WorldGenVines();
if(net.minecraftforge.event.terraingen.TerrainGen.decorate(worldIn, rand, new net.minecraft.util.math.ChunkPos(pos), net.minecraftforge.event.terraingen.DecorateBiomeEvent.Decorate.EventType.GRASS))
for (int j1 = 0; j1 < 50; ++j1)
{
k = rand.nextInt(16) + 8;
int l = 128;
int i1 = rand.nextInt(16) + 8;
worldgenvines.generate(worldIn, rand, pos.add(k, 128, i1));
}
}
}

View File

@@ -0,0 +1,349 @@
package net.minecraft.world.biome;
import java.util.Arrays;
import java.util.Random;
import net.minecraft.block.BlockColored;
import net.minecraft.block.BlockDirt;
import net.minecraft.block.BlockSand;
import net.minecraft.block.material.Material;
import net.minecraft.block.state.IBlockState;
import net.minecraft.init.Blocks;
import net.minecraft.item.EnumDyeColor;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.World;
import net.minecraft.world.chunk.ChunkPrimer;
import net.minecraft.world.gen.NoiseGeneratorPerlin;
import net.minecraft.world.gen.feature.WorldGenAbstractTree;
import net.minecraftforge.fml.relauncher.Side;
import net.minecraftforge.fml.relauncher.SideOnly;
public class BiomeMesa extends Biome
{
protected static final IBlockState COARSE_DIRT = Blocks.DIRT.getDefaultState().withProperty(BlockDirt.VARIANT, BlockDirt.DirtType.COARSE_DIRT);
protected static final IBlockState GRASS = Blocks.GRASS.getDefaultState();
protected static final IBlockState HARDENED_CLAY = Blocks.HARDENED_CLAY.getDefaultState();
protected static final IBlockState STAINED_HARDENED_CLAY = Blocks.STAINED_HARDENED_CLAY.getDefaultState();
protected static final IBlockState ORANGE_STAINED_HARDENED_CLAY = STAINED_HARDENED_CLAY.withProperty(BlockColored.COLOR, EnumDyeColor.ORANGE);
protected static final IBlockState RED_SAND = Blocks.SAND.getDefaultState().withProperty(BlockSand.VARIANT, BlockSand.EnumType.RED_SAND);
private IBlockState[] clayBands;
private long worldSeed;
private NoiseGeneratorPerlin pillarNoise;
private NoiseGeneratorPerlin pillarRoofNoise;
private NoiseGeneratorPerlin clayBandsOffsetNoise;
private final boolean brycePillars;
private final boolean hasForest;
public BiomeMesa(boolean p_i46704_1_, boolean p_i46704_2_, Biome.BiomeProperties properties)
{
super(properties);
this.brycePillars = p_i46704_1_;
this.hasForest = p_i46704_2_;
this.spawnableCreatureList.clear();
this.topBlock = RED_SAND;
this.fillerBlock = STAINED_HARDENED_CLAY;
this.decorator.treesPerChunk = -999;
this.decorator.deadBushPerChunk = 20;
this.decorator.reedsPerChunk = 3;
this.decorator.cactiPerChunk = 5;
this.decorator.flowersPerChunk = 0;
this.spawnableCreatureList.clear();
if (p_i46704_2_)
{
this.decorator.treesPerChunk = 5;
}
}
/**
* Allocate a new BiomeDecorator for this BiomeGenBase
*/
public BiomeDecorator createBiomeDecorator()
{
return new BiomeMesa.Decorator();
}
public WorldGenAbstractTree getRandomTreeFeature(Random rand)
{
return TREE_FEATURE;
}
public void genTerrainBlocks(World worldIn, Random rand, ChunkPrimer chunkPrimerIn, int x, int z, double noiseVal)
{
if (this.clayBands == null || this.worldSeed != worldIn.getSeed())
{
this.generateBands(worldIn.getSeed());
}
if (this.pillarNoise == null || this.pillarRoofNoise == null || this.worldSeed != worldIn.getSeed())
{
Random random = new Random(this.worldSeed);
this.pillarNoise = new NoiseGeneratorPerlin(random, 4);
this.pillarRoofNoise = new NoiseGeneratorPerlin(random, 1);
}
this.worldSeed = worldIn.getSeed();
double d4 = 0.0D;
if (this.brycePillars)
{
int i = (x & -16) + (z & 15);
int j = (z & -16) + (x & 15);
double d0 = Math.min(Math.abs(noiseVal), this.pillarNoise.getValue((double)i * 0.25D, (double)j * 0.25D));
if (d0 > 0.0D)
{
double d1 = 0.001953125D;
double d2 = Math.abs(this.pillarRoofNoise.getValue((double)i * 0.001953125D, (double)j * 0.001953125D));
d4 = d0 * d0 * 2.5D;
double d3 = Math.ceil(d2 * 50.0D) + 14.0D;
if (d4 > d3)
{
d4 = d3;
}
d4 = d4 + 64.0D;
}
}
int k1 = x & 15;
int l1 = z & 15;
int i2 = worldIn.getSeaLevel();
IBlockState iblockstate = STAINED_HARDENED_CLAY;
IBlockState iblockstate3 = this.fillerBlock;
int k = (int)(noiseVal / 3.0D + 3.0D + rand.nextDouble() * 0.25D);
boolean flag = Math.cos(noiseVal / 3.0D * Math.PI) > 0.0D;
int l = -1;
boolean flag1 = false;
int i1 = 0;
for (int j1 = 255; j1 >= 0; --j1)
{
if (chunkPrimerIn.getBlockState(l1, j1, k1).getMaterial() == Material.AIR && j1 < (int)d4)
{
chunkPrimerIn.setBlockState(l1, j1, k1, STONE);
}
if (j1 <= rand.nextInt(5))
{
chunkPrimerIn.setBlockState(l1, j1, k1, BEDROCK);
}
else if (i1 < 15 || this.brycePillars)
{
IBlockState iblockstate1 = chunkPrimerIn.getBlockState(l1, j1, k1);
if (iblockstate1.getMaterial() == Material.AIR)
{
l = -1;
}
else if (iblockstate1.getBlock() == Blocks.STONE)
{
if (l == -1)
{
flag1 = false;
if (k <= 0)
{
iblockstate = AIR;
iblockstate3 = STONE;
}
else if (j1 >= i2 - 4 && j1 <= i2 + 1)
{
iblockstate = STAINED_HARDENED_CLAY;
iblockstate3 = this.fillerBlock;
}
if (j1 < i2 && (iblockstate == null || iblockstate.getMaterial() == Material.AIR))
{
iblockstate = WATER;
}
l = k + Math.max(0, j1 - i2);
if (j1 >= i2 - 1)
{
if (this.hasForest && j1 > 86 + k * 2)
{
if (flag)
{
chunkPrimerIn.setBlockState(l1, j1, k1, COARSE_DIRT);
}
else
{
chunkPrimerIn.setBlockState(l1, j1, k1, GRASS);
}
}
else if (j1 > i2 + 3 + k)
{
IBlockState iblockstate2;
if (j1 >= 64 && j1 <= 127)
{
if (flag)
{
iblockstate2 = HARDENED_CLAY;
}
else
{
iblockstate2 = this.getBand(x, j1, z);
}
}
else
{
iblockstate2 = ORANGE_STAINED_HARDENED_CLAY;
}
chunkPrimerIn.setBlockState(l1, j1, k1, iblockstate2);
}
else
{
chunkPrimerIn.setBlockState(l1, j1, k1, this.topBlock);
flag1 = true;
}
}
else
{
chunkPrimerIn.setBlockState(l1, j1, k1, iblockstate3);
if (iblockstate3.getBlock() == Blocks.STAINED_HARDENED_CLAY)
{
chunkPrimerIn.setBlockState(l1, j1, k1, ORANGE_STAINED_HARDENED_CLAY);
}
}
}
else if (l > 0)
{
--l;
if (flag1)
{
chunkPrimerIn.setBlockState(l1, j1, k1, ORANGE_STAINED_HARDENED_CLAY);
}
else
{
chunkPrimerIn.setBlockState(l1, j1, k1, this.getBand(x, j1, z));
}
}
++i1;
}
}
}
}
public void generateBands(long p_150619_1_)
{
this.clayBands = new IBlockState[64];
Arrays.fill(this.clayBands, HARDENED_CLAY);
Random random = new Random(p_150619_1_);
this.clayBandsOffsetNoise = new NoiseGeneratorPerlin(random, 1);
for (int l1 = 0; l1 < 64; ++l1)
{
l1 += random.nextInt(5) + 1;
if (l1 < 64)
{
this.clayBands[l1] = ORANGE_STAINED_HARDENED_CLAY;
}
}
int i2 = random.nextInt(4) + 2;
for (int i = 0; i < i2; ++i)
{
int j = random.nextInt(3) + 1;
int k = random.nextInt(64);
for (int l = 0; k + l < 64 && l < j; ++l)
{
this.clayBands[k + l] = STAINED_HARDENED_CLAY.withProperty(BlockColored.COLOR, EnumDyeColor.YELLOW);
}
}
int j2 = random.nextInt(4) + 2;
for (int k2 = 0; k2 < j2; ++k2)
{
int i3 = random.nextInt(3) + 2;
int l3 = random.nextInt(64);
for (int i1 = 0; l3 + i1 < 64 && i1 < i3; ++i1)
{
this.clayBands[l3 + i1] = STAINED_HARDENED_CLAY.withProperty(BlockColored.COLOR, EnumDyeColor.BROWN);
}
}
int l2 = random.nextInt(4) + 2;
for (int j3 = 0; j3 < l2; ++j3)
{
int i4 = random.nextInt(3) + 1;
int k4 = random.nextInt(64);
for (int j1 = 0; k4 + j1 < 64 && j1 < i4; ++j1)
{
this.clayBands[k4 + j1] = STAINED_HARDENED_CLAY.withProperty(BlockColored.COLOR, EnumDyeColor.RED);
}
}
int k3 = random.nextInt(3) + 3;
int j4 = 0;
for (int l4 = 0; l4 < k3; ++l4)
{
int i5 = 1;
j4 += random.nextInt(16) + 4;
for (int k1 = 0; j4 + k1 < 64 && k1 < 1; ++k1)
{
this.clayBands[j4 + k1] = STAINED_HARDENED_CLAY.withProperty(BlockColored.COLOR, EnumDyeColor.WHITE);
if (j4 + k1 > 1 && random.nextBoolean())
{
this.clayBands[j4 + k1 - 1] = STAINED_HARDENED_CLAY.withProperty(BlockColored.COLOR, EnumDyeColor.SILVER);
}
if (j4 + k1 < 63 && random.nextBoolean())
{
this.clayBands[j4 + k1 + 1] = STAINED_HARDENED_CLAY.withProperty(BlockColored.COLOR, EnumDyeColor.SILVER);
}
}
}
}
public IBlockState getBand(int p_180629_1_, int p_180629_2_, int p_180629_3_)
{
int i = (int)Math.round(this.clayBandsOffsetNoise.getValue((double)p_180629_1_ / 512.0D, (double)p_180629_1_ / 512.0D) * 2.0D);
return this.clayBands[(p_180629_2_ + i + 64) % 64];
}
@SideOnly(Side.CLIENT)
public int getFoliageColorAtPos(BlockPos pos)
{
return getModdedBiomeFoliageColor(10387789);
}
@SideOnly(Side.CLIENT)
public int getGrassColorAtPos(BlockPos pos)
{
return getModdedBiomeGrassColor(9470285);
}
class Decorator extends BiomeDecorator
{
private Decorator()
{
}
/**
* Generates ores in the current chunk
*/
protected void generateOres(World worldIn, Random random)
{
super.generateOres(worldIn, random);
if (net.minecraftforge.event.terraingen.TerrainGen.generateOre(worldIn, random, goldGen, chunkPos, net.minecraftforge.event.terraingen.OreGenEvent.GenerateMinable.EventType.GOLD))
this.genStandardOre1(worldIn, random, 20, this.goldGen, 32, 80);
}
}
}

View File

@@ -0,0 +1,22 @@
package net.minecraft.world.biome;
import net.minecraft.entity.passive.EntityMooshroom;
import net.minecraft.init.Blocks;
public class BiomeMushroomIsland extends Biome
{
public BiomeMushroomIsland(Biome.BiomeProperties properties)
{
super(properties);
this.decorator.treesPerChunk = -100;
this.decorator.flowersPerChunk = -100;
this.decorator.grassPerChunk = -100;
this.decorator.mushroomsPerChunk = 1;
this.decorator.bigMushroomsPerChunk = 1;
this.topBlock = Blocks.MYCELIUM.getDefaultState();
this.spawnableMonsterList.clear();
this.spawnableCreatureList.clear();
this.spawnableWaterCreatureList.clear();
this.spawnableCreatureList.add(new Biome.SpawnListEntry(EntityMooshroom.class, 8, 4, 8));
}
}

View File

@@ -0,0 +1,15 @@
package net.minecraft.world.biome;
public class BiomeOcean extends Biome
{
public BiomeOcean(Biome.BiomeProperties properties)
{
super(properties);
this.spawnableCreatureList.clear();
}
public Biome.TempCategory getTempCategory()
{
return Biome.TempCategory.OCEAN;
}
}

View File

@@ -0,0 +1,128 @@
package net.minecraft.world.biome;
import java.util.Random;
import net.minecraft.block.BlockDoublePlant;
import net.minecraft.block.BlockFlower;
import net.minecraft.entity.passive.EntityDonkey;
import net.minecraft.entity.passive.EntityHorse;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.World;
import net.minecraft.world.gen.feature.WorldGenAbstractTree;
public class BiomePlains extends Biome
{
protected boolean sunflowers;
public BiomePlains(boolean p_i46699_1_, Biome.BiomeProperties properties)
{
super(properties);
this.sunflowers = p_i46699_1_;
this.spawnableCreatureList.add(new Biome.SpawnListEntry(EntityHorse.class, 5, 2, 6));
this.spawnableCreatureList.add(new Biome.SpawnListEntry(EntityDonkey.class, 1, 1, 3));
this.decorator.treesPerChunk = 0;
this.decorator.extraTreeChance = 0.05F;
this.decorator.flowersPerChunk = 4;
this.decorator.grassPerChunk = 10;
}
public BlockFlower.EnumFlowerType pickRandomFlower(Random rand, BlockPos pos)
{
double d0 = GRASS_COLOR_NOISE.getValue((double)pos.getX() / 200.0D, (double)pos.getZ() / 200.0D);
if (d0 < -0.8D)
{
int j = rand.nextInt(4);
switch (j)
{
case 0:
return BlockFlower.EnumFlowerType.ORANGE_TULIP;
case 1:
return BlockFlower.EnumFlowerType.RED_TULIP;
case 2:
return BlockFlower.EnumFlowerType.PINK_TULIP;
case 3:
default:
return BlockFlower.EnumFlowerType.WHITE_TULIP;
}
}
else if (rand.nextInt(3) > 0)
{
int i = rand.nextInt(3);
if (i == 0)
{
return BlockFlower.EnumFlowerType.POPPY;
}
else
{
return i == 1 ? BlockFlower.EnumFlowerType.HOUSTONIA : BlockFlower.EnumFlowerType.OXEYE_DAISY;
}
}
else
{
return BlockFlower.EnumFlowerType.DANDELION;
}
}
public void decorate(World worldIn, Random rand, BlockPos pos)
{
double d0 = GRASS_COLOR_NOISE.getValue((double)(pos.getX() + 8) / 200.0D, (double)(pos.getZ() + 8) / 200.0D);
if (d0 < -0.8D)
{
this.decorator.flowersPerChunk = 15;
this.decorator.grassPerChunk = 5;
}
else
{
this.decorator.flowersPerChunk = 4;
this.decorator.grassPerChunk = 10;
DOUBLE_PLANT_GENERATOR.setPlantType(BlockDoublePlant.EnumPlantType.GRASS);
if(net.minecraftforge.event.terraingen.TerrainGen.decorate(worldIn, rand, new net.minecraft.util.math.ChunkPos(pos), net.minecraftforge.event.terraingen.DecorateBiomeEvent.Decorate.EventType.GRASS))
for (int i = 0; i < 7; ++i)
{
int j = rand.nextInt(16) + 8;
int k = rand.nextInt(16) + 8;
int l = rand.nextInt(worldIn.getHeight(pos.add(j, 0, k)).getY() + 32);
DOUBLE_PLANT_GENERATOR.generate(worldIn, rand, pos.add(j, l, k));
}
}
if (this.sunflowers && net.minecraftforge.event.terraingen.TerrainGen.decorate(worldIn, rand, new net.minecraft.util.math.ChunkPos(pos), net.minecraftforge.event.terraingen.DecorateBiomeEvent.Decorate.EventType.FLOWERS))
{
DOUBLE_PLANT_GENERATOR.setPlantType(BlockDoublePlant.EnumPlantType.SUNFLOWER);
for (int i1 = 0; i1 < 10; ++i1)
{
int j1 = rand.nextInt(16) + 8;
int k1 = rand.nextInt(16) + 8;
int l1 = rand.nextInt(worldIn.getHeight(pos.add(j1, 0, k1)).getY() + 32);
DOUBLE_PLANT_GENERATOR.generate(worldIn, rand, pos.add(j1, l1, k1));
}
}
super.decorate(worldIn, rand, pos);
}
@Override
public void addDefaultFlowers()
{
BlockFlower red = net.minecraft.init.Blocks.RED_FLOWER;
BlockFlower yel = net.minecraft.init.Blocks.YELLOW_FLOWER;
addFlower(red.getDefaultState().withProperty(red.getTypeProperty(), BlockFlower.EnumFlowerType.ORANGE_TULIP), 3);
addFlower(red.getDefaultState().withProperty(red.getTypeProperty(), BlockFlower.EnumFlowerType.RED_TULIP), 3);
addFlower(red.getDefaultState().withProperty(red.getTypeProperty(), BlockFlower.EnumFlowerType.PINK_TULIP), 3);
addFlower(red.getDefaultState().withProperty(red.getTypeProperty(), BlockFlower.EnumFlowerType.WHITE_TULIP), 3);
addFlower(red.getDefaultState().withProperty(red.getTypeProperty(), BlockFlower.EnumFlowerType.POPPY), 20);
addFlower(red.getDefaultState().withProperty(red.getTypeProperty(), BlockFlower.EnumFlowerType.HOUSTONIA), 20);
addFlower(red.getDefaultState().withProperty(red.getTypeProperty(), BlockFlower.EnumFlowerType.OXEYE_DAISY), 20);
addFlower(yel.getDefaultState().withProperty(yel.getTypeProperty(), BlockFlower.EnumFlowerType.DANDELION), 30);
}
public WorldGenAbstractTree getRandomTreeFeature(Random rand)
{
return (WorldGenAbstractTree)(rand.nextInt(3) == 0 ? BIG_TREE_FEATURE : TREE_FEATURE);
}
}

View File

@@ -0,0 +1,256 @@
package net.minecraft.world.biome;
import com.google.common.collect.Lists;
import java.util.List;
import java.util.Random;
import javax.annotation.Nullable;
import net.minecraft.crash.CrashReport;
import net.minecraft.crash.CrashReportCategory;
import net.minecraft.init.Biomes;
import net.minecraft.util.ReportedException;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.WorldType;
import net.minecraft.world.gen.ChunkGeneratorSettings;
import net.minecraft.world.gen.layer.GenLayer;
import net.minecraft.world.gen.layer.IntCache;
import net.minecraft.world.storage.WorldInfo;
public class BiomeProvider
{
private ChunkGeneratorSettings settings;
private GenLayer genBiomes;
/** A GenLayer containing the indices into BiomeGenBase.biomeList[] */
private GenLayer biomeIndexLayer;
/** The biome list. */
private final BiomeCache biomeCache;
/** A list of biomes that the player can spawn in. */
private final List<Biome> biomesToSpawnIn;
public static List<Biome> allowedBiomes = Lists.newArrayList(Biomes.FOREST, Biomes.PLAINS, Biomes.TAIGA, Biomes.TAIGA_HILLS, Biomes.FOREST_HILLS, Biomes.JUNGLE, Biomes.JUNGLE_HILLS);
protected BiomeProvider()
{
this.biomeCache = new BiomeCache(this);
this.biomesToSpawnIn = Lists.newArrayList(allowedBiomes);
}
private BiomeProvider(long seed, WorldType worldTypeIn, String options)
{
this();
if (worldTypeIn == WorldType.CUSTOMIZED && !options.isEmpty())
{
this.settings = ChunkGeneratorSettings.Factory.jsonToFactory(options).build();
}
GenLayer[] agenlayer = GenLayer.initializeAllBiomeGenerators(seed, worldTypeIn, this.settings);
agenlayer = getModdedBiomeGenerators(worldTypeIn, seed, agenlayer);
this.genBiomes = agenlayer[0];
this.biomeIndexLayer = agenlayer[1];
}
public BiomeProvider(WorldInfo info)
{
this(info.getSeed(), info.getTerrainType(), info.getGeneratorOptions());
}
/**
* Gets the list of valid biomes for the player to spawn in.
*/
public List<Biome> getBiomesToSpawnIn()
{
return this.biomesToSpawnIn;
}
/**
* Returns the biome generator
*/
public Biome getBiome(BlockPos pos)
{
return this.getBiome(pos, (Biome)null);
}
public Biome getBiome(BlockPos pos, Biome defaultBiome)
{
return this.biomeCache.getBiome(pos.getX(), pos.getZ(), defaultBiome);
}
/**
* Return an adjusted version of a given temperature based on the y height
*/
public float getTemperatureAtHeight(float p_76939_1_, int p_76939_2_)
{
return p_76939_1_;
}
/**
* Returns an array of biomes for the location input.
*/
public Biome[] getBiomesForGeneration(Biome[] biomes, int x, int z, int width, int height)
{
IntCache.resetIntCache();
if (biomes == null || biomes.length < width * height)
{
biomes = new Biome[width * height];
}
int[] aint = this.genBiomes.getInts(x, z, width, height);
try
{
for (int i = 0; i < width * height; ++i)
{
biomes[i] = Biome.getBiome(aint[i], Biomes.DEFAULT);
}
return biomes;
}
catch (Throwable throwable)
{
CrashReport crashreport = CrashReport.makeCrashReport(throwable, "Invalid Biome id");
CrashReportCategory crashreportcategory = crashreport.makeCategory("RawBiomeBlock");
crashreportcategory.addCrashSection("biomes[] size", Integer.valueOf(biomes.length));
crashreportcategory.addCrashSection("x", Integer.valueOf(x));
crashreportcategory.addCrashSection("z", Integer.valueOf(z));
crashreportcategory.addCrashSection("w", Integer.valueOf(width));
crashreportcategory.addCrashSection("h", Integer.valueOf(height));
throw new ReportedException(crashreport);
}
}
/**
* Gets biomes to use for the blocks and loads the other data like temperature and humidity onto the
* WorldChunkManager.
*/
public Biome[] getBiomes(@Nullable Biome[] oldBiomeList, int x, int z, int width, int depth)
{
return this.getBiomes(oldBiomeList, x, z, width, depth, true);
}
/**
* Gets a list of biomes for the specified blocks.
*/
public Biome[] getBiomes(@Nullable Biome[] listToReuse, int x, int z, int width, int length, boolean cacheFlag)
{
IntCache.resetIntCache();
if (listToReuse == null || listToReuse.length < width * length)
{
listToReuse = new Biome[width * length];
}
if (cacheFlag && width == 16 && length == 16 && (x & 15) == 0 && (z & 15) == 0)
{
Biome[] abiome = this.biomeCache.getCachedBiomes(x, z);
System.arraycopy(abiome, 0, listToReuse, 0, width * length);
return listToReuse;
}
else
{
int[] aint = this.biomeIndexLayer.getInts(x, z, width, length);
for (int i = 0; i < width * length; ++i)
{
listToReuse[i] = Biome.getBiome(aint[i], Biomes.DEFAULT);
}
return listToReuse;
}
}
/**
* checks given Chunk's Biomes against List of allowed ones
*/
public boolean areBiomesViable(int x, int z, int radius, List<Biome> allowed)
{
IntCache.resetIntCache();
int i = x - radius >> 2;
int j = z - radius >> 2;
int k = x + radius >> 2;
int l = z + radius >> 2;
int i1 = k - i + 1;
int j1 = l - j + 1;
int[] aint = this.genBiomes.getInts(i, j, i1, j1);
try
{
for (int k1 = 0; k1 < i1 * j1; ++k1)
{
Biome biome = Biome.getBiome(aint[k1]);
if (!allowed.contains(biome))
{
return false;
}
}
return true;
}
catch (Throwable throwable)
{
CrashReport crashreport = CrashReport.makeCrashReport(throwable, "Invalid Biome id");
CrashReportCategory crashreportcategory = crashreport.makeCategory("Layer");
crashreportcategory.addCrashSection("Layer", this.genBiomes.toString());
crashreportcategory.addCrashSection("x", Integer.valueOf(x));
crashreportcategory.addCrashSection("z", Integer.valueOf(z));
crashreportcategory.addCrashSection("radius", Integer.valueOf(radius));
crashreportcategory.addCrashSection("allowed", allowed);
throw new ReportedException(crashreport);
}
}
@Nullable
public BlockPos findBiomePosition(int x, int z, int range, List<Biome> biomes, Random random)
{
IntCache.resetIntCache();
int i = x - range >> 2;
int j = z - range >> 2;
int k = x + range >> 2;
int l = z + range >> 2;
int i1 = k - i + 1;
int j1 = l - j + 1;
int[] aint = this.genBiomes.getInts(i, j, i1, j1);
BlockPos blockpos = null;
int k1 = 0;
for (int l1 = 0; l1 < i1 * j1; ++l1)
{
int i2 = i + l1 % i1 << 2;
int j2 = j + l1 / i1 << 2;
Biome biome = Biome.getBiome(aint[l1]);
if (biomes.contains(biome) && (blockpos == null || random.nextInt(k1 + 1) == 0))
{
blockpos = new BlockPos(i2, 0, j2);
++k1;
}
}
return blockpos;
}
/**
* Calls the WorldChunkManager's biomeCache.cleanupCache()
*/
public void cleanupCache()
{
this.biomeCache.cleanupCache();
}
public GenLayer[] getModdedBiomeGenerators(WorldType worldType, long seed, GenLayer[] original)
{
net.minecraftforge.event.terraingen.WorldTypeEvent.InitBiomeGens event = new net.minecraftforge.event.terraingen.WorldTypeEvent.InitBiomeGens(worldType, seed, original);
net.minecraftforge.common.MinecraftForge.TERRAIN_GEN_BUS.post(event);
return event.getNewBiomeGens();
}
public boolean isFixedBiome()
{
return this.settings != null && this.settings.fixedBiome >= 0;
}
public Biome getFixedBiome()
{
return this.settings != null && this.settings.fixedBiome >= 0 ? Biome.getBiomeForId(this.settings.fixedBiome) : null;
}
}

View File

@@ -0,0 +1,87 @@
package net.minecraft.world.biome;
import java.util.Arrays;
import java.util.List;
import java.util.Random;
import javax.annotation.Nullable;
import net.minecraft.util.math.BlockPos;
public class BiomeProviderSingle extends BiomeProvider
{
/** The biome generator object. */
private final Biome biome;
public BiomeProviderSingle(Biome biomeIn)
{
this.biome = biomeIn;
}
/**
* Returns the biome generator
*/
public Biome getBiome(BlockPos pos)
{
return this.biome;
}
/**
* Returns an array of biomes for the location input.
*/
public Biome[] getBiomesForGeneration(Biome[] biomes, int x, int z, int width, int height)
{
if (biomes == null || biomes.length < width * height)
{
biomes = new Biome[width * height];
}
Arrays.fill(biomes, 0, width * height, this.biome);
return biomes;
}
/**
* Gets biomes to use for the blocks and loads the other data like temperature and humidity onto the
* WorldChunkManager.
*/
public Biome[] getBiomes(@Nullable Biome[] oldBiomeList, int x, int z, int width, int depth)
{
if (oldBiomeList == null || oldBiomeList.length < width * depth)
{
oldBiomeList = new Biome[width * depth];
}
Arrays.fill(oldBiomeList, 0, width * depth, this.biome);
return oldBiomeList;
}
/**
* Gets a list of biomes for the specified blocks.
*/
public Biome[] getBiomes(@Nullable Biome[] listToReuse, int x, int z, int width, int length, boolean cacheFlag)
{
return this.getBiomes(listToReuse, x, z, width, length);
}
@Nullable
public BlockPos findBiomePosition(int x, int z, int range, List<Biome> biomes, Random random)
{
return biomes.contains(this.biome) ? new BlockPos(x - range + random.nextInt(range * 2 + 1), 0, z - range + random.nextInt(range * 2 + 1)) : null;
}
/**
* checks given Chunk's Biomes against List of allowed ones
*/
public boolean areBiomesViable(int x, int z, int radius, List<Biome> allowed)
{
return allowed.contains(this.biome);
}
public boolean isFixedBiome()
{
return true;
}
public Biome getFixedBiome()
{
return this.biome;
}
}

View File

@@ -0,0 +1,10 @@
package net.minecraft.world.biome;
public class BiomeRiver extends Biome
{
public BiomeRiver(Biome.BiomeProperties properties)
{
super(properties);
this.spawnableCreatureList.clear();
}
}

View File

@@ -0,0 +1,58 @@
package net.minecraft.world.biome;
import java.util.Random;
import net.minecraft.block.BlockDoublePlant;
import net.minecraft.entity.passive.EntityDonkey;
import net.minecraft.entity.passive.EntityHorse;
import net.minecraft.entity.passive.EntityLlama;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.World;
import net.minecraft.world.gen.feature.WorldGenAbstractTree;
import net.minecraft.world.gen.feature.WorldGenSavannaTree;
public class BiomeSavanna extends Biome
{
private static final WorldGenSavannaTree SAVANNA_TREE = new WorldGenSavannaTree(false);
public BiomeSavanna(Biome.BiomeProperties properties)
{
super(properties);
this.spawnableCreatureList.add(new Biome.SpawnListEntry(EntityHorse.class, 1, 2, 6));
this.spawnableCreatureList.add(new Biome.SpawnListEntry(EntityDonkey.class, 1, 1, 1));
if (this.getBaseHeight() > 1.1F)
{
this.spawnableCreatureList.add(new Biome.SpawnListEntry(EntityLlama.class, 8, 4, 4));
}
this.decorator.treesPerChunk = 1;
this.decorator.flowersPerChunk = 4;
this.decorator.grassPerChunk = 20;
}
public WorldGenAbstractTree getRandomTreeFeature(Random rand)
{
return (WorldGenAbstractTree)(rand.nextInt(5) > 0 ? SAVANNA_TREE : TREE_FEATURE);
}
public void decorate(World worldIn, Random rand, BlockPos pos)
{
DOUBLE_PLANT_GENERATOR.setPlantType(BlockDoublePlant.EnumPlantType.GRASS);
if(net.minecraftforge.event.terraingen.TerrainGen.decorate(worldIn, rand, new net.minecraft.util.math.ChunkPos(pos), net.minecraftforge.event.terraingen.DecorateBiomeEvent.Decorate.EventType.GRASS))
for (int i = 0; i < 7; ++i)
{
int j = rand.nextInt(16) + 8;
int k = rand.nextInt(16) + 8;
int l = rand.nextInt(worldIn.getHeight(pos.add(j, 0, k)).getY() + 32);
DOUBLE_PLANT_GENERATOR.generate(worldIn, rand, pos.add(j, l, k));
}
super.decorate(worldIn, rand, pos);
}
public Class <? extends Biome > getBiomeClass()
{
return BiomeSavanna.class;
}
}

View File

@@ -0,0 +1,42 @@
package net.minecraft.world.biome;
import java.util.Random;
import net.minecraft.block.BlockDirt;
import net.minecraft.init.Blocks;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.World;
import net.minecraft.world.chunk.ChunkPrimer;
public class BiomeSavannaMutated extends BiomeSavanna
{
public BiomeSavannaMutated(Biome.BiomeProperties properties)
{
super(properties);
this.decorator.treesPerChunk = 2;
this.decorator.flowersPerChunk = 2;
this.decorator.grassPerChunk = 5;
}
public void genTerrainBlocks(World worldIn, Random rand, ChunkPrimer chunkPrimerIn, int x, int z, double noiseVal)
{
this.topBlock = Blocks.GRASS.getDefaultState();
this.fillerBlock = Blocks.DIRT.getDefaultState();
if (noiseVal > 1.75D)
{
this.topBlock = Blocks.STONE.getDefaultState();
this.fillerBlock = Blocks.STONE.getDefaultState();
}
else if (noiseVal > -0.5D)
{
this.topBlock = Blocks.DIRT.getDefaultState().withProperty(BlockDirt.VARIANT, BlockDirt.DirtType.COARSE_DIRT);
}
this.generateBiomeTerrain(worldIn, rand, chunkPrimerIn, x, z, noiseVal);
}
public void decorate(World worldIn, Random rand, BlockPos pos)
{
this.decorator.decorate(worldIn, rand, this, pos);
}
}

View File

@@ -0,0 +1,86 @@
package net.minecraft.world.biome;
import java.util.Iterator;
import java.util.Random;
import net.minecraft.entity.monster.EntityPolarBear;
import net.minecraft.entity.monster.EntitySkeleton;
import net.minecraft.entity.monster.EntityStray;
import net.minecraft.entity.passive.EntityRabbit;
import net.minecraft.init.Blocks;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.World;
import net.minecraft.world.gen.feature.WorldGenAbstractTree;
import net.minecraft.world.gen.feature.WorldGenIcePath;
import net.minecraft.world.gen.feature.WorldGenIceSpike;
import net.minecraft.world.gen.feature.WorldGenTaiga2;
public class BiomeSnow extends Biome
{
private final boolean superIcy;
private final WorldGenIceSpike iceSpike = new WorldGenIceSpike();
private final WorldGenIcePath icePatch = new WorldGenIcePath(4);
public BiomeSnow(boolean superIcyIn, Biome.BiomeProperties properties)
{
super(properties);
this.superIcy = superIcyIn;
if (superIcyIn)
{
this.topBlock = Blocks.SNOW.getDefaultState();
}
this.spawnableCreatureList.clear();
this.spawnableCreatureList.add(new Biome.SpawnListEntry(EntityRabbit.class, 10, 2, 3));
this.spawnableCreatureList.add(new Biome.SpawnListEntry(EntityPolarBear.class, 1, 1, 2));
Iterator<Biome.SpawnListEntry> iterator = this.spawnableMonsterList.iterator();
while (iterator.hasNext())
{
Biome.SpawnListEntry biome$spawnlistentry = iterator.next();
if (biome$spawnlistentry.entityClass == EntitySkeleton.class)
{
iterator.remove();
}
}
this.spawnableMonsterList.add(new Biome.SpawnListEntry(EntitySkeleton.class, 20, 4, 4));
this.spawnableMonsterList.add(new Biome.SpawnListEntry(EntityStray.class, 80, 4, 4));
}
/**
* returns the chance a creature has to spawn.
*/
public float getSpawningChance()
{
return 0.07F;
}
public void decorate(World worldIn, Random rand, BlockPos pos)
{
if (this.superIcy && net.minecraftforge.event.terraingen.TerrainGen.decorate(worldIn, rand, new net.minecraft.util.math.ChunkPos(pos), net.minecraftforge.event.terraingen.DecorateBiomeEvent.Decorate.EventType.ICE))
{
for (int i = 0; i < 3; ++i)
{
int j = rand.nextInt(16) + 8;
int k = rand.nextInt(16) + 8;
this.iceSpike.generate(worldIn, rand, worldIn.getHeight(pos.add(j, 0, k)));
}
for (int l = 0; l < 2; ++l)
{
int i1 = rand.nextInt(16) + 8;
int j1 = rand.nextInt(16) + 8;
this.icePatch.generate(worldIn, rand, worldIn.getHeight(pos.add(i1, 0, j1)));
}
}
super.decorate(worldIn, rand, pos);
}
public WorldGenAbstractTree getRandomTreeFeature(Random rand)
{
return new WorldGenTaiga2(false);
}
}

View File

@@ -0,0 +1,18 @@
package net.minecraft.world.biome;
import net.minecraft.init.Blocks;
public class BiomeStoneBeach extends Biome
{
public BiomeStoneBeach(Biome.BiomeProperties properties)
{
super(properties);
this.spawnableCreatureList.clear();
this.topBlock = Blocks.STONE.getDefaultState();
this.fillerBlock = Blocks.STONE.getDefaultState();
this.decorator.treesPerChunk = -999;
this.decorator.deadBushPerChunk = 0;
this.decorator.reedsPerChunk = 0;
this.decorator.cactiPerChunk = 0;
}
}

View File

@@ -0,0 +1,107 @@
package net.minecraft.world.biome;
import java.util.Random;
import net.minecraft.block.BlockFlower;
import net.minecraft.block.material.Material;
import net.minecraft.block.state.IBlockState;
import net.minecraft.entity.monster.EntitySlime;
import net.minecraft.init.Blocks;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.World;
import net.minecraft.world.chunk.ChunkPrimer;
import net.minecraft.world.gen.feature.WorldGenAbstractTree;
import net.minecraft.world.gen.feature.WorldGenFossils;
import net.minecraftforge.fml.relauncher.Side;
import net.minecraftforge.fml.relauncher.SideOnly;
public class BiomeSwamp extends Biome
{
protected static final IBlockState WATER_LILY = Blocks.WATERLILY.getDefaultState();
protected BiomeSwamp(Biome.BiomeProperties properties)
{
super(properties);
this.decorator.treesPerChunk = 2;
this.decorator.flowersPerChunk = 1;
this.decorator.deadBushPerChunk = 1;
this.decorator.mushroomsPerChunk = 8;
this.decorator.reedsPerChunk = 10;
this.decorator.clayPerChunk = 1;
this.decorator.waterlilyPerChunk = 4;
this.decorator.sandPatchesPerChunk = 0;
this.decorator.gravelPatchesPerChunk = 0;
this.decorator.grassPerChunk = 5;
this.spawnableMonsterList.add(new Biome.SpawnListEntry(EntitySlime.class, 1, 1, 1));
}
public WorldGenAbstractTree getRandomTreeFeature(Random rand)
{
return SWAMP_FEATURE;
}
public BlockFlower.EnumFlowerType pickRandomFlower(Random rand, BlockPos pos)
{
return BlockFlower.EnumFlowerType.BLUE_ORCHID;
}
public void genTerrainBlocks(World worldIn, Random rand, ChunkPrimer chunkPrimerIn, int x, int z, double noiseVal)
{
double d0 = GRASS_COLOR_NOISE.getValue((double)x * 0.25D, (double)z * 0.25D);
if (d0 > 0.0D)
{
int i = x & 15;
int j = z & 15;
for (int k = 255; k >= 0; --k)
{
if (chunkPrimerIn.getBlockState(j, k, i).getMaterial() != Material.AIR)
{
if (k == 62 && chunkPrimerIn.getBlockState(j, k, i).getBlock() != Blocks.WATER)
{
chunkPrimerIn.setBlockState(j, k, i, WATER);
if (d0 < 0.12D)
{
chunkPrimerIn.setBlockState(j, k + 1, i, WATER_LILY);
}
}
break;
}
}
}
this.generateBiomeTerrain(worldIn, rand, chunkPrimerIn, x, z, noiseVal);
}
public void decorate(World worldIn, Random rand, BlockPos pos)
{
super.decorate(worldIn, rand, pos);
if(net.minecraftforge.event.terraingen.TerrainGen.decorate(worldIn, rand, new net.minecraft.util.math.ChunkPos(pos), net.minecraftforge.event.terraingen.DecorateBiomeEvent.Decorate.EventType.FOSSIL))
if (rand.nextInt(64) == 0)
{
(new WorldGenFossils()).generate(worldIn, rand, pos);
}
}
@SideOnly(Side.CLIENT)
public int getGrassColorAtPos(BlockPos pos)
{
double d0 = GRASS_COLOR_NOISE.getValue((double)pos.getX() * 0.0225D, (double)pos.getZ() * 0.0225D);
return getModdedBiomeGrassColor(d0 < -0.1D ? 5011004 : 6975545);
}
@SideOnly(Side.CLIENT)
public int getFoliageColorAtPos(BlockPos pos)
{
return getModdedBiomeFoliageColor(6975545);
}
@Override
public void addDefaultFlowers()
{
addFlower(Blocks.RED_FLOWER.getDefaultState().withProperty(Blocks.RED_FLOWER.getTypeProperty(), BlockFlower.EnumFlowerType.BLUE_ORCHID), 10);
}
}

View File

@@ -0,0 +1,126 @@
package net.minecraft.world.biome;
import java.util.Random;
import net.minecraft.block.BlockDirt;
import net.minecraft.block.BlockDoublePlant;
import net.minecraft.block.BlockTallGrass;
import net.minecraft.entity.passive.EntityRabbit;
import net.minecraft.entity.passive.EntityWolf;
import net.minecraft.init.Blocks;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.World;
import net.minecraft.world.chunk.ChunkPrimer;
import net.minecraft.world.gen.feature.WorldGenAbstractTree;
import net.minecraft.world.gen.feature.WorldGenBlockBlob;
import net.minecraft.world.gen.feature.WorldGenMegaPineTree;
import net.minecraft.world.gen.feature.WorldGenTaiga1;
import net.minecraft.world.gen.feature.WorldGenTaiga2;
import net.minecraft.world.gen.feature.WorldGenTallGrass;
import net.minecraft.world.gen.feature.WorldGenerator;
public class BiomeTaiga extends Biome
{
private static final WorldGenTaiga1 PINE_GENERATOR = new WorldGenTaiga1();
private static final WorldGenTaiga2 SPRUCE_GENERATOR = new WorldGenTaiga2(false);
private static final WorldGenMegaPineTree MEGA_PINE_GENERATOR = new WorldGenMegaPineTree(false, false);
private static final WorldGenMegaPineTree MEGA_SPRUCE_GENERATOR = new WorldGenMegaPineTree(false, true);
private static final WorldGenBlockBlob FOREST_ROCK_GENERATOR = new WorldGenBlockBlob(Blocks.MOSSY_COBBLESTONE, 0);
private final BiomeTaiga.Type type;
public BiomeTaiga(BiomeTaiga.Type typeIn, Biome.BiomeProperties properties)
{
super(properties);
this.type = typeIn;
this.spawnableCreatureList.add(new Biome.SpawnListEntry(EntityWolf.class, 8, 4, 4));
this.spawnableCreatureList.add(new Biome.SpawnListEntry(EntityRabbit.class, 4, 2, 3));
this.decorator.treesPerChunk = 10;
if (typeIn != BiomeTaiga.Type.MEGA && typeIn != BiomeTaiga.Type.MEGA_SPRUCE)
{
this.decorator.grassPerChunk = 1;
this.decorator.mushroomsPerChunk = 1;
}
else
{
this.decorator.grassPerChunk = 7;
this.decorator.deadBushPerChunk = 1;
this.decorator.mushroomsPerChunk = 3;
}
}
public WorldGenAbstractTree getRandomTreeFeature(Random rand)
{
if ((this.type == BiomeTaiga.Type.MEGA || this.type == BiomeTaiga.Type.MEGA_SPRUCE) && rand.nextInt(3) == 0)
{
return this.type != BiomeTaiga.Type.MEGA_SPRUCE && rand.nextInt(13) != 0 ? MEGA_PINE_GENERATOR : MEGA_SPRUCE_GENERATOR;
}
else
{
return (WorldGenAbstractTree)(rand.nextInt(3) == 0 ? PINE_GENERATOR : SPRUCE_GENERATOR);
}
}
/**
* Gets a WorldGen appropriate for this biome.
*/
public WorldGenerator getRandomWorldGenForGrass(Random rand)
{
return rand.nextInt(5) > 0 ? new WorldGenTallGrass(BlockTallGrass.EnumType.FERN) : new WorldGenTallGrass(BlockTallGrass.EnumType.GRASS);
}
public void decorate(World worldIn, Random rand, BlockPos pos)
{
if ((this.type == BiomeTaiga.Type.MEGA || this.type == BiomeTaiga.Type.MEGA_SPRUCE) && net.minecraftforge.event.terraingen.TerrainGen.decorate(worldIn, rand, new net.minecraft.util.math.ChunkPos(pos), net.minecraftforge.event.terraingen.DecorateBiomeEvent.Decorate.EventType.ROCK))
{
int i = rand.nextInt(3);
for (int j = 0; j < i; ++j)
{
int k = rand.nextInt(16) + 8;
int l = rand.nextInt(16) + 8;
BlockPos blockpos = worldIn.getHeight(pos.add(k, 0, l));
FOREST_ROCK_GENERATOR.generate(worldIn, rand, blockpos);
}
}
DOUBLE_PLANT_GENERATOR.setPlantType(BlockDoublePlant.EnumPlantType.FERN);
if(net.minecraftforge.event.terraingen.TerrainGen.decorate(worldIn, rand, new net.minecraft.util.math.ChunkPos(pos), net.minecraftforge.event.terraingen.DecorateBiomeEvent.Decorate.EventType.FLOWERS))
for (int i1 = 0; i1 < 7; ++i1)
{
int j1 = rand.nextInt(16) + 8;
int k1 = rand.nextInt(16) + 8;
int l1 = rand.nextInt(worldIn.getHeight(pos.add(j1, 0, k1)).getY() + 32);
DOUBLE_PLANT_GENERATOR.generate(worldIn, rand, pos.add(j1, l1, k1));
}
super.decorate(worldIn, rand, pos);
}
public void genTerrainBlocks(World worldIn, Random rand, ChunkPrimer chunkPrimerIn, int x, int z, double noiseVal)
{
if (this.type == BiomeTaiga.Type.MEGA || this.type == BiomeTaiga.Type.MEGA_SPRUCE)
{
this.topBlock = Blocks.GRASS.getDefaultState();
this.fillerBlock = Blocks.DIRT.getDefaultState();
if (noiseVal > 1.75D)
{
this.topBlock = Blocks.DIRT.getDefaultState().withProperty(BlockDirt.VARIANT, BlockDirt.DirtType.COARSE_DIRT);
}
else if (noiseVal > -0.95D)
{
this.topBlock = Blocks.DIRT.getDefaultState().withProperty(BlockDirt.VARIANT, BlockDirt.DirtType.PODZOL);
}
}
this.generateBiomeTerrain(worldIn, rand, chunkPrimerIn, x, z, noiseVal);
}
public static enum Type
{
NORMAL,
MEGA,
MEGA_SPRUCE;
}
}

View File

@@ -0,0 +1,19 @@
package net.minecraft.world.biome;
public class BiomeVoid extends Biome
{
public BiomeVoid(Biome.BiomeProperties properties)
{
super(properties);
this.spawnableMonsterList.clear();
this.spawnableCreatureList.clear();
this.spawnableWaterCreatureList.clear();
this.spawnableCaveCreatureList.clear();
this.decorator = new BiomeVoidDecorator();
}
public boolean ignorePlayerSpawnSuitability()
{
return true;
}
}

View File

@@ -0,0 +1,43 @@
package net.minecraft.world.biome;
import java.util.Random;
import net.minecraft.init.Blocks;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.World;
public class BiomeVoidDecorator extends BiomeDecorator
{
public void decorate(World worldIn, Random random, Biome biome, BlockPos pos)
{
BlockPos blockpos = worldIn.getSpawnPoint();
int i = 16;
double d0 = blockpos.distanceSq(pos.add(8, blockpos.getY(), 8));
if (d0 <= 1024.0D)
{
BlockPos blockpos1 = new BlockPos(blockpos.getX() - 16, blockpos.getY() - 1, blockpos.getZ() - 16);
BlockPos blockpos2 = new BlockPos(blockpos.getX() + 16, blockpos.getY() - 1, blockpos.getZ() + 16);
BlockPos.MutableBlockPos blockpos$mutableblockpos = new BlockPos.MutableBlockPos(blockpos1);
for (int j = pos.getZ(); j < pos.getZ() + 16; ++j)
{
for (int k = pos.getX(); k < pos.getX() + 16; ++k)
{
if (j >= blockpos1.getZ() && j <= blockpos2.getZ() && k >= blockpos1.getX() && k <= blockpos2.getX())
{
blockpos$mutableblockpos.setPos(k, blockpos$mutableblockpos.getY(), j);
if (blockpos.getX() == k && blockpos.getZ() == j)
{
worldIn.setBlockState(blockpos$mutableblockpos, Blocks.COBBLESTONE.getDefaultState(), 2);
}
else
{
worldIn.setBlockState(blockpos$mutableblockpos, Blocks.STONE.getDefaultState(), 2);
}
}
}
}
}
}
}

View File

@@ -0,0 +1,7 @@
// Auto generated package-info by MCP
@ParametersAreNonnullByDefault
@MethodsReturnNonnullByDefault
package net.minecraft.world.biome;
import mcp.MethodsReturnNonnullByDefault;
import javax.annotation.ParametersAreNonnullByDefault;

View File

@@ -0,0 +1,27 @@
package net.minecraft.world.border;
import net.minecraftforge.fml.relauncher.Side;
import net.minecraftforge.fml.relauncher.SideOnly;
public enum EnumBorderStatus
{
GROWING(4259712),
SHRINKING(16724016),
STATIONARY(2138367);
private final int color;
private EnumBorderStatus(int color)
{
this.color = color;
}
/**
* Retrieve the color that the border should be while in this state
*/
@SideOnly(Side.CLIENT)
public int getColor()
{
return this.color;
}
}

View File

@@ -0,0 +1,18 @@
package net.minecraft.world.border;
public interface IBorderListener
{
void onSizeChanged(WorldBorder border, double newSize);
void onTransitionStarted(WorldBorder border, double oldSize, double newSize, long time);
void onCenterChanged(WorldBorder border, double x, double z);
void onWarningTimeChanged(WorldBorder border, int newTime);
void onWarningDistanceChanged(WorldBorder border, int newDistance);
void onDamageAmountChanged(WorldBorder border, double newAmount);
void onDamageBufferChanged(WorldBorder border, double newSize);
}

View File

@@ -0,0 +1,292 @@
package net.minecraft.world.border;
import com.google.common.collect.Lists;
import java.util.List;
import net.minecraft.entity.Entity;
import net.minecraft.util.math.AxisAlignedBB;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.ChunkPos;
import net.minecraftforge.fml.relauncher.Side;
import net.minecraftforge.fml.relauncher.SideOnly;
public class WorldBorder
{
private final List<IBorderListener> listeners = Lists.<IBorderListener>newArrayList();
private double centerX;
private double centerZ;
private double startDiameter = 6.0E7D;
private double endDiameter;
private long endTime;
private long startTime;
private int worldSize;
private double damageAmount;
private double damageBuffer;
private int warningTime;
private int warningDistance;
public WorldBorder()
{
this.endDiameter = this.startDiameter;
this.worldSize = 29999984;
this.damageAmount = 0.2D;
this.damageBuffer = 5.0D;
this.warningTime = 15;
this.warningDistance = 5;
}
public boolean contains(BlockPos pos)
{
return (double)(pos.getX() + 1) > this.minX() && (double)pos.getX() < this.maxX() && (double)(pos.getZ() + 1) > this.minZ() && (double)pos.getZ() < this.maxZ();
}
public boolean contains(ChunkPos range)
{
return (double)range.getXEnd() > this.minX() && (double)range.getXStart() < this.maxX() && (double)range.getZEnd() > this.minZ() && (double)range.getZStart() < this.maxZ();
}
public boolean contains(AxisAlignedBB bb)
{
return bb.maxX > this.minX() && bb.minX < this.maxX() && bb.maxZ > this.minZ() && bb.minZ < this.maxZ();
}
public double getClosestDistance(Entity entityIn)
{
return this.getClosestDistance(entityIn.posX, entityIn.posZ);
}
public double getClosestDistance(double x, double z)
{
double d0 = z - this.minZ();
double d1 = this.maxZ() - z;
double d2 = x - this.minX();
double d3 = this.maxX() - x;
double d4 = Math.min(d2, d3);
d4 = Math.min(d4, d0);
return Math.min(d4, d1);
}
public EnumBorderStatus getStatus()
{
if (this.endDiameter < this.startDiameter)
{
return EnumBorderStatus.SHRINKING;
}
else
{
return this.endDiameter > this.startDiameter ? EnumBorderStatus.GROWING : EnumBorderStatus.STATIONARY;
}
}
public double minX()
{
double d0 = this.getCenterX() - this.getDiameter() / 2.0D;
if (d0 < (double)(-this.worldSize))
{
d0 = (double)(-this.worldSize);
}
return d0;
}
public double minZ()
{
double d0 = this.getCenterZ() - this.getDiameter() / 2.0D;
if (d0 < (double)(-this.worldSize))
{
d0 = (double)(-this.worldSize);
}
return d0;
}
public double maxX()
{
double d0 = this.getCenterX() + this.getDiameter() / 2.0D;
if (d0 > (double)this.worldSize)
{
d0 = (double)this.worldSize;
}
return d0;
}
public double maxZ()
{
double d0 = this.getCenterZ() + this.getDiameter() / 2.0D;
if (d0 > (double)this.worldSize)
{
d0 = (double)this.worldSize;
}
return d0;
}
public double getCenterX()
{
return this.centerX;
}
public double getCenterZ()
{
return this.centerZ;
}
public void setCenter(double x, double z)
{
this.centerX = x;
this.centerZ = z;
for (IBorderListener iborderlistener : this.getListeners())
{
iborderlistener.onCenterChanged(this, x, z);
}
}
public double getDiameter()
{
if (this.getStatus() != EnumBorderStatus.STATIONARY)
{
double d0 = (double)((float)(System.currentTimeMillis() - this.startTime) / (float)(this.endTime - this.startTime));
if (d0 < 1.0D)
{
return this.startDiameter + (this.endDiameter - this.startDiameter) * d0;
}
this.setTransition(this.endDiameter);
}
return this.startDiameter;
}
public long getTimeUntilTarget()
{
return this.getStatus() == EnumBorderStatus.STATIONARY ? 0L : this.endTime - System.currentTimeMillis();
}
public double getTargetSize()
{
return this.endDiameter;
}
public void setTransition(double newSize)
{
this.startDiameter = newSize;
this.endDiameter = newSize;
this.endTime = System.currentTimeMillis();
this.startTime = this.endTime;
for (IBorderListener iborderlistener : this.getListeners())
{
iborderlistener.onSizeChanged(this, newSize);
}
}
public void setTransition(double oldSize, double newSize, long time)
{
this.startDiameter = oldSize;
this.endDiameter = newSize;
this.startTime = System.currentTimeMillis();
this.endTime = this.startTime + time;
for (IBorderListener iborderlistener : this.getListeners())
{
iborderlistener.onTransitionStarted(this, oldSize, newSize, time);
}
}
protected List<IBorderListener> getListeners()
{
return Lists.newArrayList(this.listeners);
}
public void addListener(IBorderListener listener)
{
this.listeners.add(listener);
}
public void setSize(int size)
{
this.worldSize = size;
}
public int getSize()
{
return this.worldSize;
}
public double getDamageBuffer()
{
return this.damageBuffer;
}
public void setDamageBuffer(double bufferSize)
{
this.damageBuffer = bufferSize;
for (IBorderListener iborderlistener : this.getListeners())
{
iborderlistener.onDamageBufferChanged(this, bufferSize);
}
}
public double getDamageAmount()
{
return this.damageAmount;
}
public void setDamageAmount(double newAmount)
{
this.damageAmount = newAmount;
for (IBorderListener iborderlistener : this.getListeners())
{
iborderlistener.onDamageAmountChanged(this, newAmount);
}
}
@SideOnly(Side.CLIENT)
public double getResizeSpeed()
{
return this.endTime == this.startTime ? 0.0D : Math.abs(this.startDiameter - this.endDiameter) / (double)(this.endTime - this.startTime);
}
public int getWarningTime()
{
return this.warningTime;
}
public void setWarningTime(int warningTime)
{
this.warningTime = warningTime;
for (IBorderListener iborderlistener : this.getListeners())
{
iborderlistener.onWarningTimeChanged(this, warningTime);
}
}
public int getWarningDistance()
{
return this.warningDistance;
}
public void setWarningDistance(int warningDistance)
{
this.warningDistance = warningDistance;
for (IBorderListener iborderlistener : this.getListeners())
{
iborderlistener.onWarningDistanceChanged(this, warningDistance);
}
}
public void removeListener(IBorderListener listener)
{
this.listeners.remove(listener);
}
}

View File

@@ -0,0 +1,7 @@
// Auto generated package-info by MCP
@ParametersAreNonnullByDefault
@MethodsReturnNonnullByDefault
package net.minecraft.world.border;
import mcp.MethodsReturnNonnullByDefault;
import javax.annotation.ParametersAreNonnullByDefault;

View File

@@ -0,0 +1,175 @@
package net.minecraft.world.chunk;
import javax.annotation.Nullable;
import net.minecraft.block.Block;
import net.minecraft.block.state.IBlockState;
import net.minecraft.init.Blocks;
import net.minecraft.network.PacketBuffer;
import net.minecraft.util.BitArray;
import net.minecraft.util.math.MathHelper;
import net.minecraftforge.fml.relauncher.Side;
import net.minecraftforge.fml.relauncher.SideOnly;
public class BlockStateContainer implements IBlockStatePaletteResizer
{
private static final IBlockStatePalette REGISTRY_BASED_PALETTE = new BlockStatePaletteRegistry();
protected static final IBlockState AIR_BLOCK_STATE = Blocks.AIR.getDefaultState();
protected BitArray storage;
protected IBlockStatePalette palette;
private int bits;
public BlockStateContainer()
{
this.setBits(4);
}
private static int getIndex(int x, int y, int z)
{
return y << 8 | z << 4 | x;
}
private void setBits(int bitsIn)
{
setBits(bitsIn, false);
}
private void setBits(int bitsIn, boolean forceBits)
{
if (bitsIn != this.bits)
{
this.bits = bitsIn;
if (this.bits <= 4)
{
this.bits = 4;
this.palette = new BlockStatePaletteLinear(this.bits, this);
}
else if (this.bits <= 8)
{
this.palette = new BlockStatePaletteHashMap(this.bits, this);
}
else
{
this.palette = REGISTRY_BASED_PALETTE;
this.bits = MathHelper.log2DeBruijn(Block.BLOCK_STATE_IDS.size());
if (forceBits)
this.bits = bitsIn;
}
this.palette.idFor(AIR_BLOCK_STATE);
this.storage = new BitArray(this.bits, 4096);
}
}
public int onResize(int bits, IBlockState state)
{
BitArray bitarray = this.storage;
IBlockStatePalette iblockstatepalette = this.palette;
this.setBits(bits);
for (int i = 0; i < bitarray.size(); ++i)
{
IBlockState iblockstate = iblockstatepalette.getBlockState(bitarray.getAt(i));
if (iblockstate != null)
{
this.set(i, iblockstate);
}
}
return this.palette.idFor(state);
}
public void set(int x, int y, int z, IBlockState state)
{
this.set(getIndex(x, y, z), state);
}
protected void set(int index, IBlockState state)
{
int i = this.palette.idFor(state);
this.storage.setAt(index, i);
}
public IBlockState get(int x, int y, int z)
{
return this.get(getIndex(x, y, z));
}
protected IBlockState get(int index)
{
IBlockState iblockstate = this.palette.getBlockState(this.storage.getAt(index));
return iblockstate == null ? AIR_BLOCK_STATE : iblockstate;
}
@SideOnly(Side.CLIENT)
public void read(PacketBuffer buf)
{
int i = buf.readByte();
if (this.bits != i)
{
this.setBits(i, true); //Forge, Force bit density to fix network issues, resize below if needed.
}
this.palette.read(buf);
buf.readLongArray(this.storage.getBackingLongArray());
int regSize = MathHelper.log2DeBruijn(Block.BLOCK_STATE_IDS.size());
if (this.palette == REGISTRY_BASED_PALETTE && this.bits != regSize) // Resize bits to fit registry.
this.onResize(regSize, AIR_BLOCK_STATE);
}
public void write(PacketBuffer buf)
{
buf.writeByte(this.bits);
this.palette.write(buf);
buf.writeLongArray(this.storage.getBackingLongArray());
}
@Nullable
public NibbleArray getDataForNBT(byte[] blockIds, NibbleArray data)
{
NibbleArray nibblearray = null;
for (int i = 0; i < 4096; ++i)
{
int j = Block.BLOCK_STATE_IDS.get(this.get(i));
int k = i & 15;
int l = i >> 8 & 15;
int i1 = i >> 4 & 15;
if ((j >> 12 & 15) != 0)
{
if (nibblearray == null)
{
nibblearray = new NibbleArray();
}
nibblearray.set(k, l, i1, j >> 12 & 15);
}
blockIds[i] = (byte)(j >> 4 & 255);
data.set(k, l, i1, j & 15);
}
return nibblearray;
}
public void setDataFromNBT(byte[] blockIds, NibbleArray data, @Nullable NibbleArray blockIdExtension)
{
for (int i = 0; i < 4096; ++i)
{
int j = i & 15;
int k = i >> 8 & 15;
int l = i >> 4 & 15;
int i1 = blockIdExtension == null ? 0 : blockIdExtension.get(j, k, l);
int j1 = i1 << 12 | (blockIds[i] & 255) << 4 | data.get(j, k, l);
this.set(i, Block.BLOCK_STATE_IDS.getByValue(j1));
}
}
public int getSerializedSize()
{
return 1 + this.palette.getSerializedSize() + PacketBuffer.getVarIntSize(this.storage.size()) + this.storage.getBackingLongArray().length * 8;
}
}

View File

@@ -0,0 +1,84 @@
package net.minecraft.world.chunk;
import javax.annotation.Nullable;
import net.minecraft.block.Block;
import net.minecraft.block.state.IBlockState;
import net.minecraft.network.PacketBuffer;
import net.minecraft.util.IntIdentityHashBiMap;
import net.minecraftforge.fml.relauncher.Side;
import net.minecraftforge.fml.relauncher.SideOnly;
public class BlockStatePaletteHashMap implements IBlockStatePalette
{
private final IntIdentityHashBiMap<IBlockState> statePaletteMap;
private final IBlockStatePaletteResizer paletteResizer;
private final int bits;
public BlockStatePaletteHashMap(int bitsIn, IBlockStatePaletteResizer paletteResizerIn)
{
this.bits = bitsIn;
this.paletteResizer = paletteResizerIn;
this.statePaletteMap = new IntIdentityHashBiMap<IBlockState>(1 << bitsIn);
}
public int idFor(IBlockState state)
{
int i = this.statePaletteMap.getId(state);
if (i == -1)
{
i = this.statePaletteMap.add(state);
if (i >= 1 << this.bits)
{
i = this.paletteResizer.onResize(this.bits + 1, state);
}
}
return i;
}
/**
* Gets the block state by the palette id.
*/
@Nullable
public IBlockState getBlockState(int indexKey)
{
return this.statePaletteMap.get(indexKey);
}
@SideOnly(Side.CLIENT)
public void read(PacketBuffer buf)
{
this.statePaletteMap.clear();
int i = buf.readVarInt();
for (int j = 0; j < i; ++j)
{
this.statePaletteMap.add(Block.BLOCK_STATE_IDS.getByValue(buf.readVarInt()));
}
}
public void write(PacketBuffer buf)
{
int i = this.statePaletteMap.size();
buf.writeVarInt(i);
for (int j = 0; j < i; ++j)
{
buf.writeVarInt(Block.BLOCK_STATE_IDS.get(this.statePaletteMap.get(j)));
}
}
public int getSerializedSize()
{
int i = PacketBuffer.getVarIntSize(this.statePaletteMap.size());
for (int j = 0; j < this.statePaletteMap.size(); ++j)
{
i += PacketBuffer.getVarIntSize(Block.BLOCK_STATE_IDS.get(this.statePaletteMap.get(j)));
}
return i;
}
}

View File

@@ -0,0 +1,89 @@
package net.minecraft.world.chunk;
import javax.annotation.Nullable;
import net.minecraft.block.Block;
import net.minecraft.block.state.IBlockState;
import net.minecraft.network.PacketBuffer;
import net.minecraftforge.fml.relauncher.Side;
import net.minecraftforge.fml.relauncher.SideOnly;
public class BlockStatePaletteLinear implements IBlockStatePalette
{
private final IBlockState[] states;
private final IBlockStatePaletteResizer resizeHandler;
private final int bits;
private int arraySize;
public BlockStatePaletteLinear(int bitsIn, IBlockStatePaletteResizer resizeHandlerIn)
{
this.states = new IBlockState[1 << bitsIn];
this.bits = bitsIn;
this.resizeHandler = resizeHandlerIn;
}
public int idFor(IBlockState state)
{
for (int i = 0; i < this.arraySize; ++i)
{
if (this.states[i] == state)
{
return i;
}
}
int j = this.arraySize;
if (j < this.states.length)
{
this.states[j] = state;
++this.arraySize;
return j;
}
else
{
return this.resizeHandler.onResize(this.bits + 1, state);
}
}
/**
* Gets the block state by the palette id.
*/
@Nullable
public IBlockState getBlockState(int indexKey)
{
return indexKey >= 0 && indexKey < this.arraySize ? this.states[indexKey] : null;
}
@SideOnly(Side.CLIENT)
public void read(PacketBuffer buf)
{
this.arraySize = buf.readVarInt();
for (int i = 0; i < this.arraySize; ++i)
{
this.states[i] = Block.BLOCK_STATE_IDS.getByValue(buf.readVarInt());
}
}
public void write(PacketBuffer buf)
{
buf.writeVarInt(this.arraySize);
for (int i = 0; i < this.arraySize; ++i)
{
buf.writeVarInt(Block.BLOCK_STATE_IDS.get(this.states[i]));
}
}
public int getSerializedSize()
{
int i = PacketBuffer.getVarIntSize(this.arraySize);
for (int j = 0; j < this.arraySize; ++j)
{
i += PacketBuffer.getVarIntSize(Block.BLOCK_STATE_IDS.get(this.states[j]));
}
return i;
}
}

View File

@@ -0,0 +1,42 @@
package net.minecraft.world.chunk;
import net.minecraft.block.Block;
import net.minecraft.block.state.IBlockState;
import net.minecraft.init.Blocks;
import net.minecraft.network.PacketBuffer;
import net.minecraftforge.fml.relauncher.Side;
import net.minecraftforge.fml.relauncher.SideOnly;
public class BlockStatePaletteRegistry implements IBlockStatePalette
{
public int idFor(IBlockState state)
{
int i = Block.BLOCK_STATE_IDS.get(state);
return i == -1 ? 0 : i;
}
/**
* Gets the block state by the palette id.
*/
public IBlockState getBlockState(int indexKey)
{
IBlockState iblockstate = Block.BLOCK_STATE_IDS.getByValue(indexKey);
return iblockstate == null ? Blocks.AIR.getDefaultState() : iblockstate;
}
@SideOnly(Side.CLIENT)
public void read(PacketBuffer buf)
{
buf.readVarInt();
}
public void write(PacketBuffer buf)
{
buf.writeVarInt(0);
}
public int getSerializedSize()
{
return PacketBuffer.getVarIntSize(0);
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,48 @@
package net.minecraft.world.chunk;
import net.minecraft.block.Block;
import net.minecraft.block.state.IBlockState;
import net.minecraft.init.Blocks;
public class ChunkPrimer
{
private static final IBlockState DEFAULT_STATE = Blocks.AIR.getDefaultState();
private final char[] data = new char[65536];
public IBlockState getBlockState(int x, int y, int z)
{
IBlockState iblockstate = Block.BLOCK_STATE_IDS.getByValue(this.data[getBlockIndex(x, y, z)]);
return iblockstate == null ? DEFAULT_STATE : iblockstate;
}
public void setBlockState(int x, int y, int z, IBlockState state)
{
this.data[getBlockIndex(x, y, z)] = (char)Block.BLOCK_STATE_IDS.get(state);
}
private static int getBlockIndex(int x, int y, int z)
{
return x << 12 | z << 8 | y;
}
/**
* Counting down from the highest block in the sky, find the first non-air block for the given location
* (actually, looks like mostly checks x, z+1? And actually checks only the very top sky block of actual x, z)
*/
public int findGroundBlockIdx(int x, int z)
{
int i = (x << 12 | z << 8) + 256 - 1;
for (int j = 255; j >= 0; --j)
{
IBlockState iblockstate = Block.BLOCK_STATE_IDS.getByValue(this.data[i + j]);
if (iblockstate != null && iblockstate != DEFAULT_STATE)
{
return j;
}
}
return 0;
}
}

View File

@@ -0,0 +1,185 @@
package net.minecraft.world.chunk;
import com.google.common.base.Predicate;
import java.util.List;
import java.util.Random;
import javax.annotation.Nullable;
import net.minecraft.block.state.IBlockState;
import net.minecraft.entity.Entity;
import net.minecraft.init.Blocks;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.math.AxisAlignedBB;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.EnumSkyBlock;
import net.minecraft.world.World;
import net.minecraftforge.fml.relauncher.Side;
import net.minecraftforge.fml.relauncher.SideOnly;
@SideOnly(Side.CLIENT)
public class EmptyChunk extends Chunk
{
public EmptyChunk(World worldIn, int x, int z)
{
super(worldIn, x, z);
}
/**
* Checks whether the chunk is at the X/Z location specified
*/
public boolean isAtLocation(int x, int z)
{
return x == this.x && z == this.z;
}
/**
* Returns the value in the height map at this x, z coordinate in the chunk
*/
public int getHeightValue(int x, int z)
{
return 0;
}
/**
* Generates the height map for a chunk from scratch
*/
public void generateHeightMap()
{
}
/**
* Generates the initial skylight map for the chunk upon generation or load.
*/
public void generateSkylightMap()
{
}
public IBlockState getBlockState(BlockPos pos)
{
return Blocks.AIR.getDefaultState();
}
public int getBlockLightOpacity(BlockPos pos)
{
return 255;
}
public int getLightFor(EnumSkyBlock type, BlockPos pos)
{
return type.defaultLightValue;
}
public void setLightFor(EnumSkyBlock type, BlockPos pos, int value)
{
}
public int getLightSubtracted(BlockPos pos, int amount)
{
return 0;
}
/**
* Adds an entity to the chunk.
*/
public void addEntity(Entity entityIn)
{
}
/**
* removes entity using its y chunk coordinate as its index
*/
public void removeEntity(Entity entityIn)
{
}
/**
* Removes entity at the specified index from the entity array.
*/
public void removeEntityAtIndex(Entity entityIn, int index)
{
}
public boolean canSeeSky(BlockPos pos)
{
return false;
}
@Nullable
public TileEntity getTileEntity(BlockPos pos, Chunk.EnumCreateEntityType p_177424_2_)
{
return null;
}
public void addTileEntity(TileEntity tileEntityIn)
{
}
public void addTileEntity(BlockPos pos, TileEntity tileEntityIn)
{
}
public void removeTileEntity(BlockPos pos)
{
}
/**
* Called when this Chunk is loaded by the ChunkProvider
*/
public void onLoad()
{
}
/**
* Called when this Chunk is unloaded by the ChunkProvider
*/
public void onUnload()
{
}
/**
* Sets the isModified flag for this Chunk
*/
public void markDirty()
{
}
/**
* Fills the given list of all entities that intersect within the given bounding box that aren't the passed entity.
*/
public void getEntitiesWithinAABBForEntity(@Nullable Entity entityIn, AxisAlignedBB aabb, List<Entity> listToFill, Predicate <? super Entity > filter)
{
}
/**
* Gets all entities that can be assigned to the specified class.
*/
public <T extends Entity> void getEntitiesOfTypeWithinAABB(Class <? extends T > entityClass, AxisAlignedBB aabb, List<T> listToFill, Predicate <? super T > filter)
{
}
/**
* Returns true if this Chunk needs to be saved
*/
public boolean needsSaving(boolean p_76601_1_)
{
return false;
}
public Random getRandomWithSeed(long seed)
{
return new Random(this.getWorld().getSeed() + (long)(this.x * this.x * 4987142) + (long)(this.x * 5947611) + (long)(this.z * this.z) * 4392871L + (long)(this.z * 389711) ^ seed);
}
public boolean isEmpty()
{
return true;
}
/**
* Returns whether the ExtendedBlockStorages containing levels (in blocks) from arg 1 to arg 2 are fully empty
* (true) or not (false).
*/
public boolean isEmptyBetween(int startY, int endY)
{
return true;
}
}

View File

@@ -0,0 +1,25 @@
package net.minecraft.world.chunk;
import javax.annotation.Nullable;
import net.minecraft.block.state.IBlockState;
import net.minecraft.network.PacketBuffer;
import net.minecraftforge.fml.relauncher.Side;
import net.minecraftforge.fml.relauncher.SideOnly;
public interface IBlockStatePalette
{
int idFor(IBlockState state);
/**
* Gets the block state by the palette id.
*/
@Nullable
IBlockState getBlockState(int indexKey);
@SideOnly(Side.CLIENT)
void read(PacketBuffer buf);
void write(PacketBuffer buf);
int getSerializedSize();
}

View File

@@ -0,0 +1,8 @@
package net.minecraft.world.chunk;
import net.minecraft.block.state.IBlockState;
interface IBlockStatePaletteResizer
{
int onResize(int bits, IBlockState state);
}

View File

@@ -0,0 +1,23 @@
package net.minecraft.world.chunk;
import javax.annotation.Nullable;
public interface IChunkProvider
{
@Nullable
Chunk getLoadedChunk(int x, int z);
Chunk provideChunk(int x, int z);
/**
* Unloads chunks that are marked to be unloaded. This is not guaranteed to unload every such chunk.
*/
boolean tick();
/**
* Converts the instance data to a readable string.
*/
String makeString();
boolean isChunkGeneratedAt(int x, int z);
}

View File

@@ -0,0 +1,81 @@
package net.minecraft.world.chunk;
public class NibbleArray
{
/**
* Byte array of data stored in this holder. Possibly a light map or some chunk data. Data is accessed in 4-bit
* pieces.
*/
private final byte[] data;
public NibbleArray()
{
this.data = new byte[2048];
}
public NibbleArray(byte[] storageArray)
{
this.data = storageArray;
if (storageArray.length != 2048)
{
throw new IllegalArgumentException("ChunkNibbleArrays should be 2048 bytes not: " + storageArray.length);
}
}
/**
* Returns the nibble of data corresponding to the passed in x, y, z. y is at most 6 bits, z is at most 4.
*/
public int get(int x, int y, int z)
{
return this.getFromIndex(this.getCoordinateIndex(x, y, z));
}
/**
* Arguments are x, y, z, val. Sets the nibble of data at x << 11 | z << 7 | y to val.
*/
public void set(int x, int y, int z, int value)
{
this.setIndex(this.getCoordinateIndex(x, y, z), value);
}
private int getCoordinateIndex(int x, int y, int z)
{
return y << 8 | z << 4 | x;
}
public int getFromIndex(int index)
{
int i = this.getNibbleIndex(index);
return this.isLowerNibble(index) ? this.data[i] & 15 : this.data[i] >> 4 & 15;
}
public void setIndex(int index, int value)
{
int i = this.getNibbleIndex(index);
if (this.isLowerNibble(index))
{
this.data[i] = (byte)(this.data[i] & 240 | value & 15);
}
else
{
this.data[i] = (byte)(this.data[i] & 15 | (value & 15) << 4);
}
}
private boolean isLowerNibble(int index)
{
return (index & 1) == 0;
}
private int getNibbleIndex(int index)
{
return index >> 1;
}
public byte[] getData()
{
return this.data;
}
}

View File

@@ -0,0 +1,7 @@
// Auto generated package-info by MCP
@ParametersAreNonnullByDefault
@MethodsReturnNonnullByDefault
package net.minecraft.world.chunk;
import mcp.MethodsReturnNonnullByDefault;
import javax.annotation.ParametersAreNonnullByDefault;

View File

@@ -0,0 +1,694 @@
package net.minecraft.world.chunk.storage;
import com.google.common.collect.Maps;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.File;
import java.io.IOException;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Set;
import javax.annotation.Nullable;
import net.minecraft.block.Block;
import net.minecraft.entity.Entity;
import net.minecraft.entity.EntityList;
import net.minecraft.nbt.CompressedStreamTools;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.nbt.NBTTagList;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.ResourceLocation;
import net.minecraft.util.datafix.DataFixer;
import net.minecraft.util.datafix.FixTypes;
import net.minecraft.util.datafix.IDataFixer;
import net.minecraft.util.datafix.IDataWalker;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.ChunkPos;
import net.minecraft.world.MinecraftException;
import net.minecraft.world.NextTickListEntry;
import net.minecraft.world.World;
import net.minecraft.world.chunk.Chunk;
import net.minecraft.world.chunk.NibbleArray;
import net.minecraft.world.storage.IThreadedFileIO;
import net.minecraft.world.storage.ThreadedFileIOBase;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
public class AnvilChunkLoader implements IChunkLoader, IThreadedFileIO
{
private static final Logger LOGGER = LogManager.getLogger();
/**
* A map containing chunks to be written to disk (but not those that are currently in the process of being written).
* Key is the chunk position, value is the NBT to write.
*/
private final Map<ChunkPos, NBTTagCompound> chunksToSave = Maps.<ChunkPos, NBTTagCompound>newConcurrentMap();
/** A set containing the chunk that is currently in the process of being written to disk. */
private final Set<ChunkPos> chunksBeingSaved = Collections.<ChunkPos>newSetFromMap(Maps.newConcurrentMap());
/** Save directory for chunks using the Anvil format */
public final File chunkSaveLocation;
private final DataFixer fixer;
private boolean flushing;
public AnvilChunkLoader(File chunkSaveLocationIn, DataFixer dataFixerIn)
{
this.chunkSaveLocation = chunkSaveLocationIn;
this.fixer = dataFixerIn;
}
@Deprecated // TODO: remove (1.13)
public boolean chunkExists(World world, int x, int z)
{
return isChunkGeneratedAt(x, z);
}
/**
* Loads the specified(XZ) chunk into the specified world.
*/
@Nullable
public Chunk loadChunk(World worldIn, int x, int z) throws IOException
{
Object[] data = this.loadChunk__Async(worldIn, x, z);
if (data != null)
{
Chunk chunk = (Chunk) data[0];
NBTTagCompound nbttagcompound = (NBTTagCompound) data[1];
this.loadEntities(worldIn, nbttagcompound.getCompoundTag("Level"), chunk);
return chunk;
}
return null;
}
@Nullable
public Object[] loadChunk__Async(World worldIn, int x, int z) throws IOException
{
ChunkPos chunkpos = new ChunkPos(x, z);
NBTTagCompound nbttagcompound = this.chunksToSave.get(chunkpos);
if (nbttagcompound == null)
{
DataInputStream datainputstream = RegionFileCache.getChunkInputStream(this.chunkSaveLocation, x, z);
if (datainputstream == null)
{
return null;
}
nbttagcompound = this.fixer.process(FixTypes.CHUNK, CompressedStreamTools.read(datainputstream));
}
return this.checkedReadChunkFromNBT__Async(worldIn, x, z, nbttagcompound);
}
public boolean isChunkGeneratedAt(int x, int z)
{
ChunkPos chunkpos = new ChunkPos(x, z);
NBTTagCompound nbttagcompound = this.chunksToSave.get(chunkpos);
return nbttagcompound != null ? true : RegionFileCache.chunkExists(this.chunkSaveLocation, x, z);
}
/**
* Wraps readChunkFromNBT. Checks the coordinates and several NBT tags.
*/
@Nullable
protected Chunk checkedReadChunkFromNBT(World worldIn, int x, int z, NBTTagCompound compound)
{
Object[] data = this.checkedReadChunkFromNBT__Async(worldIn, x, z, compound);
return data != null ? (Chunk)data[0] : null;
}
@Nullable
protected Object[] checkedReadChunkFromNBT__Async(World worldIn, int x, int z, NBTTagCompound compound)
{
if (!compound.hasKey("Level", 10))
{
LOGGER.error("Chunk file at {},{} is missing level data, skipping", Integer.valueOf(x), Integer.valueOf(z));
return null;
}
else
{
NBTTagCompound nbttagcompound = compound.getCompoundTag("Level");
if (!nbttagcompound.hasKey("Sections", 9))
{
LOGGER.error("Chunk file at {},{} is missing block data, skipping", Integer.valueOf(x), Integer.valueOf(z));
return null;
}
else
{
Chunk chunk = this.readChunkFromNBT(worldIn, nbttagcompound);
if (!chunk.isAtLocation(x, z))
{
LOGGER.error("Chunk file at {},{} is in the wrong location; relocating. (Expected {}, {}, got {}, {})", Integer.valueOf(x), Integer.valueOf(z), Integer.valueOf(x), Integer.valueOf(z), Integer.valueOf(chunk.x), Integer.valueOf(chunk.z));
nbttagcompound.setInteger("xPos", x);
nbttagcompound.setInteger("zPos", z);
// Have to move tile entities since we don't load them at this stage
NBTTagList _tileEntities = nbttagcompound.getTagList("TileEntities", 10);
if (_tileEntities != null)
{
for (int te = 0; te < _tileEntities.tagCount(); te++)
{
NBTTagCompound _nbt = (NBTTagCompound) _tileEntities.getCompoundTagAt(te);
_nbt.setInteger("x", x * 16 + (_nbt.getInteger("x") - chunk.x * 16));
_nbt.setInteger("z", z * 16 + (_nbt.getInteger("z") - chunk.z * 16));
}
}
chunk = this.readChunkFromNBT(worldIn, nbttagcompound);
}
Object[] data = new Object[2];
data[0] = chunk;
data[1] = compound;
// event is fired in ChunkIOProvider.callStage2 since it must be fired after TE's load.
// MinecraftForge.EVENT_BUS.post(new ChunkDataEvent.Load(chunk, par4NBTTagCompound));
return data;
}
}
}
public void saveChunk(World worldIn, Chunk chunkIn) throws MinecraftException, IOException
{
worldIn.checkSessionLock();
try
{
NBTTagCompound nbttagcompound = new NBTTagCompound();
NBTTagCompound nbttagcompound1 = new NBTTagCompound();
nbttagcompound.setTag("Level", nbttagcompound1);
nbttagcompound.setInteger("DataVersion", 1343);
net.minecraftforge.fml.common.FMLCommonHandler.instance().getDataFixer().writeVersionData(nbttagcompound);
this.writeChunkToNBT(chunkIn, worldIn, nbttagcompound1);
net.minecraftforge.common.ForgeChunkManager.storeChunkNBT(chunkIn, nbttagcompound1);
net.minecraftforge.common.MinecraftForge.EVENT_BUS.post(new net.minecraftforge.event.world.ChunkDataEvent.Save(chunkIn, nbttagcompound));
this.addChunkToPending(chunkIn.getPos(), nbttagcompound);
}
catch (Exception exception)
{
LOGGER.error("Failed to save chunk", (Throwable)exception);
}
}
protected void addChunkToPending(ChunkPos pos, NBTTagCompound compound)
{
if (!this.chunksBeingSaved.contains(pos))
{
this.chunksToSave.put(pos, compound);
}
ThreadedFileIOBase.getThreadedIOInstance().queueIO(this);
}
/**
* Writes one queued IO action.
*
* @return true if there are more IO actions to perform afterwards, or false if there are none (and this instance of
* IThreadedFileIO should be removed from the queued list)
*/
public boolean writeNextIO()
{
if (this.chunksToSave.isEmpty())
{
if (this.flushing)
{
LOGGER.info("ThreadedAnvilChunkStorage ({}): All chunks are saved", (Object)this.chunkSaveLocation.getName());
}
return false;
}
else
{
ChunkPos chunkpos = this.chunksToSave.keySet().iterator().next();
boolean lvt_3_1_;
try
{
this.chunksBeingSaved.add(chunkpos);
NBTTagCompound nbttagcompound = this.chunksToSave.remove(chunkpos);
if (nbttagcompound != null)
{
try
{
this.writeChunkData(chunkpos, nbttagcompound);
}
catch (Exception exception)
{
LOGGER.error("Failed to save chunk", (Throwable)exception);
}
}
lvt_3_1_ = true;
}
finally
{
this.chunksBeingSaved.remove(chunkpos);
}
return lvt_3_1_;
}
}
private void writeChunkData(ChunkPos pos, NBTTagCompound compound) throws IOException
{
DataOutputStream dataoutputstream = RegionFileCache.getChunkOutputStream(this.chunkSaveLocation, pos.x, pos.z);
CompressedStreamTools.write(compound, dataoutputstream);
dataoutputstream.close();
}
/**
* Save extra data associated with this Chunk not normally saved during autosave, only during chunk unload.
* Currently unused.
*/
public void saveExtraChunkData(World worldIn, Chunk chunkIn) throws IOException
{
}
/**
* Called every World.tick()
*/
public void chunkTick()
{
}
/**
* Flushes all pending chunks fully back to disk
*/
public void flush()
{
try
{
this.flushing = true;
while (this.writeNextIO());
}
finally
{
this.flushing = false;
}
}
public static void registerFixes(DataFixer fixer)
{
fixer.registerWalker(FixTypes.CHUNK, new IDataWalker()
{
public NBTTagCompound process(IDataFixer fixer, NBTTagCompound compound, int versionIn)
{
if (compound.hasKey("Level", 10))
{
NBTTagCompound nbttagcompound = compound.getCompoundTag("Level");
if (nbttagcompound.hasKey("Entities", 9))
{
NBTTagList nbttaglist = nbttagcompound.getTagList("Entities", 10);
for (int i = 0; i < nbttaglist.tagCount(); ++i)
{
nbttaglist.set(i, fixer.process(FixTypes.ENTITY, (NBTTagCompound)nbttaglist.get(i), versionIn));
}
}
if (nbttagcompound.hasKey("TileEntities", 9))
{
NBTTagList nbttaglist1 = nbttagcompound.getTagList("TileEntities", 10);
for (int j = 0; j < nbttaglist1.tagCount(); ++j)
{
nbttaglist1.set(j, fixer.process(FixTypes.BLOCK_ENTITY, (NBTTagCompound)nbttaglist1.get(j), versionIn));
}
}
}
return compound;
}
});
}
/**
* Writes the Chunk passed as an argument to the NBTTagCompound also passed, using the World argument to retrieve
* the Chunk's last update time.
*/
private void writeChunkToNBT(Chunk chunkIn, World worldIn, NBTTagCompound compound)
{
compound.setInteger("xPos", chunkIn.x);
compound.setInteger("zPos", chunkIn.z);
compound.setLong("LastUpdate", worldIn.getTotalWorldTime());
compound.setIntArray("HeightMap", chunkIn.getHeightMap());
compound.setBoolean("TerrainPopulated", chunkIn.isTerrainPopulated());
compound.setBoolean("LightPopulated", chunkIn.isLightPopulated());
compound.setLong("InhabitedTime", chunkIn.getInhabitedTime());
ExtendedBlockStorage[] aextendedblockstorage = chunkIn.getBlockStorageArray();
NBTTagList nbttaglist = new NBTTagList();
boolean flag = worldIn.provider.hasSkyLight();
for (ExtendedBlockStorage extendedblockstorage : aextendedblockstorage)
{
if (extendedblockstorage != Chunk.NULL_BLOCK_STORAGE)
{
NBTTagCompound nbttagcompound = new NBTTagCompound();
nbttagcompound.setByte("Y", (byte)(extendedblockstorage.getYLocation() >> 4 & 255));
byte[] abyte = new byte[4096];
NibbleArray nibblearray = new NibbleArray();
NibbleArray nibblearray1 = extendedblockstorage.getData().getDataForNBT(abyte, nibblearray);
nbttagcompound.setByteArray("Blocks", abyte);
nbttagcompound.setByteArray("Data", nibblearray.getData());
if (nibblearray1 != null)
{
nbttagcompound.setByteArray("Add", nibblearray1.getData());
}
nbttagcompound.setByteArray("BlockLight", extendedblockstorage.getBlockLight().getData());
if (flag)
{
nbttagcompound.setByteArray("SkyLight", extendedblockstorage.getSkyLight().getData());
}
else
{
nbttagcompound.setByteArray("SkyLight", new byte[extendedblockstorage.getBlockLight().getData().length]);
}
nbttaglist.appendTag(nbttagcompound);
}
}
compound.setTag("Sections", nbttaglist);
compound.setByteArray("Biomes", chunkIn.getBiomeArray());
chunkIn.setHasEntities(false);
NBTTagList nbttaglist1 = new NBTTagList();
for (int i = 0; i < chunkIn.getEntityLists().length; ++i)
{
for (Entity entity : chunkIn.getEntityLists()[i])
{
NBTTagCompound nbttagcompound2 = new NBTTagCompound();
try
{
if (entity.writeToNBTOptional(nbttagcompound2))
{
chunkIn.setHasEntities(true);
nbttaglist1.appendTag(nbttagcompound2);
}
}
catch (Exception e)
{
net.minecraftforge.fml.common.FMLLog.log.error("An Entity type {} has thrown an exception trying to write state. It will not persist. Report this to the mod author",
entity.getClass().getName(), e);
}
}
}
compound.setTag("Entities", nbttaglist1);
NBTTagList nbttaglist2 = new NBTTagList();
for (TileEntity tileentity : chunkIn.getTileEntityMap().values())
{
try
{
NBTTagCompound nbttagcompound3 = tileentity.writeToNBT(new NBTTagCompound());
nbttaglist2.appendTag(nbttagcompound3);
}
catch (Exception e)
{
net.minecraftforge.fml.common.FMLLog.log.error("A TileEntity type {} has throw an exception trying to write state. It will not persist. Report this to the mod author",
tileentity.getClass().getName(), e);
}
}
compound.setTag("TileEntities", nbttaglist2);
List<NextTickListEntry> list = worldIn.getPendingBlockUpdates(chunkIn, false);
if (list != null)
{
long j = worldIn.getTotalWorldTime();
NBTTagList nbttaglist3 = new NBTTagList();
for (NextTickListEntry nextticklistentry : list)
{
NBTTagCompound nbttagcompound1 = new NBTTagCompound();
ResourceLocation resourcelocation = Block.REGISTRY.getNameForObject(nextticklistentry.getBlock());
nbttagcompound1.setString("i", resourcelocation == null ? "" : resourcelocation.toString());
nbttagcompound1.setInteger("x", nextticklistentry.position.getX());
nbttagcompound1.setInteger("y", nextticklistentry.position.getY());
nbttagcompound1.setInteger("z", nextticklistentry.position.getZ());
nbttagcompound1.setInteger("t", (int)(nextticklistentry.scheduledTime - j));
nbttagcompound1.setInteger("p", nextticklistentry.priority);
nbttaglist3.appendTag(nbttagcompound1);
}
compound.setTag("TileTicks", nbttaglist3);
}
if (chunkIn.getCapabilities() != null)
{
try
{
compound.setTag("ForgeCaps", chunkIn.getCapabilities().serializeNBT());
}
catch (Exception exception)
{
net.minecraftforge.fml.common.FMLLog.log.error("A capability provider has thrown an exception trying to write state. It will not persist. Report this to the mod author", exception);
}
}
}
/**
* Reads the data stored in the passed NBTTagCompound and creates a Chunk with that data in the passed World.
* Returns the created Chunk.
*/
private Chunk readChunkFromNBT(World worldIn, NBTTagCompound compound)
{
int i = compound.getInteger("xPos");
int j = compound.getInteger("zPos");
Chunk chunk = new Chunk(worldIn, i, j);
chunk.setHeightMap(compound.getIntArray("HeightMap"));
chunk.setTerrainPopulated(compound.getBoolean("TerrainPopulated"));
chunk.setLightPopulated(compound.getBoolean("LightPopulated"));
chunk.setInhabitedTime(compound.getLong("InhabitedTime"));
NBTTagList nbttaglist = compound.getTagList("Sections", 10);
int k = 16;
ExtendedBlockStorage[] aextendedblockstorage = new ExtendedBlockStorage[16];
boolean flag = worldIn.provider.hasSkyLight();
for (int l = 0; l < nbttaglist.tagCount(); ++l)
{
NBTTagCompound nbttagcompound = nbttaglist.getCompoundTagAt(l);
int i1 = nbttagcompound.getByte("Y");
ExtendedBlockStorage extendedblockstorage = new ExtendedBlockStorage(i1 << 4, flag);
byte[] abyte = nbttagcompound.getByteArray("Blocks");
NibbleArray nibblearray = new NibbleArray(nbttagcompound.getByteArray("Data"));
NibbleArray nibblearray1 = nbttagcompound.hasKey("Add", 7) ? new NibbleArray(nbttagcompound.getByteArray("Add")) : null;
extendedblockstorage.getData().setDataFromNBT(abyte, nibblearray, nibblearray1);
extendedblockstorage.setBlockLight(new NibbleArray(nbttagcompound.getByteArray("BlockLight")));
if (flag)
{
extendedblockstorage.setSkyLight(new NibbleArray(nbttagcompound.getByteArray("SkyLight")));
}
extendedblockstorage.recalculateRefCounts();
aextendedblockstorage[i1] = extendedblockstorage;
}
chunk.setStorageArrays(aextendedblockstorage);
if (compound.hasKey("Biomes", 7))
{
chunk.setBiomeArray(compound.getByteArray("Biomes"));
}
if (chunk.getCapabilities() != null && compound.hasKey("ForgeCaps")) {
chunk.getCapabilities().deserializeNBT(compound.getCompoundTag("ForgeCaps"));
}
// End this method here and split off entity loading to another method
return chunk;
}
public void loadEntities(World worldIn, NBTTagCompound compound, Chunk chunk)
{
NBTTagList nbttaglist1 = compound.getTagList("Entities", 10);
for (int j1 = 0; j1 < nbttaglist1.tagCount(); ++j1)
{
NBTTagCompound nbttagcompound1 = nbttaglist1.getCompoundTagAt(j1);
readChunkEntity(nbttagcompound1, worldIn, chunk);
chunk.setHasEntities(true);
}
NBTTagList nbttaglist2 = compound.getTagList("TileEntities", 10);
for (int k1 = 0; k1 < nbttaglist2.tagCount(); ++k1)
{
NBTTagCompound nbttagcompound2 = nbttaglist2.getCompoundTagAt(k1);
TileEntity tileentity = TileEntity.create(worldIn, nbttagcompound2);
if (tileentity != null)
{
chunk.addTileEntity(tileentity);
}
}
if (compound.hasKey("TileTicks", 9))
{
NBTTagList nbttaglist3 = compound.getTagList("TileTicks", 10);
for (int l1 = 0; l1 < nbttaglist3.tagCount(); ++l1)
{
NBTTagCompound nbttagcompound3 = nbttaglist3.getCompoundTagAt(l1);
Block block;
if (nbttagcompound3.hasKey("i", 8))
{
block = Block.getBlockFromName(nbttagcompound3.getString("i"));
}
else
{
block = Block.getBlockById(nbttagcompound3.getInteger("i"));
}
worldIn.scheduleBlockUpdate(new BlockPos(nbttagcompound3.getInteger("x"), nbttagcompound3.getInteger("y"), nbttagcompound3.getInteger("z")), block, nbttagcompound3.getInteger("t"), nbttagcompound3.getInteger("p"));
}
}
}
@Nullable
public static Entity readChunkEntity(NBTTagCompound compound, World worldIn, Chunk chunkIn)
{
Entity entity = createEntityFromNBT(compound, worldIn);
if (entity == null)
{
return null;
}
else
{
chunkIn.addEntity(entity);
if (compound.hasKey("Passengers", 9))
{
NBTTagList nbttaglist = compound.getTagList("Passengers", 10);
for (int i = 0; i < nbttaglist.tagCount(); ++i)
{
Entity entity1 = readChunkEntity(nbttaglist.getCompoundTagAt(i), worldIn, chunkIn);
if (entity1 != null)
{
entity1.startRiding(entity, true);
}
}
}
return entity;
}
}
@Nullable
public static Entity readWorldEntityPos(NBTTagCompound compound, World worldIn, double x, double y, double z, boolean attemptSpawn)
{
Entity entity = createEntityFromNBT(compound, worldIn);
if (entity == null)
{
return null;
}
else
{
entity.setLocationAndAngles(x, y, z, entity.rotationYaw, entity.rotationPitch);
if (attemptSpawn && !worldIn.spawnEntity(entity))
{
return null;
}
else
{
if (compound.hasKey("Passengers", 9))
{
NBTTagList nbttaglist = compound.getTagList("Passengers", 10);
for (int i = 0; i < nbttaglist.tagCount(); ++i)
{
Entity entity1 = readWorldEntityPos(nbttaglist.getCompoundTagAt(i), worldIn, x, y, z, attemptSpawn);
if (entity1 != null)
{
entity1.startRiding(entity, true);
}
}
}
return entity;
}
}
}
@Nullable
protected static Entity createEntityFromNBT(NBTTagCompound compound, World worldIn)
{
try
{
return EntityList.createEntityFromNBT(compound, worldIn);
}
catch (RuntimeException var3)
{
return null;
}
}
public static void spawnEntity(Entity entityIn, World worldIn)
{
if (worldIn.spawnEntity(entityIn) && entityIn.isBeingRidden())
{
for (Entity entity : entityIn.getPassengers())
{
spawnEntity(entity, worldIn);
}
}
}
@Nullable
public static Entity readWorldEntity(NBTTagCompound compound, World worldIn, boolean p_186051_2_)
{
Entity entity = createEntityFromNBT(compound, worldIn);
if (entity == null)
{
return null;
}
else if (p_186051_2_ && !worldIn.spawnEntity(entity))
{
return null;
}
else
{
if (compound.hasKey("Passengers", 9))
{
NBTTagList nbttaglist = compound.getTagList("Passengers", 10);
for (int i = 0; i < nbttaglist.tagCount(); ++i)
{
Entity entity1 = readWorldEntity(nbttaglist.getCompoundTagAt(i), worldIn, p_186051_2_);
if (entity1 != null)
{
entity1.startRiding(entity, true);
}
}
}
return entity;
}
}
public int getPendingSaveCount()
{
return this.chunksToSave.size();
}
}

View File

@@ -0,0 +1,298 @@
package net.minecraft.world.chunk.storage;
import com.google.common.collect.Lists;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FilenameFilter;
import java.io.IOException;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import net.minecraft.client.AnvilConverterException;
import net.minecraft.init.Biomes;
import net.minecraft.nbt.CompressedStreamTools;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.util.IProgressUpdate;
import net.minecraft.util.datafix.DataFixer;
import net.minecraft.util.text.translation.I18n;
import net.minecraft.world.WorldType;
import net.minecraft.world.biome.BiomeProvider;
import net.minecraft.world.biome.BiomeProviderSingle;
import net.minecraft.world.storage.ISaveHandler;
import net.minecraft.world.storage.SaveFormatOld;
import net.minecraft.world.storage.WorldInfo;
import net.minecraft.world.storage.WorldSummary;
import net.minecraftforge.fml.relauncher.Side;
import net.minecraftforge.fml.relauncher.SideOnly;
import org.apache.commons.lang3.StringUtils;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
public class AnvilSaveConverter extends SaveFormatOld
{
private static final Logger LOGGER = LogManager.getLogger();
public AnvilSaveConverter(File dir, DataFixer dataFixerIn)
{
super(dir, dataFixerIn);
}
/**
* Returns the name of the save format.
*/
@SideOnly(Side.CLIENT)
public String getName()
{
return "Anvil";
}
@SideOnly(Side.CLIENT)
public List<WorldSummary> getSaveList() throws AnvilConverterException
{
if (this.savesDirectory != null && this.savesDirectory.exists() && this.savesDirectory.isDirectory())
{
List<WorldSummary> list = Lists.<WorldSummary>newArrayList();
File[] afile = this.savesDirectory.listFiles();
for (File file1 : afile)
{
if (file1.isDirectory())
{
String s = file1.getName();
WorldInfo worldinfo = this.getWorldInfo(s);
if (worldinfo != null && (worldinfo.getSaveVersion() == 19132 || worldinfo.getSaveVersion() == 19133))
{
boolean flag = worldinfo.getSaveVersion() != this.getSaveVersion();
String s1 = worldinfo.getWorldName();
if (StringUtils.isEmpty(s1))
{
s1 = s;
}
long i = 0L;
list.add(new WorldSummary(worldinfo, s, s1, 0L, flag));
}
}
}
return list;
}
else
{
throw new AnvilConverterException(I18n.translateToLocal("selectWorld.load_folder_access"));
}
}
protected int getSaveVersion()
{
return 19133;
}
@SideOnly(Side.CLIENT)
public void flushCache()
{
RegionFileCache.clearRegionFileReferences();
}
/**
* Returns back a loader for the specified save directory
*/
public ISaveHandler getSaveLoader(String saveName, boolean storePlayerdata)
{
return new AnvilSaveHandler(this.savesDirectory, saveName, storePlayerdata, this.dataFixer);
}
@SideOnly(Side.CLIENT)
public boolean isConvertible(String saveName)
{
WorldInfo worldinfo = this.getWorldInfo(saveName);
return worldinfo != null && worldinfo.getSaveVersion() == 19132;
}
/**
* gets if the map is old chunk saving (true) or McRegion (false)
*/
public boolean isOldMapFormat(String saveName)
{
WorldInfo worldinfo = this.getWorldInfo(saveName);
return worldinfo != null && worldinfo.getSaveVersion() != this.getSaveVersion();
}
/**
* converts the map to mcRegion
*/
public boolean convertMapFormat(String filename, IProgressUpdate progressCallback)
{
progressCallback.setLoadingProgress(0);
List<File> list = Lists.<File>newArrayList();
List<File> list1 = Lists.<File>newArrayList();
List<File> list2 = Lists.<File>newArrayList();
File file1 = new File(this.savesDirectory, filename);
File file2 = new File(file1, "DIM-1");
File file3 = new File(file1, "DIM1");
LOGGER.info("Scanning folders...");
this.addRegionFilesToCollection(file1, list);
if (file2.exists())
{
this.addRegionFilesToCollection(file2, list1);
}
if (file3.exists())
{
this.addRegionFilesToCollection(file3, list2);
}
int i = list.size() + list1.size() + list2.size();
LOGGER.info("Total conversion count is {}", (int)i);
WorldInfo worldinfo = this.getWorldInfo(filename);
BiomeProvider biomeprovider;
if (worldinfo != null && worldinfo.getTerrainType() == WorldType.FLAT)
{
biomeprovider = new BiomeProviderSingle(Biomes.PLAINS);
}
else
{
biomeprovider = new BiomeProvider(worldinfo);
}
this.convertFile(new File(file1, "region"), list, biomeprovider, 0, i, progressCallback);
this.convertFile(new File(file2, "region"), list1, new BiomeProviderSingle(Biomes.HELL), list.size(), i, progressCallback);
this.convertFile(new File(file3, "region"), list2, new BiomeProviderSingle(Biomes.SKY), list.size() + list1.size(), i, progressCallback);
worldinfo.setSaveVersion(19133);
if (worldinfo.getTerrainType() == WorldType.DEFAULT_1_1)
{
worldinfo.setTerrainType(WorldType.DEFAULT);
}
this.createFile(filename);
ISaveHandler isavehandler = this.getSaveLoader(filename, false);
isavehandler.saveWorldInfo(worldinfo);
return true;
}
/**
* par: filename for the level.dat_mcr backup
*/
private void createFile(String filename)
{
File file1 = new File(this.savesDirectory, filename);
if (!file1.exists())
{
LOGGER.warn("Unable to create level.dat_mcr backup");
}
else
{
File file2 = new File(file1, "level.dat");
if (!file2.exists())
{
LOGGER.warn("Unable to create level.dat_mcr backup");
}
else
{
File file3 = new File(file1, "level.dat_mcr");
if (!file2.renameTo(file3))
{
LOGGER.warn("Unable to create level.dat_mcr backup");
}
}
}
}
private void convertFile(File baseFolder, Iterable<File> regionFiles, BiomeProvider p_75813_3_, int p_75813_4_, int p_75813_5_, IProgressUpdate progress)
{
for (File file1 : regionFiles)
{
this.convertChunks(baseFolder, file1, p_75813_3_, p_75813_4_, p_75813_5_, progress);
++p_75813_4_;
int i = (int)Math.round(100.0D * (double)p_75813_4_ / (double)p_75813_5_);
progress.setLoadingProgress(i);
}
}
/**
* copies a 32x32 chunk set from par2File to par1File, via AnvilConverterData
*/
private void convertChunks(File baseFolder, File p_75811_2_, BiomeProvider biomeSource, int p_75811_4_, int p_75811_5_, IProgressUpdate progressCallback)
{
try
{
String s = p_75811_2_.getName();
RegionFile regionfile = new RegionFile(p_75811_2_);
RegionFile regionfile1 = new RegionFile(new File(baseFolder, s.substring(0, s.length() - ".mcr".length()) + ".mca"));
for (int i = 0; i < 32; ++i)
{
for (int j = 0; j < 32; ++j)
{
if (regionfile.isChunkSaved(i, j) && !regionfile1.isChunkSaved(i, j))
{
DataInputStream datainputstream = regionfile.getChunkDataInputStream(i, j);
if (datainputstream == null)
{
LOGGER.warn("Failed to fetch input stream");
}
else
{
NBTTagCompound nbttagcompound = CompressedStreamTools.read(datainputstream);
datainputstream.close();
NBTTagCompound nbttagcompound1 = nbttagcompound.getCompoundTag("Level");
ChunkLoader.AnvilConverterData chunkloader$anvilconverterdata = ChunkLoader.load(nbttagcompound1);
NBTTagCompound nbttagcompound2 = new NBTTagCompound();
NBTTagCompound nbttagcompound3 = new NBTTagCompound();
nbttagcompound2.setTag("Level", nbttagcompound3);
ChunkLoader.convertToAnvilFormat(chunkloader$anvilconverterdata, nbttagcompound3, biomeSource);
DataOutputStream dataoutputstream = regionfile1.getChunkDataOutputStream(i, j);
CompressedStreamTools.write(nbttagcompound2, dataoutputstream);
dataoutputstream.close();
}
}
}
int k = (int)Math.round(100.0D * (double)(p_75811_4_ * 1024) / (double)(p_75811_5_ * 1024));
int l = (int)Math.round(100.0D * (double)((i + 1) * 32 + p_75811_4_ * 1024) / (double)(p_75811_5_ * 1024));
if (l > k)
{
progressCallback.setLoadingProgress(l);
}
}
regionfile.close();
regionfile1.close();
}
catch (IOException ioexception)
{
ioexception.printStackTrace();
}
}
/**
* filters the files in the par1 directory, and adds them to the par2 collections
*/
private void addRegionFilesToCollection(File worldDir, Collection<File> collection)
{
File file1 = new File(worldDir, "region");
File[] afile = file1.listFiles(new FilenameFilter()
{
public boolean accept(File p_accept_1_, String p_accept_2_)
{
return p_accept_2_.endsWith(".mcr");
}
});
if (afile != null)
{
Collections.addAll(collection, afile);
}
}
}

View File

@@ -0,0 +1,65 @@
package net.minecraft.world.chunk.storage;
import java.io.File;
import javax.annotation.Nullable;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.util.datafix.DataFixer;
import net.minecraft.world.WorldProvider;
import net.minecraft.world.WorldProviderEnd;
import net.minecraft.world.WorldProviderHell;
import net.minecraft.world.storage.SaveHandler;
import net.minecraft.world.storage.ThreadedFileIOBase;
import net.minecraft.world.storage.WorldInfo;
public class AnvilSaveHandler extends SaveHandler
{
public AnvilSaveHandler(File p_i46650_1_, String saveDirectoryName, boolean p_i46650_3_, DataFixer dataFixerIn)
{
super(p_i46650_1_, saveDirectoryName, p_i46650_3_, dataFixerIn);
}
/**
* initializes and returns the chunk loader for the specified world provider
*/
public IChunkLoader getChunkLoader(WorldProvider provider)
{
File file1 = this.getWorldDirectory();
if (provider.getSaveFolder() != null)
{
File file3 = new File(file1, provider.getSaveFolder());
file3.mkdirs();
return new AnvilChunkLoader(file3, this.dataFixer);
}
else
{
return new AnvilChunkLoader(file1, this.dataFixer);
}
}
/**
* Saves the given World Info with the given NBTTagCompound as the Player.
*/
public void saveWorldInfoWithPlayer(WorldInfo worldInformation, @Nullable NBTTagCompound tagCompound)
{
worldInformation.setSaveVersion(19133);
super.saveWorldInfoWithPlayer(worldInformation, tagCompound);
}
/**
* Called to flush all changes to disk, waiting for them to complete.
*/
public void flush()
{
try
{
ThreadedFileIOBase.getThreadedIOInstance().waitForFinish();
}
catch (InterruptedException interruptedexception)
{
interruptedexception.printStackTrace();
}
RegionFileCache.clearRegionFileReferences();
}
}

View File

@@ -0,0 +1,155 @@
package net.minecraft.world.chunk.storage;
import net.minecraft.init.Biomes;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.nbt.NBTTagList;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.biome.Biome;
import net.minecraft.world.biome.BiomeProvider;
import net.minecraft.world.chunk.NibbleArray;
public class ChunkLoader
{
public static ChunkLoader.AnvilConverterData load(NBTTagCompound nbt)
{
int i = nbt.getInteger("xPos");
int j = nbt.getInteger("zPos");
ChunkLoader.AnvilConverterData chunkloader$anvilconverterdata = new ChunkLoader.AnvilConverterData(i, j);
chunkloader$anvilconverterdata.blocks = nbt.getByteArray("Blocks");
chunkloader$anvilconverterdata.data = new NibbleArrayReader(nbt.getByteArray("Data"), 7);
chunkloader$anvilconverterdata.skyLight = new NibbleArrayReader(nbt.getByteArray("SkyLight"), 7);
chunkloader$anvilconverterdata.blockLight = new NibbleArrayReader(nbt.getByteArray("BlockLight"), 7);
chunkloader$anvilconverterdata.heightmap = nbt.getByteArray("HeightMap");
chunkloader$anvilconverterdata.terrainPopulated = nbt.getBoolean("TerrainPopulated");
chunkloader$anvilconverterdata.entities = nbt.getTagList("Entities", 10);
chunkloader$anvilconverterdata.tileEntities = nbt.getTagList("TileEntities", 10);
chunkloader$anvilconverterdata.tileTicks = nbt.getTagList("TileTicks", 10);
try
{
chunkloader$anvilconverterdata.lastUpdated = nbt.getLong("LastUpdate");
}
catch (ClassCastException var5)
{
chunkloader$anvilconverterdata.lastUpdated = (long)nbt.getInteger("LastUpdate");
}
return chunkloader$anvilconverterdata;
}
public static void convertToAnvilFormat(ChunkLoader.AnvilConverterData converterData, NBTTagCompound compound, BiomeProvider provider)
{
compound.setInteger("xPos", converterData.x);
compound.setInteger("zPos", converterData.z);
compound.setLong("LastUpdate", converterData.lastUpdated);
int[] aint = new int[converterData.heightmap.length];
for (int i = 0; i < converterData.heightmap.length; ++i)
{
aint[i] = converterData.heightmap[i];
}
compound.setIntArray("HeightMap", aint);
compound.setBoolean("TerrainPopulated", converterData.terrainPopulated);
NBTTagList nbttaglist = new NBTTagList();
for (int j = 0; j < 8; ++j)
{
boolean flag = true;
for (int k = 0; k < 16 && flag; ++k)
{
for (int l = 0; l < 16 && flag; ++l)
{
for (int i1 = 0; i1 < 16; ++i1)
{
int j1 = k << 11 | i1 << 7 | l + (j << 4);
int k1 = converterData.blocks[j1];
if (k1 != 0)
{
flag = false;
break;
}
}
}
}
if (!flag)
{
byte[] abyte1 = new byte[4096];
NibbleArray nibblearray = new NibbleArray();
NibbleArray nibblearray1 = new NibbleArray();
NibbleArray nibblearray2 = new NibbleArray();
for (int j3 = 0; j3 < 16; ++j3)
{
for (int l1 = 0; l1 < 16; ++l1)
{
for (int i2 = 0; i2 < 16; ++i2)
{
int j2 = j3 << 11 | i2 << 7 | l1 + (j << 4);
int k2 = converterData.blocks[j2];
abyte1[l1 << 8 | i2 << 4 | j3] = (byte)(k2 & 255);
nibblearray.set(j3, l1, i2, converterData.data.get(j3, l1 + (j << 4), i2));
nibblearray1.set(j3, l1, i2, converterData.skyLight.get(j3, l1 + (j << 4), i2));
nibblearray2.set(j3, l1, i2, converterData.blockLight.get(j3, l1 + (j << 4), i2));
}
}
}
NBTTagCompound nbttagcompound = new NBTTagCompound();
nbttagcompound.setByte("Y", (byte)(j & 255));
nbttagcompound.setByteArray("Blocks", abyte1);
nbttagcompound.setByteArray("Data", nibblearray.getData());
nbttagcompound.setByteArray("SkyLight", nibblearray1.getData());
nbttagcompound.setByteArray("BlockLight", nibblearray2.getData());
nbttaglist.appendTag(nbttagcompound);
}
}
compound.setTag("Sections", nbttaglist);
byte[] abyte = new byte[256];
BlockPos.MutableBlockPos blockpos$mutableblockpos = new BlockPos.MutableBlockPos();
for (int l2 = 0; l2 < 16; ++l2)
{
for (int i3 = 0; i3 < 16; ++i3)
{
blockpos$mutableblockpos.setPos(converterData.x << 4 | l2, 0, converterData.z << 4 | i3);
abyte[i3 << 4 | l2] = (byte)(Biome.getIdForBiome(provider.getBiome(blockpos$mutableblockpos, Biomes.DEFAULT)) & 255);
}
}
compound.setByteArray("Biomes", abyte);
compound.setTag("Entities", converterData.entities);
compound.setTag("TileEntities", converterData.tileEntities);
if (converterData.tileTicks != null)
{
compound.setTag("TileTicks", converterData.tileTicks);
}
}
public static class AnvilConverterData
{
public long lastUpdated;
public boolean terrainPopulated;
public byte[] heightmap;
public NibbleArrayReader blockLight;
public NibbleArrayReader skyLight;
public NibbleArrayReader data;
public byte[] blocks;
public NBTTagList entities;
public NBTTagList tileEntities;
public NBTTagList tileTicks;
public final int x;
public final int z;
public AnvilConverterData(int xIn, int zIn)
{
this.x = xIn;
this.z = zIn;
}
}
}

View File

@@ -0,0 +1,199 @@
package net.minecraft.world.chunk.storage;
import net.minecraft.block.Block;
import net.minecraft.block.state.IBlockState;
import net.minecraft.init.Blocks;
import net.minecraft.world.chunk.BlockStateContainer;
import net.minecraft.world.chunk.NibbleArray;
public class ExtendedBlockStorage
{
/** Contains the bottom-most Y block represented by this ExtendedBlockStorage. Typically a multiple of 16. */
private final int yBase;
/** A total count of the number of non-air blocks in this block storage's Chunk. */
private int blockRefCount;
/**
* Contains the number of blocks in this block storage's parent chunk that require random ticking. Used to cull the
* Chunk from random tick updates for performance reasons.
*/
private int tickRefCount;
private final BlockStateContainer data;
/** The NibbleArray containing a block of Block-light data. */
private NibbleArray blockLight;
/**
* The NibbleArray containing skylight data.
*
* Will be null if the provider for the world the chunk containing this block storage does not {@linkplain
* net.minecraft.world.WorldProvider#hasSkylight have skylight}.
*/
private NibbleArray skyLight;
public ExtendedBlockStorage(int y, boolean storeSkylight)
{
this.yBase = y;
this.data = new BlockStateContainer();
this.blockLight = new NibbleArray();
if (storeSkylight)
{
this.skyLight = new NibbleArray();
}
}
public IBlockState get(int x, int y, int z)
{
return this.data.get(x, y, z);
}
public void set(int x, int y, int z, IBlockState state)
{
if (state instanceof net.minecraftforge.common.property.IExtendedBlockState)
state = ((net.minecraftforge.common.property.IExtendedBlockState) state).getClean();
IBlockState iblockstate = this.get(x, y, z);
Block block = iblockstate.getBlock();
Block block1 = state.getBlock();
if (block != Blocks.AIR)
{
--this.blockRefCount;
if (block.getTickRandomly())
{
--this.tickRefCount;
}
}
if (block1 != Blocks.AIR)
{
++this.blockRefCount;
if (block1.getTickRandomly())
{
++this.tickRefCount;
}
}
this.data.set(x, y, z, state);
}
/**
* Returns whether or not this block storage's Chunk is fully empty, based on its internal reference count.
*/
public boolean isEmpty()
{
return this.blockRefCount == 0;
}
/**
* Returns whether or not this block storage's Chunk will require random ticking, used to avoid looping through
* random block ticks when there are no blocks that would randomly tick.
*/
public boolean needsRandomTick()
{
return this.tickRefCount > 0;
}
/**
* Returns the Y location of this ExtendedBlockStorage.
*/
public int getYLocation()
{
return this.yBase;
}
/**
* Sets the saved Sky-light value in the extended block storage structure.
*/
public void setSkyLight(int x, int y, int z, int value)
{
this.skyLight.set(x, y, z, value);
}
/**
* Gets the saved Sky-light value in the extended block storage structure.
*/
public int getSkyLight(int x, int y, int z)
{
return this.skyLight.get(x, y, z);
}
/**
* Sets the saved Block-light value in the extended block storage structure.
*/
public void setBlockLight(int x, int y, int z, int value)
{
this.blockLight.set(x, y, z, value);
}
/**
* Gets the saved Block-light value in the extended block storage structure.
*/
public int getBlockLight(int x, int y, int z)
{
return this.blockLight.get(x, y, z);
}
public void recalculateRefCounts()
{
this.blockRefCount = 0;
this.tickRefCount = 0;
for (int i = 0; i < 16; ++i)
{
for (int j = 0; j < 16; ++j)
{
for (int k = 0; k < 16; ++k)
{
Block block = this.get(i, j, k).getBlock();
if (block != Blocks.AIR)
{
++this.blockRefCount;
if (block.getTickRandomly())
{
++this.tickRefCount;
}
}
}
}
}
}
public BlockStateContainer getData()
{
return this.data;
}
/**
* Returns the NibbleArray instance containing Block-light data.
*/
public NibbleArray getBlockLight()
{
return this.blockLight;
}
/**
* Returns the NibbleArray instance containing Sky-light data.
*/
public NibbleArray getSkyLight()
{
return this.skyLight;
}
/**
* Sets the NibbleArray instance used for Block-light values in this particular storage block.
*/
public void setBlockLight(NibbleArray newBlocklightArray)
{
this.blockLight = newBlocklightArray;
}
/**
* Sets the NibbleArray instance used for Sky-light values in this particular storage block.
*/
public void setSkyLight(NibbleArray newSkylightArray)
{
this.skyLight = newSkylightArray;
}
}

View File

@@ -0,0 +1,36 @@
package net.minecraft.world.chunk.storage;
import java.io.IOException;
import javax.annotation.Nullable;
import net.minecraft.world.MinecraftException;
import net.minecraft.world.World;
import net.minecraft.world.chunk.Chunk;
public interface IChunkLoader
{
/**
* Loads the specified(XZ) chunk into the specified world.
*/
@Nullable
Chunk loadChunk(World worldIn, int x, int z) throws IOException;
void saveChunk(World worldIn, Chunk chunkIn) throws MinecraftException, IOException;
/**
* Save extra data associated with this Chunk not normally saved during autosave, only during chunk unload.
* Currently unused.
*/
void saveExtraChunkData(World worldIn, Chunk chunkIn) throws IOException;
/**
* Called every World.tick()
*/
void chunkTick();
/**
* Flushes all pending chunks fully back to disk
*/
void flush();
boolean isChunkGeneratedAt(int x, int z);
}

View File

@@ -0,0 +1,23 @@
package net.minecraft.world.chunk.storage;
public class NibbleArrayReader
{
public final byte[] data;
private final int depthBits;
private final int depthBitsPlusFour;
public NibbleArrayReader(byte[] dataIn, int depthBitsIn)
{
this.data = dataIn;
this.depthBits = depthBitsIn;
this.depthBitsPlusFour = depthBitsIn + 4;
}
public int get(int x, int y, int z)
{
int i = x << this.depthBitsPlusFour | z << this.depthBits | y;
int j = i >> 1;
int k = i & 1;
return k == 0 ? this.data[j] & 15 : this.data[j] >> 4 & 15;
}
}

View File

@@ -0,0 +1,367 @@
package net.minecraft.world.chunk.storage;
import com.google.common.collect.Lists;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.File;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.util.List;
import java.util.zip.DeflaterOutputStream;
import java.util.zip.GZIPInputStream;
import java.util.zip.InflaterInputStream;
import javax.annotation.Nullable;
import net.minecraft.server.MinecraftServer;
public class RegionFile
{
private static final byte[] EMPTY_SECTOR = new byte[4096];
private final File fileName;
private RandomAccessFile dataFile;
private final int[] offsets = new int[1024];
private final int[] chunkTimestamps = new int[1024];
private List<Boolean> sectorFree;
/** McRegion sizeDelta */
private int sizeDelta;
private long lastModified;
public RegionFile(File fileNameIn)
{
this.fileName = fileNameIn;
this.sizeDelta = 0;
try
{
if (fileNameIn.exists())
{
this.lastModified = fileNameIn.lastModified();
}
this.dataFile = new RandomAccessFile(fileNameIn, "rw");
if (this.dataFile.length() < 4096L)
{
this.dataFile.write(EMPTY_SECTOR);
this.dataFile.write(EMPTY_SECTOR);
this.sizeDelta += 8192;
}
if ((this.dataFile.length() & 4095L) != 0L)
{
for (int i = 0; (long)i < (this.dataFile.length() & 4095L); ++i)
{
this.dataFile.write(0);
}
}
int i1 = (int)this.dataFile.length() / 4096;
this.sectorFree = Lists.<Boolean>newArrayListWithCapacity(i1);
for (int j = 0; j < i1; ++j)
{
this.sectorFree.add(Boolean.valueOf(true));
}
this.sectorFree.set(0, Boolean.valueOf(false));
this.sectorFree.set(1, Boolean.valueOf(false));
this.dataFile.seek(0L);
for (int j1 = 0; j1 < 1024; ++j1)
{
int k = this.dataFile.readInt();
this.offsets[j1] = k;
if (k != 0 && (k >> 8) + (k & 255) <= this.sectorFree.size())
{
for (int l = 0; l < (k & 255); ++l)
{
this.sectorFree.set((k >> 8) + l, Boolean.valueOf(false));
}
}
}
for (int k1 = 0; k1 < 1024; ++k1)
{
int l1 = this.dataFile.readInt();
this.chunkTimestamps[k1] = l1;
}
}
catch (IOException ioexception)
{
ioexception.printStackTrace();
}
}
@Deprecated // TODO: remove (1.13)
public synchronized boolean chunkExists(int x, int z)
{
return isChunkSaved(x, z);
}
@Nullable
/**
* Returns an uncompressed chunk stream from the region file.
*/
public synchronized DataInputStream getChunkDataInputStream(int x, int z)
{
if (this.outOfBounds(x, z))
{
return null;
}
else
{
try
{
int i = this.getOffset(x, z);
if (i == 0)
{
return null;
}
else
{
int j = i >> 8;
int k = i & 255;
if (j + k > this.sectorFree.size())
{
return null;
}
else
{
this.dataFile.seek((long)(j * 4096));
int l = this.dataFile.readInt();
if (l > 4096 * k)
{
return null;
}
else if (l <= 0)
{
return null;
}
else
{
byte b0 = this.dataFile.readByte();
if (b0 == 1)
{
byte[] abyte1 = new byte[l - 1];
this.dataFile.read(abyte1);
return new DataInputStream(new BufferedInputStream(new GZIPInputStream(new ByteArrayInputStream(abyte1))));
}
else if (b0 == 2)
{
byte[] abyte = new byte[l - 1];
this.dataFile.read(abyte);
return new DataInputStream(new BufferedInputStream(new InflaterInputStream(new ByteArrayInputStream(abyte))));
}
else
{
return null;
}
}
}
}
}
catch (IOException var9)
{
return null;
}
}
}
/**
* Returns an output stream used to write chunk data. Data is on disk when the returned stream is closed.
*/
@Nullable
public DataOutputStream getChunkDataOutputStream(int x, int z)
{
return this.outOfBounds(x, z) ? null : new DataOutputStream(new BufferedOutputStream(new DeflaterOutputStream(new RegionFile.ChunkBuffer(x, z))));
}
/**
* Writes the specified chunk to disk.
*/
protected synchronized void write(int x, int z, byte[] data, int length)
{
try
{
int i = this.getOffset(x, z);
int j = i >> 8;
int k = i & 255;
int l = (length + 5) / 4096 + 1;
if (l >= 256)
{
return;
}
if (j != 0 && k == l)
{
this.write(j, data, length);
}
else
{
for (int i1 = 0; i1 < k; ++i1)
{
this.sectorFree.set(j + i1, Boolean.valueOf(true));
}
int l1 = this.sectorFree.indexOf(Boolean.valueOf(true));
int j1 = 0;
if (l1 != -1)
{
for (int k1 = l1; k1 < this.sectorFree.size(); ++k1)
{
if (j1 != 0)
{
if (((Boolean)this.sectorFree.get(k1)).booleanValue())
{
++j1;
}
else
{
j1 = 0;
}
}
else if (((Boolean)this.sectorFree.get(k1)).booleanValue())
{
l1 = k1;
j1 = 1;
}
if (j1 >= l)
{
break;
}
}
}
if (j1 >= l)
{
j = l1;
this.setOffset(x, z, l1 << 8 | l);
for (int j2 = 0; j2 < l; ++j2)
{
this.sectorFree.set(j + j2, Boolean.valueOf(false));
}
this.write(j, data, length);
}
else
{
this.dataFile.seek(this.dataFile.length());
j = this.sectorFree.size();
for (int i2 = 0; i2 < l; ++i2)
{
this.dataFile.write(EMPTY_SECTOR);
this.sectorFree.add(Boolean.valueOf(false));
}
this.sizeDelta += 4096 * l;
this.write(j, data, length);
this.setOffset(x, z, j << 8 | l);
}
}
this.setChunkTimestamp(x, z, (int)(MinecraftServer.getCurrentTimeMillis() / 1000L));
}
catch (IOException ioexception)
{
ioexception.printStackTrace();
}
}
/**
* Writes the chunk data to this RegionFile.
*/
private void write(int sectorNumber, byte[] data, int length) throws IOException
{
this.dataFile.seek((long)(sectorNumber * 4096));
this.dataFile.writeInt(length + 1);
this.dataFile.writeByte(2);
this.dataFile.write(data, 0, length);
}
/**
* Checks if region is out of bounds.
*/
private boolean outOfBounds(int x, int z)
{
return x < 0 || x >= 32 || z < 0 || z >= 32;
}
/**
* Gets a chunk's offset in region file.
*/
private int getOffset(int x, int z)
{
return this.offsets[x + z * 32];
}
/**
* Checks if a chunk has been saved.
*/
public boolean isChunkSaved(int x, int z)
{
return this.getOffset(x, z) != 0;
}
/**
* Sets the chunk's offset in the region file.
*/
private void setOffset(int x, int z, int offset) throws IOException
{
this.offsets[x + z * 32] = offset;
this.dataFile.seek((long)((x + z * 32) * 4));
this.dataFile.writeInt(offset);
}
/**
* Updates the specified chunk's write timestamp.
*/
private void setChunkTimestamp(int x, int z, int timestamp) throws IOException
{
this.chunkTimestamps[x + z * 32] = timestamp;
this.dataFile.seek((long)(4096 + (x + z * 32) * 4));
this.dataFile.writeInt(timestamp);
}
/**
* close this RegionFile and prevent further writes
*/
public void close() throws IOException
{
if (this.dataFile != null)
{
this.dataFile.close();
}
}
class ChunkBuffer extends ByteArrayOutputStream
{
private final int chunkX;
private final int chunkZ;
public ChunkBuffer(int x, int z)
{
super(8096);
this.chunkX = x;
this.chunkZ = z;
}
public void close() throws IOException
{
RegionFile.this.write(this.chunkX, this.chunkZ, this.buf, this.count);
}
}
}

View File

@@ -0,0 +1,116 @@
package net.minecraft.world.chunk.storage;
import com.google.common.collect.Maps;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.File;
import java.io.IOException;
import java.util.Map;
public class RegionFileCache
{
/** A map containing Files as keys and RegionFiles as values */
private static final Map<File, RegionFile> REGIONS_BY_FILE = Maps.<File, RegionFile>newHashMap();
public static synchronized RegionFile createOrLoadRegionFile(File worldDir, int chunkX, int chunkZ)
{
File file1 = new File(worldDir, "region");
File file2 = new File(file1, "r." + (chunkX >> 5) + "." + (chunkZ >> 5) + ".mca");
RegionFile regionfile = REGIONS_BY_FILE.get(file2);
if (regionfile != null)
{
return regionfile;
}
else
{
if (!file1.exists())
{
file1.mkdirs();
}
if (REGIONS_BY_FILE.size() >= 256)
{
clearRegionFileReferences();
}
RegionFile regionfile1 = new RegionFile(file2);
REGIONS_BY_FILE.put(file2, regionfile1);
return regionfile1;
}
}
public static synchronized RegionFile getRegionFileIfExists(File worldDir, int chunkX, int chunkZ)
{
File file1 = new File(worldDir, "region");
File file2 = new File(file1, "r." + (chunkX >> 5) + "." + (chunkZ >> 5) + ".mca");
RegionFile regionfile = REGIONS_BY_FILE.get(file2);
if (regionfile != null)
{
return regionfile;
}
else if (file1.exists() && file2.exists())
{
if (REGIONS_BY_FILE.size() >= 256)
{
clearRegionFileReferences();
}
RegionFile regionfile1 = new RegionFile(file2);
REGIONS_BY_FILE.put(file2, regionfile1);
return regionfile1;
}
else
{
return null;
}
}
/**
* clears region file references
*/
public static synchronized void clearRegionFileReferences()
{
for (RegionFile regionfile : REGIONS_BY_FILE.values())
{
try
{
if (regionfile != null)
{
regionfile.close();
}
}
catch (IOException ioexception)
{
ioexception.printStackTrace();
}
}
REGIONS_BY_FILE.clear();
}
/**
* Gets an input stream for the chunk at the specified location.
*/
public static DataInputStream getChunkInputStream(File worldDir, int chunkX, int chunkZ)
{
RegionFile regionfile = createOrLoadRegionFile(worldDir, chunkX, chunkZ);
return regionfile.getChunkDataInputStream(chunkX & 31, chunkZ & 31);
}
/**
* Gets an output stream for the specified chunk.
*/
public static DataOutputStream getChunkOutputStream(File worldDir, int chunkX, int chunkZ)
{
RegionFile regionfile = createOrLoadRegionFile(worldDir, chunkX, chunkZ);
return regionfile.getChunkDataOutputStream(chunkX & 31, chunkZ & 31);
}
public static boolean chunkExists(File worldDir, int chunkX, int chunkZ)
{
RegionFile regionfile = getRegionFileIfExists(worldDir, chunkX, chunkZ);
return regionfile != null ? regionfile.isChunkSaved(chunkX & 31, chunkZ & 31) : false;
}
}

View File

@@ -0,0 +1,7 @@
// Auto generated package-info by MCP
@ParametersAreNonnullByDefault
@MethodsReturnNonnullByDefault
package net.minecraft.world.chunk.storage;
import mcp.MethodsReturnNonnullByDefault;
import javax.annotation.ParametersAreNonnullByDefault;

View File

@@ -0,0 +1,597 @@
package net.minecraft.world.end;
import com.google.common.base.Predicate;
import com.google.common.base.Predicates;
import com.google.common.collect.ContiguousSet;
import com.google.common.collect.DiscreteDomain;
import com.google.common.collect.Lists;
import com.google.common.collect.Range;
import com.google.common.collect.Sets;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import java.util.Random;
import java.util.Set;
import java.util.UUID;
import javax.annotation.Nullable;
import net.minecraft.advancements.CriteriaTriggers;
import net.minecraft.block.state.BlockWorldState;
import net.minecraft.block.state.pattern.BlockMatcher;
import net.minecraft.block.state.pattern.BlockPattern;
import net.minecraft.block.state.pattern.FactoryBlockPattern;
import net.minecraft.entity.Entity;
import net.minecraft.entity.boss.EntityDragon;
import net.minecraft.entity.boss.dragon.phase.PhaseList;
import net.minecraft.entity.item.EntityEnderCrystal;
import net.minecraft.entity.player.EntityPlayerMP;
import net.minecraft.init.Blocks;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.nbt.NBTTagInt;
import net.minecraft.nbt.NBTTagList;
import net.minecraft.nbt.NBTUtil;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.tileentity.TileEntityEndPortal;
import net.minecraft.util.DamageSource;
import net.minecraft.util.EntitySelectors;
import net.minecraft.util.EnumFacing;
import net.minecraft.util.math.AxisAlignedBB;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.text.TextComponentTranslation;
import net.minecraft.world.BossInfo;
import net.minecraft.world.BossInfoServer;
import net.minecraft.world.WorldServer;
import net.minecraft.world.biome.BiomeEndDecorator;
import net.minecraft.world.chunk.Chunk;
import net.minecraft.world.gen.feature.WorldGenEndGateway;
import net.minecraft.world.gen.feature.WorldGenEndPodium;
import net.minecraft.world.gen.feature.WorldGenSpikes;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
public class DragonFightManager
{
private static final Logger LOGGER = LogManager.getLogger();
private static final Predicate<EntityPlayerMP> VALID_PLAYER = Predicates.<EntityPlayerMP>and(EntitySelectors.IS_ALIVE, EntitySelectors.withinRange(0.0D, 128.0D, 0.0D, 192.0D));
private final BossInfoServer bossInfo = (BossInfoServer)(new BossInfoServer(new TextComponentTranslation("entity.EnderDragon.name", new Object[0]), BossInfo.Color.PINK, BossInfo.Overlay.PROGRESS)).setPlayEndBossMusic(true).setCreateFog(true);
private final WorldServer world;
private final List<Integer> gateways = Lists.<Integer>newArrayList();
private final BlockPattern portalPattern;
private int ticksSinceDragonSeen;
private int aliveCrystals;
private int ticksSinceCrystalsScanned;
private int ticksSinceLastPlayerScan;
private boolean dragonKilled;
private boolean previouslyKilled;
private UUID dragonUniqueId;
private boolean scanForLegacyFight = true;
private BlockPos exitPortalLocation;
private DragonSpawnManager respawnState;
private int respawnStateTicks;
private List<EntityEnderCrystal> crystals;
public DragonFightManager(WorldServer worldIn, NBTTagCompound compound)
{
this.world = worldIn;
if (compound.hasKey("DragonKilled", 99))
{
if (compound.hasUniqueId("DragonUUID"))
{
this.dragonUniqueId = compound.getUniqueId("DragonUUID");
}
this.dragonKilled = compound.getBoolean("DragonKilled");
this.previouslyKilled = compound.getBoolean("PreviouslyKilled");
this.scanForLegacyFight = !compound.getBoolean("LegacyScanPerformed"); // Forge: fix MC-105080
if (compound.getBoolean("IsRespawning"))
{
this.respawnState = DragonSpawnManager.START;
}
if (compound.hasKey("ExitPortalLocation", 10))
{
this.exitPortalLocation = NBTUtil.getPosFromTag(compound.getCompoundTag("ExitPortalLocation"));
}
}
else
{
this.dragonKilled = true;
this.previouslyKilled = true;
}
if (compound.hasKey("Gateways", 9))
{
NBTTagList nbttaglist = compound.getTagList("Gateways", 3);
for (int i = 0; i < nbttaglist.tagCount(); ++i)
{
this.gateways.add(Integer.valueOf(nbttaglist.getIntAt(i)));
}
}
else
{
this.gateways.addAll(ContiguousSet.create(Range.closedOpen(Integer.valueOf(0), Integer.valueOf(20)), DiscreteDomain.integers()));
Collections.shuffle(this.gateways, new Random(worldIn.getSeed()));
}
this.portalPattern = FactoryBlockPattern.start().aisle(" ", " ", " ", " # ", " ", " ", " ").aisle(" ", " ", " ", " # ", " ", " ", " ").aisle(" ", " ", " ", " # ", " ", " ", " ").aisle(" ### ", " # # ", "# #", "# # #", "# #", " # # ", " ### ").aisle(" ", " ### ", " ##### ", " ##### ", " ##### ", " ### ", " ").where('#', BlockWorldState.hasState(BlockMatcher.forBlock(Blocks.BEDROCK))).build();
}
public NBTTagCompound getCompound()
{
NBTTagCompound nbttagcompound = new NBTTagCompound();
if (this.dragonUniqueId != null)
{
nbttagcompound.setUniqueId("DragonUUID", this.dragonUniqueId);
}
nbttagcompound.setBoolean("DragonKilled", this.dragonKilled);
nbttagcompound.setBoolean("PreviouslyKilled", this.previouslyKilled);
nbttagcompound.setBoolean("LegacyScanPerformed", !this.scanForLegacyFight); // Forge: fix MC-105080
if (this.exitPortalLocation != null)
{
nbttagcompound.setTag("ExitPortalLocation", NBTUtil.createPosTag(this.exitPortalLocation));
}
NBTTagList nbttaglist = new NBTTagList();
Iterator iterator = this.gateways.iterator();
while (iterator.hasNext())
{
int i = ((Integer)iterator.next()).intValue();
nbttaglist.appendTag(new NBTTagInt(i));
}
nbttagcompound.setTag("Gateways", nbttaglist);
return nbttagcompound;
}
public void tick()
{
this.bossInfo.setVisible(!this.dragonKilled);
if (++this.ticksSinceLastPlayerScan >= 20)
{
this.updateplayers();
this.ticksSinceLastPlayerScan = 0;
}
if (!this.bossInfo.getPlayers().isEmpty())
{
if (this.scanForLegacyFight)
{
LOGGER.info("Scanning for legacy world dragon fight...");
this.loadChunks();
this.scanForLegacyFight = false;
boolean flag = this.hasDragonBeenKilled();
if (flag)
{
LOGGER.info("Found that the dragon has been killed in this world already.");
this.previouslyKilled = true;
}
else
{
LOGGER.info("Found that the dragon has not yet been killed in this world.");
this.previouslyKilled = false;
this.generatePortal(false);
}
List<EntityDragon> list = this.world.getEntities(EntityDragon.class, EntitySelectors.IS_ALIVE);
if (list.isEmpty())
{
this.dragonKilled = true;
}
else
{
EntityDragon entitydragon = list.get(0);
this.dragonUniqueId = entitydragon.getUniqueID();
LOGGER.info("Found that there's a dragon still alive ({})", (Object)entitydragon);
this.dragonKilled = false;
if (!flag)
{
LOGGER.info("But we didn't have a portal, let's remove it.");
entitydragon.setDead();
this.dragonUniqueId = null;
}
}
if (!this.previouslyKilled && this.dragonKilled)
{
this.dragonKilled = false;
}
}
if (this.respawnState != null)
{
if (this.crystals == null)
{
this.respawnState = null;
this.respawnDragon();
}
this.respawnState.process(this.world, this, this.crystals, this.respawnStateTicks++, this.exitPortalLocation);
}
if (!this.dragonKilled)
{
if (this.dragonUniqueId == null || ++this.ticksSinceDragonSeen >= 1200)
{
this.loadChunks();
List<EntityDragon> list1 = this.world.getEntities(EntityDragon.class, EntitySelectors.IS_ALIVE);
if (list1.isEmpty())
{
LOGGER.debug("Haven't seen the dragon, respawning it");
this.createNewDragon();
}
else
{
LOGGER.debug("Haven't seen our dragon, but found another one to use.");
this.dragonUniqueId = ((EntityDragon)list1.get(0)).getUniqueID();
}
this.ticksSinceDragonSeen = 0;
}
if (++this.ticksSinceCrystalsScanned >= 100)
{
this.findAliveCrystals();
this.ticksSinceCrystalsScanned = 0;
}
}
}
}
protected void setRespawnState(DragonSpawnManager state)
{
if (this.respawnState == null)
{
throw new IllegalStateException("Dragon respawn isn't in progress, can't skip ahead in the animation.");
}
else
{
this.respawnStateTicks = 0;
if (state == DragonSpawnManager.END)
{
this.respawnState = null;
this.dragonKilled = false;
EntityDragon entitydragon = this.createNewDragon();
for (EntityPlayerMP entityplayermp : this.bossInfo.getPlayers())
{
CriteriaTriggers.SUMMONED_ENTITY.trigger(entityplayermp, entitydragon);
}
}
else
{
this.respawnState = state;
}
}
}
private boolean hasDragonBeenKilled()
{
for (int i = -8; i <= 8; ++i)
{
for (int j = -8; j <= 8; ++j)
{
Chunk chunk = this.world.getChunkFromChunkCoords(i, j);
for (TileEntity tileentity : chunk.getTileEntityMap().values())
{
if (tileentity instanceof TileEntityEndPortal)
{
return true;
}
}
}
}
return false;
}
@Nullable
private BlockPattern.PatternHelper findExitPortal()
{
for (int i = -8; i <= 8; ++i)
{
for (int j = -8; j <= 8; ++j)
{
Chunk chunk = this.world.getChunkFromChunkCoords(i, j);
for (TileEntity tileentity : chunk.getTileEntityMap().values())
{
if (tileentity instanceof TileEntityEndPortal)
{
BlockPattern.PatternHelper blockpattern$patternhelper = this.portalPattern.match(this.world, tileentity.getPos());
if (blockpattern$patternhelper != null)
{
BlockPos blockpos = blockpattern$patternhelper.translateOffset(3, 3, 3).getPos();
if (this.exitPortalLocation == null && blockpos.getX() == 0 && blockpos.getZ() == 0)
{
this.exitPortalLocation = blockpos;
}
return blockpattern$patternhelper;
}
}
}
}
}
int k = this.world.getHeight(WorldGenEndPodium.END_PODIUM_LOCATION).getY();
for (int l = k; l >= 0; --l)
{
BlockPattern.PatternHelper blockpattern$patternhelper1 = this.portalPattern.match(this.world, new BlockPos(WorldGenEndPodium.END_PODIUM_LOCATION.getX(), l, WorldGenEndPodium.END_PODIUM_LOCATION.getZ()));
if (blockpattern$patternhelper1 != null)
{
if (this.exitPortalLocation == null)
{
this.exitPortalLocation = blockpattern$patternhelper1.translateOffset(3, 3, 3).getPos();
}
return blockpattern$patternhelper1;
}
}
return null;
}
private void loadChunks()
{
for (int i = -8; i <= 8; ++i)
{
for (int j = -8; j <= 8; ++j)
{
this.world.getChunkFromChunkCoords(i, j);
}
}
}
private void updateplayers()
{
Set<EntityPlayerMP> set = Sets.<EntityPlayerMP>newHashSet();
for (EntityPlayerMP entityplayermp : this.world.getPlayers(EntityPlayerMP.class, VALID_PLAYER))
{
this.bossInfo.addPlayer(entityplayermp);
set.add(entityplayermp);
}
Set<EntityPlayerMP> set1 = Sets.newHashSet(this.bossInfo.getPlayers());
set1.removeAll(set);
for (EntityPlayerMP entityplayermp1 : set1)
{
this.bossInfo.removePlayer(entityplayermp1);
}
}
private void findAliveCrystals()
{
this.ticksSinceCrystalsScanned = 0;
this.aliveCrystals = 0;
for (WorldGenSpikes.EndSpike worldgenspikes$endspike : BiomeEndDecorator.getSpikesForWorld(this.world))
{
this.aliveCrystals += this.world.getEntitiesWithinAABB(EntityEnderCrystal.class, worldgenspikes$endspike.getTopBoundingBox()).size();
}
LOGGER.debug("Found {} end crystals still alive", (int)this.aliveCrystals);
}
public void processDragonDeath(EntityDragon dragon)
{
if (dragon.getUniqueID().equals(this.dragonUniqueId))
{
this.bossInfo.setPercent(0.0F);
this.bossInfo.setVisible(false);
this.generatePortal(true);
this.spawnNewGateway();
if (!this.previouslyKilled)
{
this.world.setBlockState(this.world.getHeight(WorldGenEndPodium.END_PODIUM_LOCATION), Blocks.DRAGON_EGG.getDefaultState());
}
this.previouslyKilled = true;
this.dragonKilled = true;
}
}
private void spawnNewGateway()
{
if (!this.gateways.isEmpty())
{
int i = ((Integer)this.gateways.remove(this.gateways.size() - 1)).intValue();
int j = (int)(96.0D * Math.cos(2.0D * (-Math.PI + 0.15707963267948966D * (double)i)));
int k = (int)(96.0D * Math.sin(2.0D * (-Math.PI + 0.15707963267948966D * (double)i)));
this.generateGateway(new BlockPos(j, 75, k));
}
}
private void generateGateway(BlockPos pos)
{
this.world.playEvent(3000, pos, 0);
(new WorldGenEndGateway()).generate(this.world, new Random(), pos);
}
private void generatePortal(boolean active)
{
WorldGenEndPodium worldgenendpodium = new WorldGenEndPodium(active);
if (this.exitPortalLocation == null)
{
for (this.exitPortalLocation = this.world.getTopSolidOrLiquidBlock(WorldGenEndPodium.END_PODIUM_LOCATION).down(); this.world.getBlockState(this.exitPortalLocation).getBlock() == Blocks.BEDROCK && this.exitPortalLocation.getY() > this.world.getSeaLevel(); this.exitPortalLocation = this.exitPortalLocation.down())
{
;
}
}
worldgenendpodium.generate(this.world, new Random(), this.exitPortalLocation);
}
private EntityDragon createNewDragon()
{
this.world.getChunkFromBlockCoords(new BlockPos(0, 128, 0));
EntityDragon entitydragon = new EntityDragon(this.world);
entitydragon.getPhaseManager().setPhase(PhaseList.HOLDING_PATTERN);
entitydragon.setLocationAndAngles(0.0D, 128.0D, 0.0D, this.world.rand.nextFloat() * 360.0F, 0.0F);
this.world.spawnEntity(entitydragon);
this.dragonUniqueId = entitydragon.getUniqueID();
return entitydragon;
}
public void dragonUpdate(EntityDragon dragonIn)
{
if (dragonIn.getUniqueID().equals(this.dragonUniqueId))
{
this.bossInfo.setPercent(dragonIn.getHealth() / dragonIn.getMaxHealth());
this.ticksSinceDragonSeen = 0;
if (dragonIn.hasCustomName())
{
this.bossInfo.setName(dragonIn.getDisplayName());
}
}
}
public int getNumAliveCrystals()
{
return this.aliveCrystals;
}
public void onCrystalDestroyed(EntityEnderCrystal crystal, DamageSource dmgSrc)
{
if (this.respawnState != null && this.crystals.contains(crystal))
{
LOGGER.debug("Aborting respawn sequence");
this.respawnState = null;
this.respawnStateTicks = 0;
this.resetSpikeCrystals();
this.generatePortal(true);
}
else
{
this.findAliveCrystals();
Entity entity = this.world.getEntityFromUuid(this.dragonUniqueId);
if (entity instanceof EntityDragon)
{
((EntityDragon)entity).onCrystalDestroyed(crystal, new BlockPos(crystal), dmgSrc);
}
}
}
public boolean hasPreviouslyKilledDragon()
{
return this.previouslyKilled;
}
public void respawnDragon()
{
if (this.dragonKilled && this.respawnState == null)
{
BlockPos blockpos = this.exitPortalLocation;
if (blockpos == null)
{
LOGGER.debug("Tried to respawn, but need to find the portal first.");
BlockPattern.PatternHelper blockpattern$patternhelper = this.findExitPortal();
if (blockpattern$patternhelper == null)
{
LOGGER.debug("Couldn't find a portal, so we made one.");
this.generatePortal(true);
}
else
{
LOGGER.debug("Found the exit portal & temporarily using it.");
}
blockpos = this.exitPortalLocation;
}
List<EntityEnderCrystal> list1 = Lists.<EntityEnderCrystal>newArrayList();
BlockPos blockpos1 = blockpos.up(1);
for (EnumFacing enumfacing : EnumFacing.Plane.HORIZONTAL)
{
List<EntityEnderCrystal> list = this.world.getEntitiesWithinAABB(EntityEnderCrystal.class, new AxisAlignedBB(blockpos1.offset(enumfacing, 2)));
if (list.isEmpty())
{
return;
}
list1.addAll(list);
}
LOGGER.debug("Found all crystals, respawning dragon.");
this.respawnDragon(list1);
}
}
private void respawnDragon(List<EntityEnderCrystal> crystalsIn)
{
if (this.dragonKilled && this.respawnState == null)
{
for (BlockPattern.PatternHelper blockpattern$patternhelper = this.findExitPortal(); blockpattern$patternhelper != null; blockpattern$patternhelper = this.findExitPortal())
{
for (int i = 0; i < this.portalPattern.getPalmLength(); ++i)
{
for (int j = 0; j < this.portalPattern.getThumbLength(); ++j)
{
for (int k = 0; k < this.portalPattern.getFingerLength(); ++k)
{
BlockWorldState blockworldstate = blockpattern$patternhelper.translateOffset(i, j, k);
if (blockworldstate.getBlockState().getBlock() == Blocks.BEDROCK || blockworldstate.getBlockState().getBlock() == Blocks.END_PORTAL)
{
this.world.setBlockState(blockworldstate.getPos(), Blocks.END_STONE.getDefaultState());
}
}
}
}
}
this.respawnState = DragonSpawnManager.START;
this.respawnStateTicks = 0;
this.generatePortal(false);
this.crystals = crystalsIn;
}
}
public void resetSpikeCrystals()
{
for (WorldGenSpikes.EndSpike worldgenspikes$endspike : BiomeEndDecorator.getSpikesForWorld(this.world))
{
for (EntityEnderCrystal entityendercrystal : this.world.getEntitiesWithinAABB(EntityEnderCrystal.class, worldgenspikes$endspike.getTopBoundingBox()))
{
entityendercrystal.setEntityInvulnerable(false);
entityendercrystal.setBeamTarget((BlockPos)null);
}
}
}
public void addPlayer(EntityPlayerMP player)
{
this.bossInfo.addPlayer(player);
}
public void removePlayer(EntityPlayerMP player)
{
this.bossInfo.removePlayer(player);
}
}

View File

@@ -0,0 +1,133 @@
package net.minecraft.world.end;
import java.util.List;
import java.util.Random;
import net.minecraft.entity.Entity;
import net.minecraft.entity.item.EntityEnderCrystal;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.WorldServer;
import net.minecraft.world.biome.BiomeEndDecorator;
import net.minecraft.world.gen.feature.WorldGenSpikes;
public enum DragonSpawnManager
{
START {
public void process(WorldServer worldIn, DragonFightManager manager, List<EntityEnderCrystal> crystals, int ticks, BlockPos pos)
{
BlockPos blockpos = new BlockPos(0, 128, 0);
for (EntityEnderCrystal entityendercrystal : crystals)
{
entityendercrystal.setBeamTarget(blockpos);
}
manager.setRespawnState(PREPARING_TO_SUMMON_PILLARS);
}
},
PREPARING_TO_SUMMON_PILLARS {
public void process(WorldServer worldIn, DragonFightManager manager, List<EntityEnderCrystal> crystals, int ticks, BlockPos pos)
{
if (ticks < 100)
{
if (ticks == 0 || ticks == 50 || ticks == 51 || ticks == 52 || ticks >= 95)
{
worldIn.playEvent(3001, new BlockPos(0, 128, 0), 0);
}
}
else
{
manager.setRespawnState(SUMMONING_PILLARS);
}
}
},
SUMMONING_PILLARS {
public void process(WorldServer worldIn, DragonFightManager manager, List<EntityEnderCrystal> crystals, int ticks, BlockPos pos)
{
int i = 40;
boolean flag = ticks % 40 == 0;
boolean flag1 = ticks % 40 == 39;
if (flag || flag1)
{
WorldGenSpikes.EndSpike[] aworldgenspikes$endspike = BiomeEndDecorator.getSpikesForWorld(worldIn);
int j = ticks / 40;
if (j < aworldgenspikes$endspike.length)
{
WorldGenSpikes.EndSpike worldgenspikes$endspike = aworldgenspikes$endspike[j];
if (flag)
{
for (EntityEnderCrystal entityendercrystal : crystals)
{
entityendercrystal.setBeamTarget(new BlockPos(worldgenspikes$endspike.getCenterX(), worldgenspikes$endspike.getHeight() + 1, worldgenspikes$endspike.getCenterZ()));
}
}
else
{
int k = 10;
for (BlockPos.MutableBlockPos blockpos$mutableblockpos : BlockPos.getAllInBoxMutable(new BlockPos(worldgenspikes$endspike.getCenterX() - 10, worldgenspikes$endspike.getHeight() - 10, worldgenspikes$endspike.getCenterZ() - 10), new BlockPos(worldgenspikes$endspike.getCenterX() + 10, worldgenspikes$endspike.getHeight() + 10, worldgenspikes$endspike.getCenterZ() + 10)))
{
worldIn.setBlockToAir(blockpos$mutableblockpos);
}
worldIn.createExplosion((Entity)null, (double)((float)worldgenspikes$endspike.getCenterX() + 0.5F), (double)worldgenspikes$endspike.getHeight(), (double)((float)worldgenspikes$endspike.getCenterZ() + 0.5F), 5.0F, true);
WorldGenSpikes worldgenspikes = new WorldGenSpikes();
worldgenspikes.setSpike(worldgenspikes$endspike);
worldgenspikes.setCrystalInvulnerable(true);
worldgenspikes.setBeamTarget(new BlockPos(0, 128, 0));
worldgenspikes.generate(worldIn, new Random(), new BlockPos(worldgenspikes$endspike.getCenterX(), 45, worldgenspikes$endspike.getCenterZ()));
}
}
else if (flag)
{
manager.setRespawnState(SUMMONING_DRAGON);
}
}
}
},
SUMMONING_DRAGON {
public void process(WorldServer worldIn, DragonFightManager manager, List<EntityEnderCrystal> crystals, int ticks, BlockPos pos)
{
if (ticks >= 100)
{
manager.setRespawnState(END);
manager.resetSpikeCrystals();
for (EntityEnderCrystal entityendercrystal : crystals)
{
entityendercrystal.setBeamTarget((BlockPos)null);
worldIn.createExplosion(entityendercrystal, entityendercrystal.posX, entityendercrystal.posY, entityendercrystal.posZ, 6.0F, false);
entityendercrystal.setDead();
}
}
else if (ticks >= 80)
{
worldIn.playEvent(3001, new BlockPos(0, 128, 0), 0);
}
else if (ticks == 0)
{
for (EntityEnderCrystal entityendercrystal1 : crystals)
{
entityendercrystal1.setBeamTarget(new BlockPos(0, 128, 0));
}
}
else if (ticks < 5)
{
worldIn.playEvent(3001, new BlockPos(0, 128, 0), 0);
}
}
},
END {
public void process(WorldServer worldIn, DragonFightManager manager, List<EntityEnderCrystal> crystals, int ticks, BlockPos pos)
{
}
};
private DragonSpawnManager()
{
}
public abstract void process(WorldServer worldIn, DragonFightManager manager, List<EntityEnderCrystal> crystals, int ticks, BlockPos pos);
}

View File

@@ -0,0 +1,7 @@
// Auto generated package-info by MCP
@ParametersAreNonnullByDefault
@MethodsReturnNonnullByDefault
package net.minecraft.world.end;
import mcp.MethodsReturnNonnullByDefault;
import javax.annotation.ParametersAreNonnullByDefault;

View File

@@ -0,0 +1,143 @@
package net.minecraft.world.gen;
import com.google.common.collect.Lists;
import java.util.List;
import javax.annotation.Nullable;
import net.minecraft.block.Block;
import net.minecraft.block.state.IBlockState;
import net.minecraft.entity.EnumCreatureType;
import net.minecraft.init.Blocks;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.MathHelper;
import net.minecraft.world.World;
import net.minecraft.world.biome.Biome;
import net.minecraft.world.chunk.Chunk;
import net.minecraft.world.chunk.ChunkPrimer;
public class ChunkGeneratorDebug implements IChunkGenerator
{
/** A list of all valid block states. */
private static final List<IBlockState> ALL_VALID_STATES = Lists.<IBlockState>newArrayList();
private static final int GRID_WIDTH;
private static final int GRID_HEIGHT;
protected static final IBlockState AIR = Blocks.AIR.getDefaultState();
protected static final IBlockState BARRIER = Blocks.BARRIER.getDefaultState();
private final World world;
public ChunkGeneratorDebug(World worldIn)
{
this.world = worldIn;
}
/**
* Generates the chunk at the specified position, from scratch
*/
public Chunk generateChunk(int x, int z)
{
ChunkPrimer chunkprimer = new ChunkPrimer();
for (int i = 0; i < 16; ++i)
{
for (int j = 0; j < 16; ++j)
{
int k = x * 16 + i;
int l = z * 16 + j;
chunkprimer.setBlockState(i, 60, j, BARRIER);
IBlockState iblockstate = getBlockStateFor(k, l);
if (iblockstate != null)
{
chunkprimer.setBlockState(i, 70, j, iblockstate);
}
}
}
Chunk chunk = new Chunk(this.world, chunkprimer, x, z);
chunk.generateSkylightMap();
Biome[] abiome = this.world.getBiomeProvider().getBiomes((Biome[])null, x * 16, z * 16, 16, 16);
byte[] abyte = chunk.getBiomeArray();
for (int i1 = 0; i1 < abyte.length; ++i1)
{
abyte[i1] = (byte)Biome.getIdForBiome(abiome[i1]);
}
chunk.generateSkylightMap();
return chunk;
}
public static IBlockState getBlockStateFor(int p_177461_0_, int p_177461_1_)
{
IBlockState iblockstate = AIR;
if (p_177461_0_ > 0 && p_177461_1_ > 0 && p_177461_0_ % 2 != 0 && p_177461_1_ % 2 != 0)
{
p_177461_0_ = p_177461_0_ / 2;
p_177461_1_ = p_177461_1_ / 2;
if (p_177461_0_ <= GRID_WIDTH && p_177461_1_ <= GRID_HEIGHT)
{
int i = MathHelper.abs(p_177461_0_ * GRID_WIDTH + p_177461_1_);
if (i < ALL_VALID_STATES.size())
{
iblockstate = ALL_VALID_STATES.get(i);
}
}
}
return iblockstate;
}
/**
* Generate initial structures in this chunk, e.g. mineshafts, temples, lakes, and dungeons
*/
public void populate(int x, int z)
{
}
/**
* Called to generate additional structures after initial worldgen, used by ocean monuments
*/
public boolean generateStructures(Chunk chunkIn, int x, int z)
{
return false;
}
public List<Biome.SpawnListEntry> getPossibleCreatures(EnumCreatureType creatureType, BlockPos pos)
{
Biome biome = this.world.getBiome(pos);
return biome.getSpawnableList(creatureType);
}
@Nullable
public BlockPos getNearestStructurePos(World worldIn, String structureName, BlockPos position, boolean findUnexplored)
{
return null;
}
public boolean isInsideStructure(World worldIn, String structureName, BlockPos pos)
{
return false;
}
/**
* Recreates data about structures intersecting given chunk (used for example by getPossibleCreatures), without
* placing any blocks. When called for the first time before any chunk is generated - also initializes the internal
* state needed by getPossibleCreatures.
*/
public void recreateStructures(Chunk chunkIn, int x, int z)
{
}
static
{
for (Block block : Block.REGISTRY)
{
ALL_VALID_STATES.addAll(block.getBlockState().getValidStates());
}
GRID_WIDTH = MathHelper.ceil(MathHelper.sqrt((float)ALL_VALID_STATES.size()));
GRID_HEIGHT = MathHelper.ceil((float)ALL_VALID_STATES.size() / (float)GRID_WIDTH);
}
}

View File

@@ -0,0 +1,469 @@
package net.minecraft.world.gen;
import java.util.List;
import java.util.Random;
import javax.annotation.Nullable;
import net.minecraft.block.BlockChorusFlower;
import net.minecraft.block.BlockFalling;
import net.minecraft.block.material.Material;
import net.minecraft.block.state.IBlockState;
import net.minecraft.entity.EnumCreatureType;
import net.minecraft.init.Blocks;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.tileentity.TileEntityEndGateway;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.ChunkPos;
import net.minecraft.util.math.MathHelper;
import net.minecraft.world.World;
import net.minecraft.world.biome.Biome;
import net.minecraft.world.chunk.Chunk;
import net.minecraft.world.chunk.ChunkPrimer;
import net.minecraft.world.gen.feature.WorldGenEndGateway;
import net.minecraft.world.gen.feature.WorldGenEndIsland;
import net.minecraft.world.gen.structure.MapGenEndCity;
public class ChunkGeneratorEnd implements IChunkGenerator
{
/** RNG. */
private final Random rand;
protected static final IBlockState END_STONE = Blocks.END_STONE.getDefaultState();
protected static final IBlockState AIR = Blocks.AIR.getDefaultState();
private NoiseGeneratorOctaves lperlinNoise1;
private NoiseGeneratorOctaves lperlinNoise2;
private NoiseGeneratorOctaves perlinNoise1;
/** A NoiseGeneratorOctaves used in generating terrain */
public NoiseGeneratorOctaves noiseGen5;
/** A NoiseGeneratorOctaves used in generating terrain */
public NoiseGeneratorOctaves noiseGen6;
/** Reference to the World object. */
private final World world;
/** are map structures going to be generated (e.g. strongholds) */
private final boolean mapFeaturesEnabled;
private final BlockPos spawnPoint;
private MapGenEndCity endCityGen = new MapGenEndCity(this);
private NoiseGeneratorSimplex islandNoise;
private double[] buffer;
/** The biomes that are used to generate the chunk */
private Biome[] biomesForGeneration;
double[] pnr;
double[] ar;
double[] br;
private final WorldGenEndIsland endIslands = new WorldGenEndIsland();
// temporary variables used during event handling
private int chunkX = 0;
private int chunkZ = 0;
public ChunkGeneratorEnd(World p_i47241_1_, boolean p_i47241_2_, long p_i47241_3_, BlockPos p_i47241_5_)
{
this.world = p_i47241_1_;
this.mapFeaturesEnabled = p_i47241_2_;
this.spawnPoint = p_i47241_5_;
this.rand = new Random(p_i47241_3_);
this.lperlinNoise1 = new NoiseGeneratorOctaves(this.rand, 16);
this.lperlinNoise2 = new NoiseGeneratorOctaves(this.rand, 16);
this.perlinNoise1 = new NoiseGeneratorOctaves(this.rand, 8);
this.noiseGen5 = new NoiseGeneratorOctaves(this.rand, 10);
this.noiseGen6 = new NoiseGeneratorOctaves(this.rand, 16);
this.islandNoise = new NoiseGeneratorSimplex(this.rand);
net.minecraftforge.event.terraingen.InitNoiseGensEvent.ContextEnd ctx =
new net.minecraftforge.event.terraingen.InitNoiseGensEvent.ContextEnd(lperlinNoise1, lperlinNoise2, perlinNoise1, noiseGen5, noiseGen6, islandNoise);
ctx = net.minecraftforge.event.terraingen.TerrainGen.getModdedNoiseGenerators(p_i47241_1_, this.rand, ctx);
this.lperlinNoise1 = ctx.getLPerlin1();
this.lperlinNoise2 = ctx.getLPerlin2();
this.perlinNoise1 = ctx.getPerlin();
this.noiseGen5 = ctx.getDepth();
this.noiseGen6 = ctx.getScale();
this.islandNoise = ctx.getIsland();
this.endCityGen = (MapGenEndCity) net.minecraftforge.event.terraingen.TerrainGen.getModdedMapGen(this.endCityGen, net.minecraftforge.event.terraingen.InitMapGenEvent.EventType.END_CITY);
}
/**
* Generates a bare-bones chunk of nothing but stone or ocean blocks, formed, but featureless.
*/
public void setBlocksInChunk(int x, int z, ChunkPrimer primer)
{
int i = 2;
int j = 3;
int k = 33;
int l = 3;
this.buffer = this.getHeights(this.buffer, x * 2, 0, z * 2, 3, 33, 3);
for (int i1 = 0; i1 < 2; ++i1)
{
for (int j1 = 0; j1 < 2; ++j1)
{
for (int k1 = 0; k1 < 32; ++k1)
{
double d0 = 0.25D;
double d1 = this.buffer[((i1 + 0) * 3 + j1 + 0) * 33 + k1 + 0];
double d2 = this.buffer[((i1 + 0) * 3 + j1 + 1) * 33 + k1 + 0];
double d3 = this.buffer[((i1 + 1) * 3 + j1 + 0) * 33 + k1 + 0];
double d4 = this.buffer[((i1 + 1) * 3 + j1 + 1) * 33 + k1 + 0];
double d5 = (this.buffer[((i1 + 0) * 3 + j1 + 0) * 33 + k1 + 1] - d1) * 0.25D;
double d6 = (this.buffer[((i1 + 0) * 3 + j1 + 1) * 33 + k1 + 1] - d2) * 0.25D;
double d7 = (this.buffer[((i1 + 1) * 3 + j1 + 0) * 33 + k1 + 1] - d3) * 0.25D;
double d8 = (this.buffer[((i1 + 1) * 3 + j1 + 1) * 33 + k1 + 1] - d4) * 0.25D;
for (int l1 = 0; l1 < 4; ++l1)
{
double d9 = 0.125D;
double d10 = d1;
double d11 = d2;
double d12 = (d3 - d1) * 0.125D;
double d13 = (d4 - d2) * 0.125D;
for (int i2 = 0; i2 < 8; ++i2)
{
double d14 = 0.125D;
double d15 = d10;
double d16 = (d11 - d10) * 0.125D;
for (int j2 = 0; j2 < 8; ++j2)
{
IBlockState iblockstate = AIR;
if (d15 > 0.0D)
{
iblockstate = END_STONE;
}
int k2 = i2 + i1 * 8;
int l2 = l1 + k1 * 4;
int i3 = j2 + j1 * 8;
primer.setBlockState(k2, l2, i3, iblockstate);
d15 += d16;
}
d10 += d12;
d11 += d13;
}
d1 += d5;
d2 += d6;
d3 += d7;
d4 += d8;
}
}
}
}
}
public void buildSurfaces(ChunkPrimer primer)
{
if (!net.minecraftforge.event.ForgeEventFactory.onReplaceBiomeBlocks(this, this.chunkX, this.chunkZ, primer, this.world)) return;
for (int i = 0; i < 16; ++i)
{
for (int j = 0; j < 16; ++j)
{
int k = 1;
int l = -1;
IBlockState iblockstate = END_STONE;
IBlockState iblockstate1 = END_STONE;
for (int i1 = 127; i1 >= 0; --i1)
{
IBlockState iblockstate2 = primer.getBlockState(i, i1, j);
if (iblockstate2.getMaterial() == Material.AIR)
{
l = -1;
}
else if (iblockstate2.getBlock() == Blocks.STONE)
{
if (l == -1)
{
l = 1;
if (i1 >= 0)
{
primer.setBlockState(i, i1, j, iblockstate);
}
else
{
primer.setBlockState(i, i1, j, iblockstate1);
}
}
else if (l > 0)
{
--l;
primer.setBlockState(i, i1, j, iblockstate1);
}
}
}
}
}
}
/**
* Generates the chunk at the specified position, from scratch
*/
public Chunk generateChunk(int x, int z)
{
this.chunkX = x; this.chunkZ = z;
this.rand.setSeed((long)x * 341873128712L + (long)z * 132897987541L);
ChunkPrimer chunkprimer = new ChunkPrimer();
this.biomesForGeneration = this.world.getBiomeProvider().getBiomes(this.biomesForGeneration, x * 16, z * 16, 16, 16);
this.setBlocksInChunk(x, z, chunkprimer);
this.buildSurfaces(chunkprimer);
if (this.mapFeaturesEnabled)
{
this.endCityGen.generate(this.world, x, z, chunkprimer);
}
Chunk chunk = new Chunk(this.world, chunkprimer, x, z);
byte[] abyte = chunk.getBiomeArray();
for (int i = 0; i < abyte.length; ++i)
{
abyte[i] = (byte)Biome.getIdForBiome(this.biomesForGeneration[i]);
}
chunk.generateSkylightMap();
return chunk;
}
private float getIslandHeightValue(int p_185960_1_, int p_185960_2_, int p_185960_3_, int p_185960_4_)
{
float f = (float)(p_185960_1_ * 2 + p_185960_3_);
float f1 = (float)(p_185960_2_ * 2 + p_185960_4_);
float f2 = 100.0F - MathHelper.sqrt(f * f + f1 * f1) * 8.0F;
if (f2 > 80.0F)
{
f2 = 80.0F;
}
if (f2 < -100.0F)
{
f2 = -100.0F;
}
for (int i = -12; i <= 12; ++i)
{
for (int j = -12; j <= 12; ++j)
{
long k = (long)(p_185960_1_ + i);
long l = (long)(p_185960_2_ + j);
if (k * k + l * l > 4096L && this.islandNoise.getValue((double)k, (double)l) < -0.8999999761581421D)
{
float f3 = (MathHelper.abs((float)k) * 3439.0F + MathHelper.abs((float)l) * 147.0F) % 13.0F + 9.0F;
f = (float)(p_185960_3_ - i * 2);
f1 = (float)(p_185960_4_ - j * 2);
float f4 = 100.0F - MathHelper.sqrt(f * f + f1 * f1) * f3;
if (f4 > 80.0F)
{
f4 = 80.0F;
}
if (f4 < -100.0F)
{
f4 = -100.0F;
}
if (f4 > f2)
{
f2 = f4;
}
}
}
}
return f2;
}
public boolean isIslandChunk(int p_185961_1_, int p_185961_2_)
{
return (long)p_185961_1_ * (long)p_185961_1_ + (long)p_185961_2_ * (long)p_185961_2_ > 4096L && this.getIslandHeightValue(p_185961_1_, p_185961_2_, 1, 1) >= 0.0F;
}
private double[] getHeights(double[] p_185963_1_, int p_185963_2_, int p_185963_3_, int p_185963_4_, int p_185963_5_, int p_185963_6_, int p_185963_7_)
{
net.minecraftforge.event.terraingen.ChunkGeneratorEvent.InitNoiseField event = new net.minecraftforge.event.terraingen.ChunkGeneratorEvent.InitNoiseField(this, p_185963_1_, p_185963_2_, p_185963_3_, p_185963_4_, p_185963_5_, p_185963_6_, p_185963_7_);
net.minecraftforge.common.MinecraftForge.EVENT_BUS.post(event);
if (event.getResult() == net.minecraftforge.fml.common.eventhandler.Event.Result.DENY) return event.getNoisefield();
if (p_185963_1_ == null)
{
p_185963_1_ = new double[p_185963_5_ * p_185963_6_ * p_185963_7_];
}
double d0 = 684.412D;
double d1 = 684.412D;
d0 = d0 * 2.0D;
this.pnr = this.perlinNoise1.generateNoiseOctaves(this.pnr, p_185963_2_, p_185963_3_, p_185963_4_, p_185963_5_, p_185963_6_, p_185963_7_, d0 / 80.0D, 4.277575000000001D, d0 / 80.0D);
this.ar = this.lperlinNoise1.generateNoiseOctaves(this.ar, p_185963_2_, p_185963_3_, p_185963_4_, p_185963_5_, p_185963_6_, p_185963_7_, d0, 684.412D, d0);
this.br = this.lperlinNoise2.generateNoiseOctaves(this.br, p_185963_2_, p_185963_3_, p_185963_4_, p_185963_5_, p_185963_6_, p_185963_7_, d0, 684.412D, d0);
int i = p_185963_2_ / 2;
int j = p_185963_4_ / 2;
int k = 0;
for (int l = 0; l < p_185963_5_; ++l)
{
for (int i1 = 0; i1 < p_185963_7_; ++i1)
{
float f = this.getIslandHeightValue(i, j, l, i1);
for (int j1 = 0; j1 < p_185963_6_; ++j1)
{
double d2 = this.ar[k] / 512.0D;
double d3 = this.br[k] / 512.0D;
double d5 = (this.pnr[k] / 10.0D + 1.0D) / 2.0D;
double d4;
if (d5 < 0.0D)
{
d4 = d2;
}
else if (d5 > 1.0D)
{
d4 = d3;
}
else
{
d4 = d2 + (d3 - d2) * d5;
}
d4 = d4 - 8.0D;
d4 = d4 + (double)f;
int k1 = 2;
if (j1 > p_185963_6_ / 2 - k1)
{
double d6 = (double)((float)(j1 - (p_185963_6_ / 2 - k1)) / 64.0F);
d6 = MathHelper.clamp(d6, 0.0D, 1.0D);
d4 = d4 * (1.0D - d6) + -3000.0D * d6;
}
k1 = 8;
if (j1 < k1)
{
double d7 = (double)((float)(k1 - j1) / ((float)k1 - 1.0F));
d4 = d4 * (1.0D - d7) + -30.0D * d7;
}
p_185963_1_[k] = d4;
++k;
}
}
}
return p_185963_1_;
}
/**
* Generate initial structures in this chunk, e.g. mineshafts, temples, lakes, and dungeons
*/
public void populate(int x, int z)
{
BlockFalling.fallInstantly = true;
net.minecraftforge.event.ForgeEventFactory.onChunkPopulate(true, this, this.world, this.rand, x, z, false);
BlockPos blockpos = new BlockPos(x * 16, 0, z * 16);
if (this.mapFeaturesEnabled)
{
this.endCityGen.generateStructure(this.world, this.rand, new ChunkPos(x, z));
}
this.world.getBiome(blockpos.add(16, 0, 16)).decorate(this.world, this.world.rand, blockpos);
long i = (long)x * (long)x + (long)z * (long)z;
if (i > 4096L)
{
float f = this.getIslandHeightValue(x, z, 1, 1);
if (f < -20.0F && this.rand.nextInt(14) == 0)
{
this.endIslands.generate(this.world, this.rand, blockpos.add(this.rand.nextInt(16) + 8, 55 + this.rand.nextInt(16), this.rand.nextInt(16) + 8));
if (this.rand.nextInt(4) == 0)
{
this.endIslands.generate(this.world, this.rand, blockpos.add(this.rand.nextInt(16) + 8, 55 + this.rand.nextInt(16), this.rand.nextInt(16) + 8));
}
}
if (this.getIslandHeightValue(x, z, 1, 1) > 40.0F)
{
int j = this.rand.nextInt(5);
for (int k = 0; k < j; ++k)
{
int l = this.rand.nextInt(16) + 8;
int i1 = this.rand.nextInt(16) + 8;
int j1 = this.world.getHeight(blockpos.add(l, 0, i1)).getY();
if (j1 > 0)
{
int k1 = j1 - 1;
if (this.world.isAirBlock(blockpos.add(l, k1 + 1, i1)) && this.world.getBlockState(blockpos.add(l, k1, i1)).getBlock() == Blocks.END_STONE)
{
BlockChorusFlower.generatePlant(this.world, blockpos.add(l, k1 + 1, i1), this.rand, 8);
}
}
}
if (this.rand.nextInt(700) == 0)
{
int l1 = this.rand.nextInt(16) + 8;
int i2 = this.rand.nextInt(16) + 8;
int j2 = this.world.getHeight(blockpos.add(l1, 0, i2)).getY();
if (j2 > 0)
{
int k2 = j2 + 3 + this.rand.nextInt(7);
BlockPos blockpos1 = blockpos.add(l1, k2, i2);
(new WorldGenEndGateway()).generate(this.world, this.rand, blockpos1);
TileEntity tileentity = this.world.getTileEntity(blockpos1);
if (tileentity instanceof TileEntityEndGateway)
{
TileEntityEndGateway tileentityendgateway = (TileEntityEndGateway)tileentity;
tileentityendgateway.setExactPosition(this.spawnPoint);
}
}
}
}
}
net.minecraftforge.event.ForgeEventFactory.onChunkPopulate(false, this, this.world, this.rand, x, z, false);
BlockFalling.fallInstantly = false;
}
/**
* Called to generate additional structures after initial worldgen, used by ocean monuments
*/
public boolean generateStructures(Chunk chunkIn, int x, int z)
{
return false;
}
public List<Biome.SpawnListEntry> getPossibleCreatures(EnumCreatureType creatureType, BlockPos pos)
{
return this.world.getBiome(pos).getSpawnableList(creatureType);
}
@Nullable
public BlockPos getNearestStructurePos(World worldIn, String structureName, BlockPos position, boolean findUnexplored)
{
return "EndCity".equals(structureName) && this.endCityGen != null ? this.endCityGen.getNearestStructurePos(worldIn, position, findUnexplored) : null;
}
public boolean isInsideStructure(World worldIn, String structureName, BlockPos pos)
{
return "EndCity".equals(structureName) && this.endCityGen != null ? this.endCityGen.isInsideStructure(pos) : false;
}
/**
* Recreates data about structures intersecting given chunk (used for example by getPossibleCreatures), without
* placing any blocks. When called for the first time before any chunk is generated - also initializes the internal
* state needed by getPossibleCreatures.
*/
public void recreateStructures(Chunk chunkIn, int x, int z)
{
}
}

View File

@@ -0,0 +1,266 @@
package net.minecraft.world.gen;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Random;
import javax.annotation.Nullable;
import net.minecraft.block.state.IBlockState;
import net.minecraft.entity.EnumCreatureType;
import net.minecraft.init.Biomes;
import net.minecraft.init.Blocks;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.ChunkPos;
import net.minecraft.world.World;
import net.minecraft.world.biome.Biome;
import net.minecraft.world.chunk.Chunk;
import net.minecraft.world.chunk.ChunkPrimer;
import net.minecraft.world.gen.feature.WorldGenDungeons;
import net.minecraft.world.gen.feature.WorldGenLakes;
import net.minecraft.world.gen.structure.MapGenMineshaft;
import net.minecraft.world.gen.structure.MapGenScatteredFeature;
import net.minecraft.world.gen.structure.MapGenStronghold;
import net.minecraft.world.gen.structure.MapGenStructure;
import net.minecraft.world.gen.structure.MapGenVillage;
import net.minecraft.world.gen.structure.StructureOceanMonument;
public class ChunkGeneratorFlat implements IChunkGenerator
{
private final World world;
private final Random random;
private final IBlockState[] cachedBlockIDs = new IBlockState[256];
private final FlatGeneratorInfo flatWorldGenInfo;
private final Map<String, MapGenStructure> structureGenerators = new HashMap<String, MapGenStructure>();
private final boolean hasDecoration;
private final boolean hasDungeons;
private WorldGenLakes waterLakeGenerator;
private WorldGenLakes lavaLakeGenerator;
public ChunkGeneratorFlat(World worldIn, long seed, boolean generateStructures, String flatGeneratorSettings)
{
this.world = worldIn;
this.random = new Random(seed);
this.flatWorldGenInfo = FlatGeneratorInfo.createFlatGeneratorFromString(flatGeneratorSettings);
if (generateStructures)
{
Map<String, Map<String, String>> map = this.flatWorldGenInfo.getWorldFeatures();
if (map.containsKey("village"))
{
Map<String, String> map1 = (Map)map.get("village");
if (!map1.containsKey("size"))
{
map1.put("size", "1");
}
this.structureGenerators.put("Village", new MapGenVillage(map1));
}
if (map.containsKey("biome_1"))
{
this.structureGenerators.put("Temple", new MapGenScatteredFeature(map.get("biome_1")));
}
if (map.containsKey("mineshaft"))
{
this.structureGenerators.put("Mineshaft", new MapGenMineshaft(map.get("mineshaft")));
}
if (map.containsKey("stronghold"))
{
this.structureGenerators.put("Stronghold", new MapGenStronghold(map.get("stronghold")));
}
if (map.containsKey("oceanmonument"))
{
this.structureGenerators.put("Monument", new StructureOceanMonument(map.get("oceanmonument")));
}
}
if (this.flatWorldGenInfo.getWorldFeatures().containsKey("lake"))
{
this.waterLakeGenerator = new WorldGenLakes(Blocks.WATER);
}
if (this.flatWorldGenInfo.getWorldFeatures().containsKey("lava_lake"))
{
this.lavaLakeGenerator = new WorldGenLakes(Blocks.LAVA);
}
this.hasDungeons = this.flatWorldGenInfo.getWorldFeatures().containsKey("dungeon");
int j = 0;
int k = 0;
boolean flag = true;
for (FlatLayerInfo flatlayerinfo : this.flatWorldGenInfo.getFlatLayers())
{
for (int i = flatlayerinfo.getMinY(); i < flatlayerinfo.getMinY() + flatlayerinfo.getLayerCount(); ++i)
{
IBlockState iblockstate = flatlayerinfo.getLayerMaterial();
if (iblockstate.getBlock() != Blocks.AIR)
{
flag = false;
this.cachedBlockIDs[i] = iblockstate;
}
}
if (flatlayerinfo.getLayerMaterial().getBlock() == Blocks.AIR)
{
k += flatlayerinfo.getLayerCount();
}
else
{
j += flatlayerinfo.getLayerCount() + k;
k = 0;
}
}
worldIn.setSeaLevel(j);
this.hasDecoration = flag && this.flatWorldGenInfo.getBiome() != Biome.getIdForBiome(Biomes.VOID) ? false : this.flatWorldGenInfo.getWorldFeatures().containsKey("decoration");
}
/**
* Generates the chunk at the specified position, from scratch
*/
public Chunk generateChunk(int x, int z)
{
ChunkPrimer chunkprimer = new ChunkPrimer();
for (int i = 0; i < this.cachedBlockIDs.length; ++i)
{
IBlockState iblockstate = this.cachedBlockIDs[i];
if (iblockstate != null)
{
for (int j = 0; j < 16; ++j)
{
for (int k = 0; k < 16; ++k)
{
chunkprimer.setBlockState(j, i, k, iblockstate);
}
}
}
}
for (MapGenBase mapgenbase : this.structureGenerators.values())
{
mapgenbase.generate(this.world, x, z, chunkprimer);
}
Chunk chunk = new Chunk(this.world, chunkprimer, x, z);
Biome[] abiome = this.world.getBiomeProvider().getBiomes((Biome[])null, x * 16, z * 16, 16, 16);
byte[] abyte = chunk.getBiomeArray();
for (int l = 0; l < abyte.length; ++l)
{
abyte[l] = (byte)Biome.getIdForBiome(abiome[l]);
}
chunk.generateSkylightMap();
return chunk;
}
/**
* Generate initial structures in this chunk, e.g. mineshafts, temples, lakes, and dungeons
*/
public void populate(int x, int z)
{
net.minecraft.block.BlockFalling.fallInstantly = true;
int i = x * 16;
int j = z * 16;
BlockPos blockpos = new BlockPos(i, 0, j);
Biome biome = this.world.getBiome(new BlockPos(i + 16, 0, j + 16));
boolean flag = false;
this.random.setSeed(this.world.getSeed());
long k = this.random.nextLong() / 2L * 2L + 1L;
long l = this.random.nextLong() / 2L * 2L + 1L;
this.random.setSeed((long)x * k + (long)z * l ^ this.world.getSeed());
ChunkPos chunkpos = new ChunkPos(x, z);
net.minecraftforge.event.ForgeEventFactory.onChunkPopulate(true, this, this.world, this.random, x, z, flag);
for (MapGenStructure mapgenstructure : this.structureGenerators.values())
{
boolean flag1 = mapgenstructure.generateStructure(this.world, this.random, chunkpos);
if (mapgenstructure instanceof MapGenVillage)
{
flag |= flag1;
}
}
if (this.waterLakeGenerator != null && !flag && this.random.nextInt(4) == 0)
{
this.waterLakeGenerator.generate(this.world, this.random, blockpos.add(this.random.nextInt(16) + 8, this.random.nextInt(256), this.random.nextInt(16) + 8));
}
if (this.lavaLakeGenerator != null && !flag && this.random.nextInt(8) == 0)
{
BlockPos blockpos1 = blockpos.add(this.random.nextInt(16) + 8, this.random.nextInt(this.random.nextInt(248) + 8), this.random.nextInt(16) + 8);
if (blockpos1.getY() < this.world.getSeaLevel() || this.random.nextInt(10) == 0)
{
this.lavaLakeGenerator.generate(this.world, this.random, blockpos1);
}
}
if (this.hasDungeons)
{
for (int i1 = 0; i1 < 8; ++i1)
{
(new WorldGenDungeons()).generate(this.world, this.random, blockpos.add(this.random.nextInt(16) + 8, this.random.nextInt(256), this.random.nextInt(16) + 8));
}
}
if (this.hasDecoration)
{
biome.decorate(this.world, this.random, blockpos);
}
net.minecraftforge.event.ForgeEventFactory.onChunkPopulate(false, this, this.world, this.random, x, z, flag);
net.minecraft.block.BlockFalling.fallInstantly = false;
}
/**
* Called to generate additional structures after initial worldgen, used by ocean monuments
*/
public boolean generateStructures(Chunk chunkIn, int x, int z)
{
return false;
}
public List<Biome.SpawnListEntry> getPossibleCreatures(EnumCreatureType creatureType, BlockPos pos)
{
Biome biome = this.world.getBiome(pos);
return biome.getSpawnableList(creatureType);
}
@Nullable
public BlockPos getNearestStructurePos(World worldIn, String structureName, BlockPos position, boolean findUnexplored)
{
MapGenStructure mapgenstructure = this.structureGenerators.get(structureName);
return mapgenstructure != null ? mapgenstructure.getNearestStructurePos(worldIn, position, findUnexplored) : null;
}
public boolean isInsideStructure(World worldIn, String structureName, BlockPos pos)
{
MapGenStructure mapgenstructure = this.structureGenerators.get(structureName);
return mapgenstructure != null ? mapgenstructure.isInsideStructure(pos) : false;
}
/**
* Recreates data about structures intersecting given chunk (used for example by getPossibleCreatures), without
* placing any blocks. When called for the first time before any chunk is generated - also initializes the internal
* state needed by getPossibleCreatures.
*/
public void recreateStructures(Chunk chunkIn, int x, int z)
{
for (MapGenStructure mapgenstructure : this.structureGenerators.values())
{
mapgenstructure.generate(this.world, x, z, (ChunkPrimer)null);
}
}
}

View File

@@ -0,0 +1,513 @@
package net.minecraft.world.gen;
import java.util.List;
import java.util.Random;
import javax.annotation.Nullable;
import net.minecraft.block.BlockFalling;
import net.minecraft.block.material.Material;
import net.minecraft.block.state.IBlockState;
import net.minecraft.block.state.pattern.BlockMatcher;
import net.minecraft.entity.EnumCreatureType;
import net.minecraft.init.Blocks;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.ChunkPos;
import net.minecraft.util.math.MathHelper;
import net.minecraft.world.World;
import net.minecraft.world.biome.Biome;
import net.minecraft.world.chunk.Chunk;
import net.minecraft.world.chunk.ChunkPrimer;
import net.minecraft.world.gen.feature.WorldGenBush;
import net.minecraft.world.gen.feature.WorldGenFire;
import net.minecraft.world.gen.feature.WorldGenGlowStone1;
import net.minecraft.world.gen.feature.WorldGenGlowStone2;
import net.minecraft.world.gen.feature.WorldGenHellLava;
import net.minecraft.world.gen.feature.WorldGenMinable;
import net.minecraft.world.gen.feature.WorldGenerator;
import net.minecraft.world.gen.structure.MapGenNetherBridge;
public class ChunkGeneratorHell implements IChunkGenerator
{
protected static final IBlockState AIR = Blocks.AIR.getDefaultState();
protected static final IBlockState NETHERRACK = Blocks.NETHERRACK.getDefaultState();
protected static final IBlockState BEDROCK = Blocks.BEDROCK.getDefaultState();
protected static final IBlockState LAVA = Blocks.LAVA.getDefaultState();
protected static final IBlockState GRAVEL = Blocks.GRAVEL.getDefaultState();
protected static final IBlockState SOUL_SAND = Blocks.SOUL_SAND.getDefaultState();
private final World world;
private final boolean generateStructures;
private final Random rand;
/** Holds the noise used to determine whether slowsand can be generated at a location */
private double[] slowsandNoise = new double[256];
private double[] gravelNoise = new double[256];
private double[] depthBuffer = new double[256];
private double[] buffer;
private NoiseGeneratorOctaves lperlinNoise1;
private NoiseGeneratorOctaves lperlinNoise2;
private NoiseGeneratorOctaves perlinNoise1;
/** Determines whether slowsand or gravel can be generated at a location */
private NoiseGeneratorOctaves slowsandGravelNoiseGen;
/** Determines whether something other than nettherack can be generated at a location */
private NoiseGeneratorOctaves netherrackExculsivityNoiseGen;
public NoiseGeneratorOctaves scaleNoise;
public NoiseGeneratorOctaves depthNoise;
private final WorldGenFire fireFeature = new WorldGenFire();
private final WorldGenGlowStone1 lightGemGen = new WorldGenGlowStone1();
private final WorldGenGlowStone2 hellPortalGen = new WorldGenGlowStone2();
private final WorldGenerator quartzGen = new WorldGenMinable(Blocks.QUARTZ_ORE.getDefaultState(), 14, BlockMatcher.forBlock(Blocks.NETHERRACK));
private final WorldGenerator magmaGen = new WorldGenMinable(Blocks.MAGMA.getDefaultState(), 33, BlockMatcher.forBlock(Blocks.NETHERRACK));
private final WorldGenHellLava lavaTrapGen = new WorldGenHellLava(Blocks.FLOWING_LAVA, true);
private final WorldGenHellLava hellSpringGen = new WorldGenHellLava(Blocks.FLOWING_LAVA, false);
private final WorldGenBush brownMushroomFeature = new WorldGenBush(Blocks.BROWN_MUSHROOM);
private final WorldGenBush redMushroomFeature = new WorldGenBush(Blocks.RED_MUSHROOM);
private MapGenNetherBridge genNetherBridge = new MapGenNetherBridge();
private MapGenBase genNetherCaves = new MapGenCavesHell();
double[] pnr;
double[] ar;
double[] br;
double[] noiseData4;
double[] dr;
public ChunkGeneratorHell(World worldIn, boolean p_i45637_2_, long seed)
{
this.world = worldIn;
this.generateStructures = p_i45637_2_;
this.rand = new Random(seed);
this.lperlinNoise1 = new NoiseGeneratorOctaves(this.rand, 16);
this.lperlinNoise2 = new NoiseGeneratorOctaves(this.rand, 16);
this.perlinNoise1 = new NoiseGeneratorOctaves(this.rand, 8);
this.slowsandGravelNoiseGen = new NoiseGeneratorOctaves(this.rand, 4);
this.netherrackExculsivityNoiseGen = new NoiseGeneratorOctaves(this.rand, 4);
this.scaleNoise = new NoiseGeneratorOctaves(this.rand, 10);
this.depthNoise = new NoiseGeneratorOctaves(this.rand, 16);
worldIn.setSeaLevel(63);
net.minecraftforge.event.terraingen.InitNoiseGensEvent.ContextHell ctx =
new net.minecraftforge.event.terraingen.InitNoiseGensEvent.ContextHell(lperlinNoise1, lperlinNoise2, perlinNoise1, slowsandGravelNoiseGen, netherrackExculsivityNoiseGen, scaleNoise, depthNoise);
ctx = net.minecraftforge.event.terraingen.TerrainGen.getModdedNoiseGenerators(worldIn, this.rand, ctx);
this.lperlinNoise1 = ctx.getLPerlin1();
this.lperlinNoise2 = ctx.getLPerlin2();
this.perlinNoise1 = ctx.getPerlin();
this.slowsandGravelNoiseGen = ctx.getPerlin2();
this.netherrackExculsivityNoiseGen = ctx.getPerlin3();
this.scaleNoise = ctx.getScale();
this.depthNoise = ctx.getDepth();
this.genNetherBridge = (MapGenNetherBridge)net.minecraftforge.event.terraingen.TerrainGen.getModdedMapGen(genNetherBridge, net.minecraftforge.event.terraingen.InitMapGenEvent.EventType.NETHER_BRIDGE);
this.genNetherCaves = net.minecraftforge.event.terraingen.TerrainGen.getModdedMapGen(genNetherCaves, net.minecraftforge.event.terraingen.InitMapGenEvent.EventType.NETHER_CAVE);
}
public void prepareHeights(int p_185936_1_, int p_185936_2_, ChunkPrimer primer)
{
int i = 4;
int j = this.world.getSeaLevel() / 2 + 1;
int k = 5;
int l = 17;
int i1 = 5;
this.buffer = this.getHeights(this.buffer, p_185936_1_ * 4, 0, p_185936_2_ * 4, 5, 17, 5);
for (int j1 = 0; j1 < 4; ++j1)
{
for (int k1 = 0; k1 < 4; ++k1)
{
for (int l1 = 0; l1 < 16; ++l1)
{
double d0 = 0.125D;
double d1 = this.buffer[((j1 + 0) * 5 + k1 + 0) * 17 + l1 + 0];
double d2 = this.buffer[((j1 + 0) * 5 + k1 + 1) * 17 + l1 + 0];
double d3 = this.buffer[((j1 + 1) * 5 + k1 + 0) * 17 + l1 + 0];
double d4 = this.buffer[((j1 + 1) * 5 + k1 + 1) * 17 + l1 + 0];
double d5 = (this.buffer[((j1 + 0) * 5 + k1 + 0) * 17 + l1 + 1] - d1) * 0.125D;
double d6 = (this.buffer[((j1 + 0) * 5 + k1 + 1) * 17 + l1 + 1] - d2) * 0.125D;
double d7 = (this.buffer[((j1 + 1) * 5 + k1 + 0) * 17 + l1 + 1] - d3) * 0.125D;
double d8 = (this.buffer[((j1 + 1) * 5 + k1 + 1) * 17 + l1 + 1] - d4) * 0.125D;
for (int i2 = 0; i2 < 8; ++i2)
{
double d9 = 0.25D;
double d10 = d1;
double d11 = d2;
double d12 = (d3 - d1) * 0.25D;
double d13 = (d4 - d2) * 0.25D;
for (int j2 = 0; j2 < 4; ++j2)
{
double d14 = 0.25D;
double d15 = d10;
double d16 = (d11 - d10) * 0.25D;
for (int k2 = 0; k2 < 4; ++k2)
{
IBlockState iblockstate = null;
if (l1 * 8 + i2 < j)
{
iblockstate = LAVA;
}
if (d15 > 0.0D)
{
iblockstate = NETHERRACK;
}
int l2 = j2 + j1 * 4;
int i3 = i2 + l1 * 8;
int j3 = k2 + k1 * 4;
primer.setBlockState(l2, i3, j3, iblockstate);
d15 += d16;
}
d10 += d12;
d11 += d13;
}
d1 += d5;
d2 += d6;
d3 += d7;
d4 += d8;
}
}
}
}
}
public void buildSurfaces(int p_185937_1_, int p_185937_2_, ChunkPrimer primer)
{
if (!net.minecraftforge.event.ForgeEventFactory.onReplaceBiomeBlocks(this, p_185937_1_, p_185937_2_, primer, this.world)) return;
int i = this.world.getSeaLevel() + 1;
double d0 = 0.03125D;
this.slowsandNoise = this.slowsandGravelNoiseGen.generateNoiseOctaves(this.slowsandNoise, p_185937_1_ * 16, p_185937_2_ * 16, 0, 16, 16, 1, 0.03125D, 0.03125D, 1.0D);
this.gravelNoise = this.slowsandGravelNoiseGen.generateNoiseOctaves(this.gravelNoise, p_185937_1_ * 16, 109, p_185937_2_ * 16, 16, 1, 16, 0.03125D, 1.0D, 0.03125D);
this.depthBuffer = this.netherrackExculsivityNoiseGen.generateNoiseOctaves(this.depthBuffer, p_185937_1_ * 16, p_185937_2_ * 16, 0, 16, 16, 1, 0.0625D, 0.0625D, 0.0625D);
for (int j = 0; j < 16; ++j)
{
for (int k = 0; k < 16; ++k)
{
boolean flag = this.slowsandNoise[j + k * 16] + this.rand.nextDouble() * 0.2D > 0.0D;
boolean flag1 = this.gravelNoise[j + k * 16] + this.rand.nextDouble() * 0.2D > 0.0D;
int l = (int)(this.depthBuffer[j + k * 16] / 3.0D + 3.0D + this.rand.nextDouble() * 0.25D);
int i1 = -1;
IBlockState iblockstate = NETHERRACK;
IBlockState iblockstate1 = NETHERRACK;
for (int j1 = 127; j1 >= 0; --j1)
{
if (j1 < 127 - this.rand.nextInt(5) && j1 > this.rand.nextInt(5))
{
IBlockState iblockstate2 = primer.getBlockState(k, j1, j);
if (iblockstate2.getBlock() != null && iblockstate2.getMaterial() != Material.AIR)
{
if (iblockstate2.getBlock() == Blocks.NETHERRACK)
{
if (i1 == -1)
{
if (l <= 0)
{
iblockstate = AIR;
iblockstate1 = NETHERRACK;
}
else if (j1 >= i - 4 && j1 <= i + 1)
{
iblockstate = NETHERRACK;
iblockstate1 = NETHERRACK;
if (flag1)
{
iblockstate = GRAVEL;
iblockstate1 = NETHERRACK;
}
if (flag)
{
iblockstate = SOUL_SAND;
iblockstate1 = SOUL_SAND;
}
}
if (j1 < i && (iblockstate == null || iblockstate.getMaterial() == Material.AIR))
{
iblockstate = LAVA;
}
i1 = l;
if (j1 >= i - 1)
{
primer.setBlockState(k, j1, j, iblockstate);
}
else
{
primer.setBlockState(k, j1, j, iblockstate1);
}
}
else if (i1 > 0)
{
--i1;
primer.setBlockState(k, j1, j, iblockstate1);
}
}
}
else
{
i1 = -1;
}
}
else
{
primer.setBlockState(k, j1, j, BEDROCK);
}
}
}
}
}
/**
* Generates the chunk at the specified position, from scratch
*/
public Chunk generateChunk(int x, int z)
{
this.rand.setSeed((long)x * 341873128712L + (long)z * 132897987541L);
ChunkPrimer chunkprimer = new ChunkPrimer();
this.prepareHeights(x, z, chunkprimer);
this.buildSurfaces(x, z, chunkprimer);
this.genNetherCaves.generate(this.world, x, z, chunkprimer);
if (this.generateStructures)
{
this.genNetherBridge.generate(this.world, x, z, chunkprimer);
}
Chunk chunk = new Chunk(this.world, chunkprimer, x, z);
Biome[] abiome = this.world.getBiomeProvider().getBiomes((Biome[])null, x * 16, z * 16, 16, 16);
byte[] abyte = chunk.getBiomeArray();
for (int i = 0; i < abyte.length; ++i)
{
abyte[i] = (byte)Biome.getIdForBiome(abiome[i]);
}
chunk.resetRelightChecks();
return chunk;
}
private double[] getHeights(double[] p_185938_1_, int p_185938_2_, int p_185938_3_, int p_185938_4_, int p_185938_5_, int p_185938_6_, int p_185938_7_)
{
if (p_185938_1_ == null)
{
p_185938_1_ = new double[p_185938_5_ * p_185938_6_ * p_185938_7_];
}
net.minecraftforge.event.terraingen.ChunkGeneratorEvent.InitNoiseField event = new net.minecraftforge.event.terraingen.ChunkGeneratorEvent.InitNoiseField(this, p_185938_1_, p_185938_2_, p_185938_3_, p_185938_4_, p_185938_5_, p_185938_6_, p_185938_7_);
net.minecraftforge.common.MinecraftForge.EVENT_BUS.post(event);
if (event.getResult() == net.minecraftforge.fml.common.eventhandler.Event.Result.DENY) return event.getNoisefield();
double d0 = 684.412D;
double d1 = 2053.236D;
this.noiseData4 = this.scaleNoise.generateNoiseOctaves(this.noiseData4, p_185938_2_, p_185938_3_, p_185938_4_, p_185938_5_, 1, p_185938_7_, 1.0D, 0.0D, 1.0D);
this.dr = this.depthNoise.generateNoiseOctaves(this.dr, p_185938_2_, p_185938_3_, p_185938_4_, p_185938_5_, 1, p_185938_7_, 100.0D, 0.0D, 100.0D);
this.pnr = this.perlinNoise1.generateNoiseOctaves(this.pnr, p_185938_2_, p_185938_3_, p_185938_4_, p_185938_5_, p_185938_6_, p_185938_7_, 8.555150000000001D, 34.2206D, 8.555150000000001D);
this.ar = this.lperlinNoise1.generateNoiseOctaves(this.ar, p_185938_2_, p_185938_3_, p_185938_4_, p_185938_5_, p_185938_6_, p_185938_7_, 684.412D, 2053.236D, 684.412D);
this.br = this.lperlinNoise2.generateNoiseOctaves(this.br, p_185938_2_, p_185938_3_, p_185938_4_, p_185938_5_, p_185938_6_, p_185938_7_, 684.412D, 2053.236D, 684.412D);
int i = 0;
double[] adouble = new double[p_185938_6_];
for (int j = 0; j < p_185938_6_; ++j)
{
adouble[j] = Math.cos((double)j * Math.PI * 6.0D / (double)p_185938_6_) * 2.0D;
double d2 = (double)j;
if (j > p_185938_6_ / 2)
{
d2 = (double)(p_185938_6_ - 1 - j);
}
if (d2 < 4.0D)
{
d2 = 4.0D - d2;
adouble[j] -= d2 * d2 * d2 * 10.0D;
}
}
for (int l = 0; l < p_185938_5_; ++l)
{
for (int i1 = 0; i1 < p_185938_7_; ++i1)
{
double d3 = 0.0D;
for (int k = 0; k < p_185938_6_; ++k)
{
double d4 = adouble[k];
double d5 = this.ar[i] / 512.0D;
double d6 = this.br[i] / 512.0D;
double d7 = (this.pnr[i] / 10.0D + 1.0D) / 2.0D;
double d8;
if (d7 < 0.0D)
{
d8 = d5;
}
else if (d7 > 1.0D)
{
d8 = d6;
}
else
{
d8 = d5 + (d6 - d5) * d7;
}
d8 = d8 - d4;
if (k > p_185938_6_ - 4)
{
double d9 = (double)((float)(k - (p_185938_6_ - 4)) / 3.0F);
d8 = d8 * (1.0D - d9) + -10.0D * d9;
}
if ((double)k < 0.0D)
{
double d10 = (0.0D - (double)k) / 4.0D;
d10 = MathHelper.clamp(d10, 0.0D, 1.0D);
d8 = d8 * (1.0D - d10) + -10.0D * d10;
}
p_185938_1_[i] = d8;
++i;
}
}
}
return p_185938_1_;
}
/**
* Generate initial structures in this chunk, e.g. mineshafts, temples, lakes, and dungeons
*/
public void populate(int x, int z)
{
BlockFalling.fallInstantly = true;
net.minecraftforge.event.ForgeEventFactory.onChunkPopulate(true, this, this.world, this.rand, x, z, false);
int i = x * 16;
int j = z * 16;
BlockPos blockpos = new BlockPos(i, 0, j);
Biome biome = this.world.getBiome(blockpos.add(16, 0, 16));
ChunkPos chunkpos = new ChunkPos(x, z);
this.genNetherBridge.generateStructure(this.world, this.rand, chunkpos);
if (net.minecraftforge.event.terraingen.TerrainGen.populate(this, this.world, this.rand, x, z, false, net.minecraftforge.event.terraingen.PopulateChunkEvent.Populate.EventType.NETHER_LAVA))
for (int k = 0; k < 8; ++k)
{
this.hellSpringGen.generate(this.world, this.rand, blockpos.add(this.rand.nextInt(16) + 8, this.rand.nextInt(120) + 4, this.rand.nextInt(16) + 8));
}
if (net.minecraftforge.event.terraingen.TerrainGen.populate(this, this.world, this.rand, x, z, false, net.minecraftforge.event.terraingen.PopulateChunkEvent.Populate.EventType.FIRE))
for (int i1 = 0; i1 < this.rand.nextInt(this.rand.nextInt(10) + 1) + 1; ++i1)
{
this.fireFeature.generate(this.world, this.rand, blockpos.add(this.rand.nextInt(16) + 8, this.rand.nextInt(120) + 4, this.rand.nextInt(16) + 8));
}
if (net.minecraftforge.event.terraingen.TerrainGen.populate(this, this.world, this.rand, x, z, false, net.minecraftforge.event.terraingen.PopulateChunkEvent.Populate.EventType.GLOWSTONE))
{
for (int j1 = 0; j1 < this.rand.nextInt(this.rand.nextInt(10) + 1); ++j1)
{
this.lightGemGen.generate(this.world, this.rand, blockpos.add(this.rand.nextInt(16) + 8, this.rand.nextInt(120) + 4, this.rand.nextInt(16) + 8));
}
for (int k1 = 0; k1 < 10; ++k1)
{
this.hellPortalGen.generate(this.world, this.rand, blockpos.add(this.rand.nextInt(16) + 8, this.rand.nextInt(128), this.rand.nextInt(16) + 8));
}
}//Forge: End doGLowstone
net.minecraftforge.event.ForgeEventFactory.onChunkPopulate(false, this, this.world, this.rand, x, z, false);
net.minecraftforge.common.MinecraftForge.EVENT_BUS.post(new net.minecraftforge.event.terraingen.DecorateBiomeEvent.Pre(this.world, this.rand, chunkpos));
if (net.minecraftforge.event.terraingen.TerrainGen.decorate(this.world, this.rand, chunkpos, net.minecraftforge.event.terraingen.DecorateBiomeEvent.Decorate.EventType.SHROOM))
{
if (this.rand.nextBoolean())
{
this.brownMushroomFeature.generate(this.world, this.rand, blockpos.add(this.rand.nextInt(16) + 8, this.rand.nextInt(128), this.rand.nextInt(16) + 8));
}
if (this.rand.nextBoolean())
{
this.redMushroomFeature.generate(this.world, this.rand, blockpos.add(this.rand.nextInt(16) + 8, this.rand.nextInt(128), this.rand.nextInt(16) + 8));
}
}
if (net.minecraftforge.event.terraingen.TerrainGen.generateOre(this.world, this.rand, quartzGen, blockpos, net.minecraftforge.event.terraingen.OreGenEvent.GenerateMinable.EventType.QUARTZ))
for (int l1 = 0; l1 < 16; ++l1)
{
this.quartzGen.generate(this.world, this.rand, blockpos.add(this.rand.nextInt(16), this.rand.nextInt(108) + 10, this.rand.nextInt(16)));
}
int i2 = this.world.getSeaLevel() / 2 + 1;
if (net.minecraftforge.event.terraingen.TerrainGen.populate(this, this.world, this.rand, x, z, false, net.minecraftforge.event.terraingen.PopulateChunkEvent.Populate.EventType.NETHER_MAGMA))
for (int l = 0; l < 4; ++l)
{
this.magmaGen.generate(this.world, this.rand, blockpos.add(this.rand.nextInt(16), i2 - 5 + this.rand.nextInt(10), this.rand.nextInt(16)));
}
if (net.minecraftforge.event.terraingen.TerrainGen.populate(this, this.world, this.rand, x, z, false, net.minecraftforge.event.terraingen.PopulateChunkEvent.Populate.EventType.NETHER_LAVA2))
for (int j2 = 0; j2 < 16; ++j2)
{
int offset = net.minecraftforge.common.ForgeModContainer.fixVanillaCascading ? 8 : 0; // MC-117810
this.lavaTrapGen.generate(this.world, this.rand, blockpos.add(this.rand.nextInt(16) + offset, this.rand.nextInt(108) + 10, this.rand.nextInt(16) + offset));
}
biome.decorate(this.world, this.rand, new BlockPos(i, 0, j));
net.minecraftforge.common.MinecraftForge.EVENT_BUS.post(new net.minecraftforge.event.terraingen.DecorateBiomeEvent.Post(this.world, this.rand, blockpos));
BlockFalling.fallInstantly = false;
}
/**
* Called to generate additional structures after initial worldgen, used by ocean monuments
*/
public boolean generateStructures(Chunk chunkIn, int x, int z)
{
return false;
}
public List<Biome.SpawnListEntry> getPossibleCreatures(EnumCreatureType creatureType, BlockPos pos)
{
if (creatureType == EnumCreatureType.MONSTER)
{
if (this.genNetherBridge.isInsideStructure(pos))
{
return this.genNetherBridge.getSpawnList();
}
if (this.genNetherBridge.isPositionInStructure(this.world, pos) && this.world.getBlockState(pos.down()).getBlock() == Blocks.NETHER_BRICK)
{
return this.genNetherBridge.getSpawnList();
}
}
Biome biome = this.world.getBiome(pos);
return biome.getSpawnableList(creatureType);
}
@Nullable
public BlockPos getNearestStructurePos(World worldIn, String structureName, BlockPos position, boolean findUnexplored)
{
return "Fortress".equals(structureName) && this.genNetherBridge != null ? this.genNetherBridge.getNearestStructurePos(worldIn, position, findUnexplored) : null;
}
public boolean isInsideStructure(World worldIn, String structureName, BlockPos pos)
{
return "Fortress".equals(structureName) && this.genNetherBridge != null ? this.genNetherBridge.isInsideStructure(pos) : false;
}
/**
* Recreates data about structures intersecting given chunk (used for example by getPossibleCreatures), without
* placing any blocks. When called for the first time before any chunk is generated - also initializes the internal
* state needed by getPossibleCreatures.
*/
public void recreateStructures(Chunk chunkIn, int x, int z)
{
this.genNetherBridge.generate(this.world, x, z, (ChunkPrimer)null);
}
}

View File

@@ -0,0 +1,642 @@
package net.minecraft.world.gen;
import java.util.List;
import java.util.Random;
import javax.annotation.Nullable;
import net.minecraft.block.BlockFalling;
import net.minecraft.block.state.IBlockState;
import net.minecraft.entity.EnumCreatureType;
import net.minecraft.init.Biomes;
import net.minecraft.init.Blocks;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.ChunkPos;
import net.minecraft.util.math.MathHelper;
import net.minecraft.world.World;
import net.minecraft.world.WorldEntitySpawner;
import net.minecraft.world.WorldType;
import net.minecraft.world.biome.Biome;
import net.minecraft.world.chunk.Chunk;
import net.minecraft.world.chunk.ChunkPrimer;
import net.minecraft.world.gen.feature.WorldGenDungeons;
import net.minecraft.world.gen.feature.WorldGenLakes;
import net.minecraft.world.gen.structure.MapGenMineshaft;
import net.minecraft.world.gen.structure.MapGenScatteredFeature;
import net.minecraft.world.gen.structure.MapGenStronghold;
import net.minecraft.world.gen.structure.MapGenVillage;
import net.minecraft.world.gen.structure.StructureOceanMonument;
import net.minecraft.world.gen.structure.WoodlandMansion;
public class ChunkGeneratorOverworld implements IChunkGenerator
{
protected static final IBlockState STONE = Blocks.STONE.getDefaultState();
private final Random rand;
private NoiseGeneratorOctaves minLimitPerlinNoise;
private NoiseGeneratorOctaves maxLimitPerlinNoise;
private NoiseGeneratorOctaves mainPerlinNoise;
private NoiseGeneratorPerlin surfaceNoise;
public NoiseGeneratorOctaves scaleNoise;
public NoiseGeneratorOctaves depthNoise;
public NoiseGeneratorOctaves forestNoise;
private final World world;
private final boolean mapFeaturesEnabled;
private final WorldType terrainType;
private final double[] heightMap;
private final float[] biomeWeights;
private ChunkGeneratorSettings settings;
private IBlockState oceanBlock = Blocks.WATER.getDefaultState();
private double[] depthBuffer = new double[256];
private MapGenBase caveGenerator = new MapGenCaves();
private MapGenStronghold strongholdGenerator = new MapGenStronghold();
private MapGenVillage villageGenerator = new MapGenVillage();
private MapGenMineshaft mineshaftGenerator = new MapGenMineshaft();
private MapGenScatteredFeature scatteredFeatureGenerator = new MapGenScatteredFeature();
private MapGenBase ravineGenerator = new MapGenRavine();
private StructureOceanMonument oceanMonumentGenerator = new StructureOceanMonument();
private WoodlandMansion woodlandMansionGenerator = new WoodlandMansion(this);
private Biome[] biomesForGeneration;
double[] mainNoiseRegion;
double[] minLimitRegion;
double[] maxLimitRegion;
double[] depthRegion;
public ChunkGeneratorOverworld(World worldIn, long seed, boolean mapFeaturesEnabledIn, String generatorOptions)
{
{
caveGenerator = net.minecraftforge.event.terraingen.TerrainGen.getModdedMapGen(caveGenerator, net.minecraftforge.event.terraingen.InitMapGenEvent.EventType.CAVE);
strongholdGenerator = (MapGenStronghold)net.minecraftforge.event.terraingen.TerrainGen.getModdedMapGen(strongholdGenerator, net.minecraftforge.event.terraingen.InitMapGenEvent.EventType.STRONGHOLD);
villageGenerator = (MapGenVillage)net.minecraftforge.event.terraingen.TerrainGen.getModdedMapGen(villageGenerator, net.minecraftforge.event.terraingen.InitMapGenEvent.EventType.VILLAGE);
mineshaftGenerator = (MapGenMineshaft)net.minecraftforge.event.terraingen.TerrainGen.getModdedMapGen(mineshaftGenerator, net.minecraftforge.event.terraingen.InitMapGenEvent.EventType.MINESHAFT);
scatteredFeatureGenerator = (MapGenScatteredFeature)net.minecraftforge.event.terraingen.TerrainGen.getModdedMapGen(scatteredFeatureGenerator, net.minecraftforge.event.terraingen.InitMapGenEvent.EventType.SCATTERED_FEATURE);
ravineGenerator = net.minecraftforge.event.terraingen.TerrainGen.getModdedMapGen(ravineGenerator, net.minecraftforge.event.terraingen.InitMapGenEvent.EventType.RAVINE);
oceanMonumentGenerator = (StructureOceanMonument)net.minecraftforge.event.terraingen.TerrainGen.getModdedMapGen(oceanMonumentGenerator, net.minecraftforge.event.terraingen.InitMapGenEvent.EventType.OCEAN_MONUMENT);
woodlandMansionGenerator = (WoodlandMansion)net.minecraftforge.event.terraingen.TerrainGen.getModdedMapGen(woodlandMansionGenerator, net.minecraftforge.event.terraingen.InitMapGenEvent.EventType.WOODLAND_MANSION);
}
this.world = worldIn;
this.mapFeaturesEnabled = mapFeaturesEnabledIn;
this.terrainType = worldIn.getWorldInfo().getTerrainType();
this.rand = new Random(seed);
this.minLimitPerlinNoise = new NoiseGeneratorOctaves(this.rand, 16);
this.maxLimitPerlinNoise = new NoiseGeneratorOctaves(this.rand, 16);
this.mainPerlinNoise = new NoiseGeneratorOctaves(this.rand, 8);
this.surfaceNoise = new NoiseGeneratorPerlin(this.rand, 4);
this.scaleNoise = new NoiseGeneratorOctaves(this.rand, 10);
this.depthNoise = new NoiseGeneratorOctaves(this.rand, 16);
this.forestNoise = new NoiseGeneratorOctaves(this.rand, 8);
this.heightMap = new double[825];
this.biomeWeights = new float[25];
for (int i = -2; i <= 2; ++i)
{
for (int j = -2; j <= 2; ++j)
{
float f = 10.0F / MathHelper.sqrt((float)(i * i + j * j) + 0.2F);
this.biomeWeights[i + 2 + (j + 2) * 5] = f;
}
}
if (generatorOptions != null)
{
this.settings = ChunkGeneratorSettings.Factory.jsonToFactory(generatorOptions).build();
this.oceanBlock = this.settings.useLavaOceans ? Blocks.LAVA.getDefaultState() : Blocks.WATER.getDefaultState();
worldIn.setSeaLevel(this.settings.seaLevel);
}
net.minecraftforge.event.terraingen.InitNoiseGensEvent.ContextOverworld ctx =
new net.minecraftforge.event.terraingen.InitNoiseGensEvent.ContextOverworld(minLimitPerlinNoise, maxLimitPerlinNoise, mainPerlinNoise, surfaceNoise, scaleNoise, depthNoise, forestNoise);
ctx = net.minecraftforge.event.terraingen.TerrainGen.getModdedNoiseGenerators(worldIn, this.rand, ctx);
this.minLimitPerlinNoise = ctx.getLPerlin1();
this.maxLimitPerlinNoise = ctx.getLPerlin2();
this.mainPerlinNoise = ctx.getPerlin();
this.surfaceNoise = ctx.getHeight();
this.scaleNoise = ctx.getScale();
this.depthNoise = ctx.getDepth();
this.forestNoise = ctx.getForest();
}
public void setBlocksInChunk(int x, int z, ChunkPrimer primer)
{
this.biomesForGeneration = this.world.getBiomeProvider().getBiomesForGeneration(this.biomesForGeneration, x * 4 - 2, z * 4 - 2, 10, 10);
this.generateHeightmap(x * 4, 0, z * 4);
for (int i = 0; i < 4; ++i)
{
int j = i * 5;
int k = (i + 1) * 5;
for (int l = 0; l < 4; ++l)
{
int i1 = (j + l) * 33;
int j1 = (j + l + 1) * 33;
int k1 = (k + l) * 33;
int l1 = (k + l + 1) * 33;
for (int i2 = 0; i2 < 32; ++i2)
{
double d0 = 0.125D;
double d1 = this.heightMap[i1 + i2];
double d2 = this.heightMap[j1 + i2];
double d3 = this.heightMap[k1 + i2];
double d4 = this.heightMap[l1 + i2];
double d5 = (this.heightMap[i1 + i2 + 1] - d1) * 0.125D;
double d6 = (this.heightMap[j1 + i2 + 1] - d2) * 0.125D;
double d7 = (this.heightMap[k1 + i2 + 1] - d3) * 0.125D;
double d8 = (this.heightMap[l1 + i2 + 1] - d4) * 0.125D;
for (int j2 = 0; j2 < 8; ++j2)
{
double d9 = 0.25D;
double d10 = d1;
double d11 = d2;
double d12 = (d3 - d1) * 0.25D;
double d13 = (d4 - d2) * 0.25D;
for (int k2 = 0; k2 < 4; ++k2)
{
double d14 = 0.25D;
double d16 = (d11 - d10) * 0.25D;
double lvt_45_1_ = d10 - d16;
for (int l2 = 0; l2 < 4; ++l2)
{
if ((lvt_45_1_ += d16) > 0.0D)
{
primer.setBlockState(i * 4 + k2, i2 * 8 + j2, l * 4 + l2, STONE);
}
else if (i2 * 8 + j2 < this.settings.seaLevel)
{
primer.setBlockState(i * 4 + k2, i2 * 8 + j2, l * 4 + l2, this.oceanBlock);
}
}
d10 += d12;
d11 += d13;
}
d1 += d5;
d2 += d6;
d3 += d7;
d4 += d8;
}
}
}
}
}
public void replaceBiomeBlocks(int x, int z, ChunkPrimer primer, Biome[] biomesIn)
{
if (!net.minecraftforge.event.ForgeEventFactory.onReplaceBiomeBlocks(this, x, z, primer, this.world)) return;
double d0 = 0.03125D;
this.depthBuffer = this.surfaceNoise.getRegion(this.depthBuffer, (double)(x * 16), (double)(z * 16), 16, 16, 0.0625D, 0.0625D, 1.0D);
for (int i = 0; i < 16; ++i)
{
for (int j = 0; j < 16; ++j)
{
Biome biome = biomesIn[j + i * 16];
biome.genTerrainBlocks(this.world, this.rand, primer, x * 16 + i, z * 16 + j, this.depthBuffer[j + i * 16]);
}
}
}
/**
* Generates the chunk at the specified position, from scratch
*/
public Chunk generateChunk(int x, int z)
{
this.rand.setSeed((long)x * 341873128712L + (long)z * 132897987541L);
ChunkPrimer chunkprimer = new ChunkPrimer();
this.setBlocksInChunk(x, z, chunkprimer);
this.biomesForGeneration = this.world.getBiomeProvider().getBiomes(this.biomesForGeneration, x * 16, z * 16, 16, 16);
this.replaceBiomeBlocks(x, z, chunkprimer, this.biomesForGeneration);
if (this.settings.useCaves)
{
this.caveGenerator.generate(this.world, x, z, chunkprimer);
}
if (this.settings.useRavines)
{
this.ravineGenerator.generate(this.world, x, z, chunkprimer);
}
if (this.mapFeaturesEnabled)
{
if (this.settings.useMineShafts)
{
this.mineshaftGenerator.generate(this.world, x, z, chunkprimer);
}
if (this.settings.useVillages)
{
this.villageGenerator.generate(this.world, x, z, chunkprimer);
}
if (this.settings.useStrongholds)
{
this.strongholdGenerator.generate(this.world, x, z, chunkprimer);
}
if (this.settings.useTemples)
{
this.scatteredFeatureGenerator.generate(this.world, x, z, chunkprimer);
}
if (this.settings.useMonuments)
{
this.oceanMonumentGenerator.generate(this.world, x, z, chunkprimer);
}
if (this.settings.useMansions)
{
this.woodlandMansionGenerator.generate(this.world, x, z, chunkprimer);
}
}
Chunk chunk = new Chunk(this.world, chunkprimer, x, z);
byte[] abyte = chunk.getBiomeArray();
for (int i = 0; i < abyte.length; ++i)
{
abyte[i] = (byte)Biome.getIdForBiome(this.biomesForGeneration[i]);
}
chunk.generateSkylightMap();
return chunk;
}
private void generateHeightmap(int p_185978_1_, int p_185978_2_, int p_185978_3_)
{
this.depthRegion = this.depthNoise.generateNoiseOctaves(this.depthRegion, p_185978_1_, p_185978_3_, 5, 5, (double)this.settings.depthNoiseScaleX, (double)this.settings.depthNoiseScaleZ, (double)this.settings.depthNoiseScaleExponent);
float f = this.settings.coordinateScale;
float f1 = this.settings.heightScale;
this.mainNoiseRegion = this.mainPerlinNoise.generateNoiseOctaves(this.mainNoiseRegion, p_185978_1_, p_185978_2_, p_185978_3_, 5, 33, 5, (double)(f / this.settings.mainNoiseScaleX), (double)(f1 / this.settings.mainNoiseScaleY), (double)(f / this.settings.mainNoiseScaleZ));
this.minLimitRegion = this.minLimitPerlinNoise.generateNoiseOctaves(this.minLimitRegion, p_185978_1_, p_185978_2_, p_185978_3_, 5, 33, 5, (double)f, (double)f1, (double)f);
this.maxLimitRegion = this.maxLimitPerlinNoise.generateNoiseOctaves(this.maxLimitRegion, p_185978_1_, p_185978_2_, p_185978_3_, 5, 33, 5, (double)f, (double)f1, (double)f);
int i = 0;
int j = 0;
for (int k = 0; k < 5; ++k)
{
for (int l = 0; l < 5; ++l)
{
float f2 = 0.0F;
float f3 = 0.0F;
float f4 = 0.0F;
int i1 = 2;
Biome biome = this.biomesForGeneration[k + 2 + (l + 2) * 10];
for (int j1 = -2; j1 <= 2; ++j1)
{
for (int k1 = -2; k1 <= 2; ++k1)
{
Biome biome1 = this.biomesForGeneration[k + j1 + 2 + (l + k1 + 2) * 10];
float f5 = this.settings.biomeDepthOffSet + biome1.getBaseHeight() * this.settings.biomeDepthWeight;
float f6 = this.settings.biomeScaleOffset + biome1.getHeightVariation() * this.settings.biomeScaleWeight;
if (this.terrainType == WorldType.AMPLIFIED && f5 > 0.0F)
{
f5 = 1.0F + f5 * 2.0F;
f6 = 1.0F + f6 * 4.0F;
}
float f7 = this.biomeWeights[j1 + 2 + (k1 + 2) * 5] / (f5 + 2.0F);
if (biome1.getBaseHeight() > biome.getBaseHeight())
{
f7 /= 2.0F;
}
f2 += f6 * f7;
f3 += f5 * f7;
f4 += f7;
}
}
f2 = f2 / f4;
f3 = f3 / f4;
f2 = f2 * 0.9F + 0.1F;
f3 = (f3 * 4.0F - 1.0F) / 8.0F;
double d7 = this.depthRegion[j] / 8000.0D;
if (d7 < 0.0D)
{
d7 = -d7 * 0.3D;
}
d7 = d7 * 3.0D - 2.0D;
if (d7 < 0.0D)
{
d7 = d7 / 2.0D;
if (d7 < -1.0D)
{
d7 = -1.0D;
}
d7 = d7 / 1.4D;
d7 = d7 / 2.0D;
}
else
{
if (d7 > 1.0D)
{
d7 = 1.0D;
}
d7 = d7 / 8.0D;
}
++j;
double d8 = (double)f3;
double d9 = (double)f2;
d8 = d8 + d7 * 0.2D;
d8 = d8 * (double)this.settings.baseSize / 8.0D;
double d0 = (double)this.settings.baseSize + d8 * 4.0D;
for (int l1 = 0; l1 < 33; ++l1)
{
double d1 = ((double)l1 - d0) * (double)this.settings.stretchY * 128.0D / 256.0D / d9;
if (d1 < 0.0D)
{
d1 *= 4.0D;
}
double d2 = this.minLimitRegion[i] / (double)this.settings.lowerLimitScale;
double d3 = this.maxLimitRegion[i] / (double)this.settings.upperLimitScale;
double d4 = (this.mainNoiseRegion[i] / 10.0D + 1.0D) / 2.0D;
double d5 = MathHelper.clampedLerp(d2, d3, d4) - d1;
if (l1 > 29)
{
double d6 = (double)((float)(l1 - 29) / 3.0F);
d5 = d5 * (1.0D - d6) + -10.0D * d6;
}
this.heightMap[i] = d5;
++i;
}
}
}
}
/**
* Generate initial structures in this chunk, e.g. mineshafts, temples, lakes, and dungeons
*/
public void populate(int x, int z)
{
BlockFalling.fallInstantly = true;
int i = x * 16;
int j = z * 16;
BlockPos blockpos = new BlockPos(i, 0, j);
Biome biome = this.world.getBiome(blockpos.add(16, 0, 16));
this.rand.setSeed(this.world.getSeed());
long k = this.rand.nextLong() / 2L * 2L + 1L;
long l = this.rand.nextLong() / 2L * 2L + 1L;
this.rand.setSeed((long)x * k + (long)z * l ^ this.world.getSeed());
boolean flag = false;
ChunkPos chunkpos = new ChunkPos(x, z);
net.minecraftforge.event.ForgeEventFactory.onChunkPopulate(true, this, this.world, this.rand, x, z, flag);
if (this.mapFeaturesEnabled)
{
if (this.settings.useMineShafts)
{
this.mineshaftGenerator.generateStructure(this.world, this.rand, chunkpos);
}
if (this.settings.useVillages)
{
flag = this.villageGenerator.generateStructure(this.world, this.rand, chunkpos);
}
if (this.settings.useStrongholds)
{
this.strongholdGenerator.generateStructure(this.world, this.rand, chunkpos);
}
if (this.settings.useTemples)
{
this.scatteredFeatureGenerator.generateStructure(this.world, this.rand, chunkpos);
}
if (this.settings.useMonuments)
{
this.oceanMonumentGenerator.generateStructure(this.world, this.rand, chunkpos);
}
if (this.settings.useMansions)
{
this.woodlandMansionGenerator.generateStructure(this.world, this.rand, chunkpos);
}
}
if (biome != Biomes.DESERT && biome != Biomes.DESERT_HILLS && this.settings.useWaterLakes && !flag && this.rand.nextInt(this.settings.waterLakeChance) == 0)
if (net.minecraftforge.event.terraingen.TerrainGen.populate(this, this.world, this.rand, x, z, flag, net.minecraftforge.event.terraingen.PopulateChunkEvent.Populate.EventType.LAKE))
{
int i1 = this.rand.nextInt(16) + 8;
int j1 = this.rand.nextInt(256);
int k1 = this.rand.nextInt(16) + 8;
(new WorldGenLakes(Blocks.WATER)).generate(this.world, this.rand, blockpos.add(i1, j1, k1));
}
if (!flag && this.rand.nextInt(this.settings.lavaLakeChance / 10) == 0 && this.settings.useLavaLakes)
if (net.minecraftforge.event.terraingen.TerrainGen.populate(this, this.world, this.rand, x, z, flag, net.minecraftforge.event.terraingen.PopulateChunkEvent.Populate.EventType.LAVA))
{
int i2 = this.rand.nextInt(16) + 8;
int l2 = this.rand.nextInt(this.rand.nextInt(248) + 8);
int k3 = this.rand.nextInt(16) + 8;
if (l2 < this.world.getSeaLevel() || this.rand.nextInt(this.settings.lavaLakeChance / 8) == 0)
{
(new WorldGenLakes(Blocks.LAVA)).generate(this.world, this.rand, blockpos.add(i2, l2, k3));
}
}
if (this.settings.useDungeons)
if (net.minecraftforge.event.terraingen.TerrainGen.populate(this, this.world, this.rand, x, z, flag, net.minecraftforge.event.terraingen.PopulateChunkEvent.Populate.EventType.DUNGEON))
{
for (int j2 = 0; j2 < this.settings.dungeonChance; ++j2)
{
int i3 = this.rand.nextInt(16) + 8;
int l3 = this.rand.nextInt(256);
int l1 = this.rand.nextInt(16) + 8;
(new WorldGenDungeons()).generate(this.world, this.rand, blockpos.add(i3, l3, l1));
}
}
biome.decorate(this.world, this.rand, new BlockPos(i, 0, j));
if (net.minecraftforge.event.terraingen.TerrainGen.populate(this, this.world, this.rand, x, z, flag, net.minecraftforge.event.terraingen.PopulateChunkEvent.Populate.EventType.ANIMALS))
WorldEntitySpawner.performWorldGenSpawning(this.world, biome, i + 8, j + 8, 16, 16, this.rand);
blockpos = blockpos.add(8, 0, 8);
if (net.minecraftforge.event.terraingen.TerrainGen.populate(this, this.world, this.rand, x, z, flag, net.minecraftforge.event.terraingen.PopulateChunkEvent.Populate.EventType.ICE))
{
for (int k2 = 0; k2 < 16; ++k2)
{
for (int j3 = 0; j3 < 16; ++j3)
{
BlockPos blockpos1 = this.world.getPrecipitationHeight(blockpos.add(k2, 0, j3));
BlockPos blockpos2 = blockpos1.down();
if (this.world.canBlockFreezeWater(blockpos2))
{
this.world.setBlockState(blockpos2, Blocks.ICE.getDefaultState(), 2);
}
if (this.world.canSnowAt(blockpos1, true))
{
this.world.setBlockState(blockpos1, Blocks.SNOW_LAYER.getDefaultState(), 2);
}
}
}
}//Forge: End ICE
net.minecraftforge.event.ForgeEventFactory.onChunkPopulate(false, this, this.world, this.rand, x, z, flag);
BlockFalling.fallInstantly = false;
}
/**
* Called to generate additional structures after initial worldgen, used by ocean monuments
*/
public boolean generateStructures(Chunk chunkIn, int x, int z)
{
boolean flag = false;
if (this.settings.useMonuments && this.mapFeaturesEnabled && chunkIn.getInhabitedTime() < 3600L)
{
flag |= this.oceanMonumentGenerator.generateStructure(this.world, this.rand, new ChunkPos(x, z));
}
return flag;
}
public List<Biome.SpawnListEntry> getPossibleCreatures(EnumCreatureType creatureType, BlockPos pos)
{
Biome biome = this.world.getBiome(pos);
if (this.mapFeaturesEnabled)
{
if (creatureType == EnumCreatureType.MONSTER && this.scatteredFeatureGenerator.isSwampHut(pos))
{
return this.scatteredFeatureGenerator.getMonsters();
}
if (creatureType == EnumCreatureType.MONSTER && this.settings.useMonuments && this.oceanMonumentGenerator.isPositionInStructure(this.world, pos))
{
return this.oceanMonumentGenerator.getMonsters();
}
}
return biome.getSpawnableList(creatureType);
}
public boolean isInsideStructure(World worldIn, String structureName, BlockPos pos)
{
if (!this.mapFeaturesEnabled)
{
return false;
}
else if ("Stronghold".equals(structureName) && this.strongholdGenerator != null)
{
return this.strongholdGenerator.isInsideStructure(pos);
}
else if ("Mansion".equals(structureName) && this.woodlandMansionGenerator != null)
{
return this.woodlandMansionGenerator.isInsideStructure(pos);
}
else if ("Monument".equals(structureName) && this.oceanMonumentGenerator != null)
{
return this.oceanMonumentGenerator.isInsideStructure(pos);
}
else if ("Village".equals(structureName) && this.villageGenerator != null)
{
return this.villageGenerator.isInsideStructure(pos);
}
else if ("Mineshaft".equals(structureName) && this.mineshaftGenerator != null)
{
return this.mineshaftGenerator.isInsideStructure(pos);
}
else
{
return "Temple".equals(structureName) && this.scatteredFeatureGenerator != null ? this.scatteredFeatureGenerator.isInsideStructure(pos) : false;
}
}
@Nullable
public BlockPos getNearestStructurePos(World worldIn, String structureName, BlockPos position, boolean findUnexplored)
{
if (!this.mapFeaturesEnabled)
{
return null;
}
else if ("Stronghold".equals(structureName) && this.strongholdGenerator != null)
{
return this.strongholdGenerator.getNearestStructurePos(worldIn, position, findUnexplored);
}
else if ("Mansion".equals(structureName) && this.woodlandMansionGenerator != null)
{
return this.woodlandMansionGenerator.getNearestStructurePos(worldIn, position, findUnexplored);
}
else if ("Monument".equals(structureName) && this.oceanMonumentGenerator != null)
{
return this.oceanMonumentGenerator.getNearestStructurePos(worldIn, position, findUnexplored);
}
else if ("Village".equals(structureName) && this.villageGenerator != null)
{
return this.villageGenerator.getNearestStructurePos(worldIn, position, findUnexplored);
}
else if ("Mineshaft".equals(structureName) && this.mineshaftGenerator != null)
{
return this.mineshaftGenerator.getNearestStructurePos(worldIn, position, findUnexplored);
}
else
{
return "Temple".equals(structureName) && this.scatteredFeatureGenerator != null ? this.scatteredFeatureGenerator.getNearestStructurePos(worldIn, position, findUnexplored) : null;
}
}
/**
* Recreates data about structures intersecting given chunk (used for example by getPossibleCreatures), without
* placing any blocks. When called for the first time before any chunk is generated - also initializes the internal
* state needed by getPossibleCreatures.
*/
public void recreateStructures(Chunk chunkIn, int x, int z)
{
if (this.mapFeaturesEnabled)
{
if (this.settings.useMineShafts)
{
this.mineshaftGenerator.generate(this.world, x, z, (ChunkPrimer)null);
}
if (this.settings.useVillages)
{
this.villageGenerator.generate(this.world, x, z, (ChunkPrimer)null);
}
if (this.settings.useStrongholds)
{
this.strongholdGenerator.generate(this.world, x, z, (ChunkPrimer)null);
}
if (this.settings.useTemples)
{
this.scatteredFeatureGenerator.generate(this.world, x, z, (ChunkPrimer)null);
}
if (this.settings.useMonuments)
{
this.oceanMonumentGenerator.generate(this.world, x, z, (ChunkPrimer)null);
}
if (this.settings.useMansions)
{
this.woodlandMansionGenerator.generate(this.world, x, z, (ChunkPrimer)null);
}
}
}
}

View File

@@ -0,0 +1,997 @@
package net.minecraft.world.gen;
import com.google.common.annotations.VisibleForTesting;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.JsonDeserializationContext;
import com.google.gson.JsonDeserializer;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonParseException;
import com.google.gson.JsonSerializationContext;
import com.google.gson.JsonSerializer;
import java.lang.reflect.Type;
import net.minecraft.init.Biomes;
import net.minecraft.util.JsonUtils;
import net.minecraft.world.biome.Biome;
public class ChunkGeneratorSettings
{
public final float coordinateScale;
public final float heightScale;
public final float upperLimitScale;
public final float lowerLimitScale;
public final float depthNoiseScaleX;
public final float depthNoiseScaleZ;
public final float depthNoiseScaleExponent;
public final float mainNoiseScaleX;
public final float mainNoiseScaleY;
public final float mainNoiseScaleZ;
public final float baseSize;
public final float stretchY;
public final float biomeDepthWeight;
public final float biomeDepthOffSet;
public final float biomeScaleWeight;
public final float biomeScaleOffset;
public final int seaLevel;
public final boolean useCaves;
public final boolean useDungeons;
public final int dungeonChance;
public final boolean useStrongholds;
public final boolean useVillages;
public final boolean useMineShafts;
public final boolean useTemples;
public final boolean useMonuments;
public final boolean useMansions;
public final boolean useRavines;
public final boolean useWaterLakes;
public final int waterLakeChance;
public final boolean useLavaLakes;
public final int lavaLakeChance;
public final boolean useLavaOceans;
public final int fixedBiome;
public final int biomeSize;
public final int riverSize;
public final int dirtSize;
public final int dirtCount;
public final int dirtMinHeight;
public final int dirtMaxHeight;
public final int gravelSize;
public final int gravelCount;
public final int gravelMinHeight;
public final int gravelMaxHeight;
public final int graniteSize;
public final int graniteCount;
public final int graniteMinHeight;
public final int graniteMaxHeight;
public final int dioriteSize;
public final int dioriteCount;
public final int dioriteMinHeight;
public final int dioriteMaxHeight;
public final int andesiteSize;
public final int andesiteCount;
public final int andesiteMinHeight;
public final int andesiteMaxHeight;
public final int coalSize;
public final int coalCount;
public final int coalMinHeight;
public final int coalMaxHeight;
public final int ironSize;
public final int ironCount;
public final int ironMinHeight;
public final int ironMaxHeight;
public final int goldSize;
public final int goldCount;
public final int goldMinHeight;
public final int goldMaxHeight;
public final int redstoneSize;
public final int redstoneCount;
public final int redstoneMinHeight;
public final int redstoneMaxHeight;
public final int diamondSize;
public final int diamondCount;
public final int diamondMinHeight;
public final int diamondMaxHeight;
public final int lapisSize;
public final int lapisCount;
public final int lapisCenterHeight;
public final int lapisSpread;
private ChunkGeneratorSettings(ChunkGeneratorSettings.Factory settingsFactory)
{
this.coordinateScale = settingsFactory.coordinateScale;
this.heightScale = settingsFactory.heightScale;
this.upperLimitScale = settingsFactory.upperLimitScale;
this.lowerLimitScale = settingsFactory.lowerLimitScale;
this.depthNoiseScaleX = settingsFactory.depthNoiseScaleX;
this.depthNoiseScaleZ = settingsFactory.depthNoiseScaleZ;
this.depthNoiseScaleExponent = settingsFactory.depthNoiseScaleExponent;
this.mainNoiseScaleX = settingsFactory.mainNoiseScaleX;
this.mainNoiseScaleY = settingsFactory.mainNoiseScaleY;
this.mainNoiseScaleZ = settingsFactory.mainNoiseScaleZ;
this.baseSize = settingsFactory.baseSize;
this.stretchY = settingsFactory.stretchY;
this.biomeDepthWeight = settingsFactory.biomeDepthWeight;
this.biomeDepthOffSet = settingsFactory.biomeDepthOffset;
this.biomeScaleWeight = settingsFactory.biomeScaleWeight;
this.biomeScaleOffset = settingsFactory.biomeScaleOffset;
this.seaLevel = settingsFactory.seaLevel;
this.useCaves = settingsFactory.useCaves;
this.useDungeons = settingsFactory.useDungeons;
this.dungeonChance = settingsFactory.dungeonChance;
this.useStrongholds = settingsFactory.useStrongholds;
this.useVillages = settingsFactory.useVillages;
this.useMineShafts = settingsFactory.useMineShafts;
this.useTemples = settingsFactory.useTemples;
this.useMonuments = settingsFactory.useMonuments;
this.useMansions = settingsFactory.useMansions;
this.useRavines = settingsFactory.useRavines;
this.useWaterLakes = settingsFactory.useWaterLakes;
this.waterLakeChance = settingsFactory.waterLakeChance;
this.useLavaLakes = settingsFactory.useLavaLakes;
this.lavaLakeChance = settingsFactory.lavaLakeChance;
this.useLavaOceans = settingsFactory.useLavaOceans;
this.fixedBiome = settingsFactory.fixedBiome;
this.biomeSize = settingsFactory.biomeSize;
this.riverSize = settingsFactory.riverSize;
this.dirtSize = settingsFactory.dirtSize;
this.dirtCount = settingsFactory.dirtCount;
this.dirtMinHeight = settingsFactory.dirtMinHeight;
this.dirtMaxHeight = settingsFactory.dirtMaxHeight;
this.gravelSize = settingsFactory.gravelSize;
this.gravelCount = settingsFactory.gravelCount;
this.gravelMinHeight = settingsFactory.gravelMinHeight;
this.gravelMaxHeight = settingsFactory.gravelMaxHeight;
this.graniteSize = settingsFactory.graniteSize;
this.graniteCount = settingsFactory.graniteCount;
this.graniteMinHeight = settingsFactory.graniteMinHeight;
this.graniteMaxHeight = settingsFactory.graniteMaxHeight;
this.dioriteSize = settingsFactory.dioriteSize;
this.dioriteCount = settingsFactory.dioriteCount;
this.dioriteMinHeight = settingsFactory.dioriteMinHeight;
this.dioriteMaxHeight = settingsFactory.dioriteMaxHeight;
this.andesiteSize = settingsFactory.andesiteSize;
this.andesiteCount = settingsFactory.andesiteCount;
this.andesiteMinHeight = settingsFactory.andesiteMinHeight;
this.andesiteMaxHeight = settingsFactory.andesiteMaxHeight;
this.coalSize = settingsFactory.coalSize;
this.coalCount = settingsFactory.coalCount;
this.coalMinHeight = settingsFactory.coalMinHeight;
this.coalMaxHeight = settingsFactory.coalMaxHeight;
this.ironSize = settingsFactory.ironSize;
this.ironCount = settingsFactory.ironCount;
this.ironMinHeight = settingsFactory.ironMinHeight;
this.ironMaxHeight = settingsFactory.ironMaxHeight;
this.goldSize = settingsFactory.goldSize;
this.goldCount = settingsFactory.goldCount;
this.goldMinHeight = settingsFactory.goldMinHeight;
this.goldMaxHeight = settingsFactory.goldMaxHeight;
this.redstoneSize = settingsFactory.redstoneSize;
this.redstoneCount = settingsFactory.redstoneCount;
this.redstoneMinHeight = settingsFactory.redstoneMinHeight;
this.redstoneMaxHeight = settingsFactory.redstoneMaxHeight;
this.diamondSize = settingsFactory.diamondSize;
this.diamondCount = settingsFactory.diamondCount;
this.diamondMinHeight = settingsFactory.diamondMinHeight;
this.diamondMaxHeight = settingsFactory.diamondMaxHeight;
this.lapisSize = settingsFactory.lapisSize;
this.lapisCount = settingsFactory.lapisCount;
this.lapisCenterHeight = settingsFactory.lapisCenterHeight;
this.lapisSpread = settingsFactory.lapisSpread;
}
public static class Factory
{
@VisibleForTesting
static final Gson JSON_ADAPTER = (new GsonBuilder()).registerTypeAdapter(ChunkGeneratorSettings.Factory.class, new ChunkGeneratorSettings.Serializer()).create();
public float coordinateScale = 684.412F;
public float heightScale = 684.412F;
public float upperLimitScale = 512.0F;
public float lowerLimitScale = 512.0F;
public float depthNoiseScaleX = 200.0F;
public float depthNoiseScaleZ = 200.0F;
public float depthNoiseScaleExponent = 0.5F;
public float mainNoiseScaleX = 80.0F;
public float mainNoiseScaleY = 160.0F;
public float mainNoiseScaleZ = 80.0F;
public float baseSize = 8.5F;
public float stretchY = 12.0F;
public float biomeDepthWeight = 1.0F;
public float biomeDepthOffset;
public float biomeScaleWeight = 1.0F;
public float biomeScaleOffset;
public int seaLevel = 63;
public boolean useCaves = true;
public boolean useDungeons = true;
public int dungeonChance = 8;
public boolean useStrongholds = true;
public boolean useVillages = true;
public boolean useMineShafts = true;
public boolean useTemples = true;
public boolean useMonuments = true;
public boolean useMansions = true;
public boolean useRavines = true;
public boolean useWaterLakes = true;
public int waterLakeChance = 4;
public boolean useLavaLakes = true;
public int lavaLakeChance = 80;
public boolean useLavaOceans;
public int fixedBiome = -1;
public int biomeSize = 4;
public int riverSize = 4;
public int dirtSize = 33;
public int dirtCount = 10;
public int dirtMinHeight;
public int dirtMaxHeight = 256;
public int gravelSize = 33;
public int gravelCount = 8;
public int gravelMinHeight;
public int gravelMaxHeight = 256;
public int graniteSize = 33;
public int graniteCount = 10;
public int graniteMinHeight;
public int graniteMaxHeight = 80;
public int dioriteSize = 33;
public int dioriteCount = 10;
public int dioriteMinHeight;
public int dioriteMaxHeight = 80;
public int andesiteSize = 33;
public int andesiteCount = 10;
public int andesiteMinHeight;
public int andesiteMaxHeight = 80;
public int coalSize = 17;
public int coalCount = 20;
public int coalMinHeight;
public int coalMaxHeight = 128;
public int ironSize = 9;
public int ironCount = 20;
public int ironMinHeight;
public int ironMaxHeight = 64;
public int goldSize = 9;
public int goldCount = 2;
public int goldMinHeight;
public int goldMaxHeight = 32;
public int redstoneSize = 8;
public int redstoneCount = 8;
public int redstoneMinHeight;
public int redstoneMaxHeight = 16;
public int diamondSize = 8;
public int diamondCount = 1;
public int diamondMinHeight;
public int diamondMaxHeight = 16;
public int lapisSize = 7;
public int lapisCount = 1;
public int lapisCenterHeight = 16;
public int lapisSpread = 16;
public static ChunkGeneratorSettings.Factory jsonToFactory(String p_177865_0_)
{
if (p_177865_0_.isEmpty())
{
return new ChunkGeneratorSettings.Factory();
}
else
{
try
{
return (ChunkGeneratorSettings.Factory)JsonUtils.gsonDeserialize(JSON_ADAPTER, p_177865_0_, ChunkGeneratorSettings.Factory.class);
}
catch (Exception var2)
{
return new ChunkGeneratorSettings.Factory();
}
}
}
public String toString()
{
return JSON_ADAPTER.toJson(this);
}
public Factory()
{
this.setDefaults();
}
public void setDefaults()
{
this.coordinateScale = 684.412F;
this.heightScale = 684.412F;
this.upperLimitScale = 512.0F;
this.lowerLimitScale = 512.0F;
this.depthNoiseScaleX = 200.0F;
this.depthNoiseScaleZ = 200.0F;
this.depthNoiseScaleExponent = 0.5F;
this.mainNoiseScaleX = 80.0F;
this.mainNoiseScaleY = 160.0F;
this.mainNoiseScaleZ = 80.0F;
this.baseSize = 8.5F;
this.stretchY = 12.0F;
this.biomeDepthWeight = 1.0F;
this.biomeDepthOffset = 0.0F;
this.biomeScaleWeight = 1.0F;
this.biomeScaleOffset = 0.0F;
this.seaLevel = 63;
this.useCaves = true;
this.useDungeons = true;
this.dungeonChance = 8;
this.useStrongholds = true;
this.useVillages = true;
this.useMineShafts = true;
this.useTemples = true;
this.useMonuments = true;
this.useMansions = true;
this.useRavines = true;
this.useWaterLakes = true;
this.waterLakeChance = 4;
this.useLavaLakes = true;
this.lavaLakeChance = 80;
this.useLavaOceans = false;
this.fixedBiome = -1;
this.biomeSize = 4;
this.riverSize = 4;
this.dirtSize = 33;
this.dirtCount = 10;
this.dirtMinHeight = 0;
this.dirtMaxHeight = 256;
this.gravelSize = 33;
this.gravelCount = 8;
this.gravelMinHeight = 0;
this.gravelMaxHeight = 256;
this.graniteSize = 33;
this.graniteCount = 10;
this.graniteMinHeight = 0;
this.graniteMaxHeight = 80;
this.dioriteSize = 33;
this.dioriteCount = 10;
this.dioriteMinHeight = 0;
this.dioriteMaxHeight = 80;
this.andesiteSize = 33;
this.andesiteCount = 10;
this.andesiteMinHeight = 0;
this.andesiteMaxHeight = 80;
this.coalSize = 17;
this.coalCount = 20;
this.coalMinHeight = 0;
this.coalMaxHeight = 128;
this.ironSize = 9;
this.ironCount = 20;
this.ironMinHeight = 0;
this.ironMaxHeight = 64;
this.goldSize = 9;
this.goldCount = 2;
this.goldMinHeight = 0;
this.goldMaxHeight = 32;
this.redstoneSize = 8;
this.redstoneCount = 8;
this.redstoneMinHeight = 0;
this.redstoneMaxHeight = 16;
this.diamondSize = 8;
this.diamondCount = 1;
this.diamondMinHeight = 0;
this.diamondMaxHeight = 16;
this.lapisSize = 7;
this.lapisCount = 1;
this.lapisCenterHeight = 16;
this.lapisSpread = 16;
}
public boolean equals(Object p_equals_1_)
{
if (this == p_equals_1_)
{
return true;
}
else if (p_equals_1_ != null && this.getClass() == p_equals_1_.getClass())
{
ChunkGeneratorSettings.Factory chunkgeneratorsettings$factory = (ChunkGeneratorSettings.Factory)p_equals_1_;
if (this.andesiteCount != chunkgeneratorsettings$factory.andesiteCount)
{
return false;
}
else if (this.andesiteMaxHeight != chunkgeneratorsettings$factory.andesiteMaxHeight)
{
return false;
}
else if (this.andesiteMinHeight != chunkgeneratorsettings$factory.andesiteMinHeight)
{
return false;
}
else if (this.andesiteSize != chunkgeneratorsettings$factory.andesiteSize)
{
return false;
}
else if (Float.compare(chunkgeneratorsettings$factory.baseSize, this.baseSize) != 0)
{
return false;
}
else if (Float.compare(chunkgeneratorsettings$factory.biomeDepthOffset, this.biomeDepthOffset) != 0)
{
return false;
}
else if (Float.compare(chunkgeneratorsettings$factory.biomeDepthWeight, this.biomeDepthWeight) != 0)
{
return false;
}
else if (Float.compare(chunkgeneratorsettings$factory.biomeScaleOffset, this.biomeScaleOffset) != 0)
{
return false;
}
else if (Float.compare(chunkgeneratorsettings$factory.biomeScaleWeight, this.biomeScaleWeight) != 0)
{
return false;
}
else if (this.biomeSize != chunkgeneratorsettings$factory.biomeSize)
{
return false;
}
else if (this.coalCount != chunkgeneratorsettings$factory.coalCount)
{
return false;
}
else if (this.coalMaxHeight != chunkgeneratorsettings$factory.coalMaxHeight)
{
return false;
}
else if (this.coalMinHeight != chunkgeneratorsettings$factory.coalMinHeight)
{
return false;
}
else if (this.coalSize != chunkgeneratorsettings$factory.coalSize)
{
return false;
}
else if (Float.compare(chunkgeneratorsettings$factory.coordinateScale, this.coordinateScale) != 0)
{
return false;
}
else if (Float.compare(chunkgeneratorsettings$factory.depthNoiseScaleExponent, this.depthNoiseScaleExponent) != 0)
{
return false;
}
else if (Float.compare(chunkgeneratorsettings$factory.depthNoiseScaleX, this.depthNoiseScaleX) != 0)
{
return false;
}
else if (Float.compare(chunkgeneratorsettings$factory.depthNoiseScaleZ, this.depthNoiseScaleZ) != 0)
{
return false;
}
else if (this.diamondCount != chunkgeneratorsettings$factory.diamondCount)
{
return false;
}
else if (this.diamondMaxHeight != chunkgeneratorsettings$factory.diamondMaxHeight)
{
return false;
}
else if (this.diamondMinHeight != chunkgeneratorsettings$factory.diamondMinHeight)
{
return false;
}
else if (this.diamondSize != chunkgeneratorsettings$factory.diamondSize)
{
return false;
}
else if (this.dioriteCount != chunkgeneratorsettings$factory.dioriteCount)
{
return false;
}
else if (this.dioriteMaxHeight != chunkgeneratorsettings$factory.dioriteMaxHeight)
{
return false;
}
else if (this.dioriteMinHeight != chunkgeneratorsettings$factory.dioriteMinHeight)
{
return false;
}
else if (this.dioriteSize != chunkgeneratorsettings$factory.dioriteSize)
{
return false;
}
else if (this.dirtCount != chunkgeneratorsettings$factory.dirtCount)
{
return false;
}
else if (this.dirtMaxHeight != chunkgeneratorsettings$factory.dirtMaxHeight)
{
return false;
}
else if (this.dirtMinHeight != chunkgeneratorsettings$factory.dirtMinHeight)
{
return false;
}
else if (this.dirtSize != chunkgeneratorsettings$factory.dirtSize)
{
return false;
}
else if (this.dungeonChance != chunkgeneratorsettings$factory.dungeonChance)
{
return false;
}
else if (this.fixedBiome != chunkgeneratorsettings$factory.fixedBiome)
{
return false;
}
else if (this.goldCount != chunkgeneratorsettings$factory.goldCount)
{
return false;
}
else if (this.goldMaxHeight != chunkgeneratorsettings$factory.goldMaxHeight)
{
return false;
}
else if (this.goldMinHeight != chunkgeneratorsettings$factory.goldMinHeight)
{
return false;
}
else if (this.goldSize != chunkgeneratorsettings$factory.goldSize)
{
return false;
}
else if (this.graniteCount != chunkgeneratorsettings$factory.graniteCount)
{
return false;
}
else if (this.graniteMaxHeight != chunkgeneratorsettings$factory.graniteMaxHeight)
{
return false;
}
else if (this.graniteMinHeight != chunkgeneratorsettings$factory.graniteMinHeight)
{
return false;
}
else if (this.graniteSize != chunkgeneratorsettings$factory.graniteSize)
{
return false;
}
else if (this.gravelCount != chunkgeneratorsettings$factory.gravelCount)
{
return false;
}
else if (this.gravelMaxHeight != chunkgeneratorsettings$factory.gravelMaxHeight)
{
return false;
}
else if (this.gravelMinHeight != chunkgeneratorsettings$factory.gravelMinHeight)
{
return false;
}
else if (this.gravelSize != chunkgeneratorsettings$factory.gravelSize)
{
return false;
}
else if (Float.compare(chunkgeneratorsettings$factory.heightScale, this.heightScale) != 0)
{
return false;
}
else if (this.ironCount != chunkgeneratorsettings$factory.ironCount)
{
return false;
}
else if (this.ironMaxHeight != chunkgeneratorsettings$factory.ironMaxHeight)
{
return false;
}
else if (this.ironMinHeight != chunkgeneratorsettings$factory.ironMinHeight)
{
return false;
}
else if (this.ironSize != chunkgeneratorsettings$factory.ironSize)
{
return false;
}
else if (this.lapisCenterHeight != chunkgeneratorsettings$factory.lapisCenterHeight)
{
return false;
}
else if (this.lapisCount != chunkgeneratorsettings$factory.lapisCount)
{
return false;
}
else if (this.lapisSize != chunkgeneratorsettings$factory.lapisSize)
{
return false;
}
else if (this.lapisSpread != chunkgeneratorsettings$factory.lapisSpread)
{
return false;
}
else if (this.lavaLakeChance != chunkgeneratorsettings$factory.lavaLakeChance)
{
return false;
}
else if (Float.compare(chunkgeneratorsettings$factory.lowerLimitScale, this.lowerLimitScale) != 0)
{
return false;
}
else if (Float.compare(chunkgeneratorsettings$factory.mainNoiseScaleX, this.mainNoiseScaleX) != 0)
{
return false;
}
else if (Float.compare(chunkgeneratorsettings$factory.mainNoiseScaleY, this.mainNoiseScaleY) != 0)
{
return false;
}
else if (Float.compare(chunkgeneratorsettings$factory.mainNoiseScaleZ, this.mainNoiseScaleZ) != 0)
{
return false;
}
else if (this.redstoneCount != chunkgeneratorsettings$factory.redstoneCount)
{
return false;
}
else if (this.redstoneMaxHeight != chunkgeneratorsettings$factory.redstoneMaxHeight)
{
return false;
}
else if (this.redstoneMinHeight != chunkgeneratorsettings$factory.redstoneMinHeight)
{
return false;
}
else if (this.redstoneSize != chunkgeneratorsettings$factory.redstoneSize)
{
return false;
}
else if (this.riverSize != chunkgeneratorsettings$factory.riverSize)
{
return false;
}
else if (this.seaLevel != chunkgeneratorsettings$factory.seaLevel)
{
return false;
}
else if (Float.compare(chunkgeneratorsettings$factory.stretchY, this.stretchY) != 0)
{
return false;
}
else if (Float.compare(chunkgeneratorsettings$factory.upperLimitScale, this.upperLimitScale) != 0)
{
return false;
}
else if (this.useCaves != chunkgeneratorsettings$factory.useCaves)
{
return false;
}
else if (this.useDungeons != chunkgeneratorsettings$factory.useDungeons)
{
return false;
}
else if (this.useLavaLakes != chunkgeneratorsettings$factory.useLavaLakes)
{
return false;
}
else if (this.useLavaOceans != chunkgeneratorsettings$factory.useLavaOceans)
{
return false;
}
else if (this.useMineShafts != chunkgeneratorsettings$factory.useMineShafts)
{
return false;
}
else if (this.useRavines != chunkgeneratorsettings$factory.useRavines)
{
return false;
}
else if (this.useStrongholds != chunkgeneratorsettings$factory.useStrongholds)
{
return false;
}
else if (this.useTemples != chunkgeneratorsettings$factory.useTemples)
{
return false;
}
else if (this.useMonuments != chunkgeneratorsettings$factory.useMonuments)
{
return false;
}
else if (this.useMansions != chunkgeneratorsettings$factory.useMansions)
{
return false;
}
else if (this.useVillages != chunkgeneratorsettings$factory.useVillages)
{
return false;
}
else if (this.useWaterLakes != chunkgeneratorsettings$factory.useWaterLakes)
{
return false;
}
else
{
return this.waterLakeChance == chunkgeneratorsettings$factory.waterLakeChance;
}
}
else
{
return false;
}
}
public int hashCode()
{
int i = this.coordinateScale == 0.0F ? 0 : Float.floatToIntBits(this.coordinateScale);
i = 31 * i + (this.heightScale == 0.0F ? 0 : Float.floatToIntBits(this.heightScale));
i = 31 * i + (this.upperLimitScale == 0.0F ? 0 : Float.floatToIntBits(this.upperLimitScale));
i = 31 * i + (this.lowerLimitScale == 0.0F ? 0 : Float.floatToIntBits(this.lowerLimitScale));
i = 31 * i + (this.depthNoiseScaleX == 0.0F ? 0 : Float.floatToIntBits(this.depthNoiseScaleX));
i = 31 * i + (this.depthNoiseScaleZ == 0.0F ? 0 : Float.floatToIntBits(this.depthNoiseScaleZ));
i = 31 * i + (this.depthNoiseScaleExponent == 0.0F ? 0 : Float.floatToIntBits(this.depthNoiseScaleExponent));
i = 31 * i + (this.mainNoiseScaleX == 0.0F ? 0 : Float.floatToIntBits(this.mainNoiseScaleX));
i = 31 * i + (this.mainNoiseScaleY == 0.0F ? 0 : Float.floatToIntBits(this.mainNoiseScaleY));
i = 31 * i + (this.mainNoiseScaleZ == 0.0F ? 0 : Float.floatToIntBits(this.mainNoiseScaleZ));
i = 31 * i + (this.baseSize == 0.0F ? 0 : Float.floatToIntBits(this.baseSize));
i = 31 * i + (this.stretchY == 0.0F ? 0 : Float.floatToIntBits(this.stretchY));
i = 31 * i + (this.biomeDepthWeight == 0.0F ? 0 : Float.floatToIntBits(this.biomeDepthWeight));
i = 31 * i + (this.biomeDepthOffset == 0.0F ? 0 : Float.floatToIntBits(this.biomeDepthOffset));
i = 31 * i + (this.biomeScaleWeight == 0.0F ? 0 : Float.floatToIntBits(this.biomeScaleWeight));
i = 31 * i + (this.biomeScaleOffset == 0.0F ? 0 : Float.floatToIntBits(this.biomeScaleOffset));
i = 31 * i + this.seaLevel;
i = 31 * i + (this.useCaves ? 1 : 0);
i = 31 * i + (this.useDungeons ? 1 : 0);
i = 31 * i + this.dungeonChance;
i = 31 * i + (this.useStrongholds ? 1 : 0);
i = 31 * i + (this.useVillages ? 1 : 0);
i = 31 * i + (this.useMineShafts ? 1 : 0);
i = 31 * i + (this.useTemples ? 1 : 0);
i = 31 * i + (this.useMonuments ? 1 : 0);
i = 31 * i + (this.useMansions ? 1 : 0);
i = 31 * i + (this.useRavines ? 1 : 0);
i = 31 * i + (this.useWaterLakes ? 1 : 0);
i = 31 * i + this.waterLakeChance;
i = 31 * i + (this.useLavaLakes ? 1 : 0);
i = 31 * i + this.lavaLakeChance;
i = 31 * i + (this.useLavaOceans ? 1 : 0);
i = 31 * i + this.fixedBiome;
i = 31 * i + this.biomeSize;
i = 31 * i + this.riverSize;
i = 31 * i + this.dirtSize;
i = 31 * i + this.dirtCount;
i = 31 * i + this.dirtMinHeight;
i = 31 * i + this.dirtMaxHeight;
i = 31 * i + this.gravelSize;
i = 31 * i + this.gravelCount;
i = 31 * i + this.gravelMinHeight;
i = 31 * i + this.gravelMaxHeight;
i = 31 * i + this.graniteSize;
i = 31 * i + this.graniteCount;
i = 31 * i + this.graniteMinHeight;
i = 31 * i + this.graniteMaxHeight;
i = 31 * i + this.dioriteSize;
i = 31 * i + this.dioriteCount;
i = 31 * i + this.dioriteMinHeight;
i = 31 * i + this.dioriteMaxHeight;
i = 31 * i + this.andesiteSize;
i = 31 * i + this.andesiteCount;
i = 31 * i + this.andesiteMinHeight;
i = 31 * i + this.andesiteMaxHeight;
i = 31 * i + this.coalSize;
i = 31 * i + this.coalCount;
i = 31 * i + this.coalMinHeight;
i = 31 * i + this.coalMaxHeight;
i = 31 * i + this.ironSize;
i = 31 * i + this.ironCount;
i = 31 * i + this.ironMinHeight;
i = 31 * i + this.ironMaxHeight;
i = 31 * i + this.goldSize;
i = 31 * i + this.goldCount;
i = 31 * i + this.goldMinHeight;
i = 31 * i + this.goldMaxHeight;
i = 31 * i + this.redstoneSize;
i = 31 * i + this.redstoneCount;
i = 31 * i + this.redstoneMinHeight;
i = 31 * i + this.redstoneMaxHeight;
i = 31 * i + this.diamondSize;
i = 31 * i + this.diamondCount;
i = 31 * i + this.diamondMinHeight;
i = 31 * i + this.diamondMaxHeight;
i = 31 * i + this.lapisSize;
i = 31 * i + this.lapisCount;
i = 31 * i + this.lapisCenterHeight;
i = 31 * i + this.lapisSpread;
return i;
}
public ChunkGeneratorSettings build()
{
return new ChunkGeneratorSettings(this);
}
}
public static class Serializer implements JsonDeserializer<ChunkGeneratorSettings.Factory>, JsonSerializer<ChunkGeneratorSettings.Factory>
{
public ChunkGeneratorSettings.Factory deserialize(JsonElement p_deserialize_1_, Type p_deserialize_2_, JsonDeserializationContext p_deserialize_3_) throws JsonParseException
{
JsonObject jsonobject = p_deserialize_1_.getAsJsonObject();
ChunkGeneratorSettings.Factory chunkgeneratorsettings$factory = new ChunkGeneratorSettings.Factory();
try
{
chunkgeneratorsettings$factory.coordinateScale = JsonUtils.getFloat(jsonobject, "coordinateScale", chunkgeneratorsettings$factory.coordinateScale);
chunkgeneratorsettings$factory.heightScale = JsonUtils.getFloat(jsonobject, "heightScale", chunkgeneratorsettings$factory.heightScale);
chunkgeneratorsettings$factory.lowerLimitScale = JsonUtils.getFloat(jsonobject, "lowerLimitScale", chunkgeneratorsettings$factory.lowerLimitScale);
chunkgeneratorsettings$factory.upperLimitScale = JsonUtils.getFloat(jsonobject, "upperLimitScale", chunkgeneratorsettings$factory.upperLimitScale);
chunkgeneratorsettings$factory.depthNoiseScaleX = JsonUtils.getFloat(jsonobject, "depthNoiseScaleX", chunkgeneratorsettings$factory.depthNoiseScaleX);
chunkgeneratorsettings$factory.depthNoiseScaleZ = JsonUtils.getFloat(jsonobject, "depthNoiseScaleZ", chunkgeneratorsettings$factory.depthNoiseScaleZ);
chunkgeneratorsettings$factory.depthNoiseScaleExponent = JsonUtils.getFloat(jsonobject, "depthNoiseScaleExponent", chunkgeneratorsettings$factory.depthNoiseScaleExponent);
chunkgeneratorsettings$factory.mainNoiseScaleX = JsonUtils.getFloat(jsonobject, "mainNoiseScaleX", chunkgeneratorsettings$factory.mainNoiseScaleX);
chunkgeneratorsettings$factory.mainNoiseScaleY = JsonUtils.getFloat(jsonobject, "mainNoiseScaleY", chunkgeneratorsettings$factory.mainNoiseScaleY);
chunkgeneratorsettings$factory.mainNoiseScaleZ = JsonUtils.getFloat(jsonobject, "mainNoiseScaleZ", chunkgeneratorsettings$factory.mainNoiseScaleZ);
chunkgeneratorsettings$factory.baseSize = JsonUtils.getFloat(jsonobject, "baseSize", chunkgeneratorsettings$factory.baseSize);
chunkgeneratorsettings$factory.stretchY = JsonUtils.getFloat(jsonobject, "stretchY", chunkgeneratorsettings$factory.stretchY);
chunkgeneratorsettings$factory.biomeDepthWeight = JsonUtils.getFloat(jsonobject, "biomeDepthWeight", chunkgeneratorsettings$factory.biomeDepthWeight);
chunkgeneratorsettings$factory.biomeDepthOffset = JsonUtils.getFloat(jsonobject, "biomeDepthOffset", chunkgeneratorsettings$factory.biomeDepthOffset);
chunkgeneratorsettings$factory.biomeScaleWeight = JsonUtils.getFloat(jsonobject, "biomeScaleWeight", chunkgeneratorsettings$factory.biomeScaleWeight);
chunkgeneratorsettings$factory.biomeScaleOffset = JsonUtils.getFloat(jsonobject, "biomeScaleOffset", chunkgeneratorsettings$factory.biomeScaleOffset);
chunkgeneratorsettings$factory.seaLevel = JsonUtils.getInt(jsonobject, "seaLevel", chunkgeneratorsettings$factory.seaLevel);
chunkgeneratorsettings$factory.useCaves = JsonUtils.getBoolean(jsonobject, "useCaves", chunkgeneratorsettings$factory.useCaves);
chunkgeneratorsettings$factory.useDungeons = JsonUtils.getBoolean(jsonobject, "useDungeons", chunkgeneratorsettings$factory.useDungeons);
chunkgeneratorsettings$factory.dungeonChance = JsonUtils.getInt(jsonobject, "dungeonChance", chunkgeneratorsettings$factory.dungeonChance);
chunkgeneratorsettings$factory.useStrongholds = JsonUtils.getBoolean(jsonobject, "useStrongholds", chunkgeneratorsettings$factory.useStrongholds);
chunkgeneratorsettings$factory.useVillages = JsonUtils.getBoolean(jsonobject, "useVillages", chunkgeneratorsettings$factory.useVillages);
chunkgeneratorsettings$factory.useMineShafts = JsonUtils.getBoolean(jsonobject, "useMineShafts", chunkgeneratorsettings$factory.useMineShafts);
chunkgeneratorsettings$factory.useTemples = JsonUtils.getBoolean(jsonobject, "useTemples", chunkgeneratorsettings$factory.useTemples);
chunkgeneratorsettings$factory.useMonuments = JsonUtils.getBoolean(jsonobject, "useMonuments", chunkgeneratorsettings$factory.useMonuments);
chunkgeneratorsettings$factory.useMansions = JsonUtils.getBoolean(jsonobject, "useMansions", chunkgeneratorsettings$factory.useMansions);
chunkgeneratorsettings$factory.useRavines = JsonUtils.getBoolean(jsonobject, "useRavines", chunkgeneratorsettings$factory.useRavines);
chunkgeneratorsettings$factory.useWaterLakes = JsonUtils.getBoolean(jsonobject, "useWaterLakes", chunkgeneratorsettings$factory.useWaterLakes);
chunkgeneratorsettings$factory.waterLakeChance = JsonUtils.getInt(jsonobject, "waterLakeChance", chunkgeneratorsettings$factory.waterLakeChance);
chunkgeneratorsettings$factory.useLavaLakes = JsonUtils.getBoolean(jsonobject, "useLavaLakes", chunkgeneratorsettings$factory.useLavaLakes);
chunkgeneratorsettings$factory.lavaLakeChance = JsonUtils.getInt(jsonobject, "lavaLakeChance", chunkgeneratorsettings$factory.lavaLakeChance);
chunkgeneratorsettings$factory.useLavaOceans = JsonUtils.getBoolean(jsonobject, "useLavaOceans", chunkgeneratorsettings$factory.useLavaOceans);
chunkgeneratorsettings$factory.fixedBiome = JsonUtils.getInt(jsonobject, "fixedBiome", chunkgeneratorsettings$factory.fixedBiome);
if (chunkgeneratorsettings$factory.fixedBiome < 38 && chunkgeneratorsettings$factory.fixedBiome >= -1)
{
if (chunkgeneratorsettings$factory.fixedBiome >= Biome.getIdForBiome(Biomes.HELL))
{
chunkgeneratorsettings$factory.fixedBiome += 2;
}
}
else
{
chunkgeneratorsettings$factory.fixedBiome = -1;
}
chunkgeneratorsettings$factory.biomeSize = JsonUtils.getInt(jsonobject, "biomeSize", chunkgeneratorsettings$factory.biomeSize);
chunkgeneratorsettings$factory.riverSize = JsonUtils.getInt(jsonobject, "riverSize", chunkgeneratorsettings$factory.riverSize);
chunkgeneratorsettings$factory.dirtSize = JsonUtils.getInt(jsonobject, "dirtSize", chunkgeneratorsettings$factory.dirtSize);
chunkgeneratorsettings$factory.dirtCount = JsonUtils.getInt(jsonobject, "dirtCount", chunkgeneratorsettings$factory.dirtCount);
chunkgeneratorsettings$factory.dirtMinHeight = JsonUtils.getInt(jsonobject, "dirtMinHeight", chunkgeneratorsettings$factory.dirtMinHeight);
chunkgeneratorsettings$factory.dirtMaxHeight = JsonUtils.getInt(jsonobject, "dirtMaxHeight", chunkgeneratorsettings$factory.dirtMaxHeight);
chunkgeneratorsettings$factory.gravelSize = JsonUtils.getInt(jsonobject, "gravelSize", chunkgeneratorsettings$factory.gravelSize);
chunkgeneratorsettings$factory.gravelCount = JsonUtils.getInt(jsonobject, "gravelCount", chunkgeneratorsettings$factory.gravelCount);
chunkgeneratorsettings$factory.gravelMinHeight = JsonUtils.getInt(jsonobject, "gravelMinHeight", chunkgeneratorsettings$factory.gravelMinHeight);
chunkgeneratorsettings$factory.gravelMaxHeight = JsonUtils.getInt(jsonobject, "gravelMaxHeight", chunkgeneratorsettings$factory.gravelMaxHeight);
chunkgeneratorsettings$factory.graniteSize = JsonUtils.getInt(jsonobject, "graniteSize", chunkgeneratorsettings$factory.graniteSize);
chunkgeneratorsettings$factory.graniteCount = JsonUtils.getInt(jsonobject, "graniteCount", chunkgeneratorsettings$factory.graniteCount);
chunkgeneratorsettings$factory.graniteMinHeight = JsonUtils.getInt(jsonobject, "graniteMinHeight", chunkgeneratorsettings$factory.graniteMinHeight);
chunkgeneratorsettings$factory.graniteMaxHeight = JsonUtils.getInt(jsonobject, "graniteMaxHeight", chunkgeneratorsettings$factory.graniteMaxHeight);
chunkgeneratorsettings$factory.dioriteSize = JsonUtils.getInt(jsonobject, "dioriteSize", chunkgeneratorsettings$factory.dioriteSize);
chunkgeneratorsettings$factory.dioriteCount = JsonUtils.getInt(jsonobject, "dioriteCount", chunkgeneratorsettings$factory.dioriteCount);
chunkgeneratorsettings$factory.dioriteMinHeight = JsonUtils.getInt(jsonobject, "dioriteMinHeight", chunkgeneratorsettings$factory.dioriteMinHeight);
chunkgeneratorsettings$factory.dioriteMaxHeight = JsonUtils.getInt(jsonobject, "dioriteMaxHeight", chunkgeneratorsettings$factory.dioriteMaxHeight);
chunkgeneratorsettings$factory.andesiteSize = JsonUtils.getInt(jsonobject, "andesiteSize", chunkgeneratorsettings$factory.andesiteSize);
chunkgeneratorsettings$factory.andesiteCount = JsonUtils.getInt(jsonobject, "andesiteCount", chunkgeneratorsettings$factory.andesiteCount);
chunkgeneratorsettings$factory.andesiteMinHeight = JsonUtils.getInt(jsonobject, "andesiteMinHeight", chunkgeneratorsettings$factory.andesiteMinHeight);
chunkgeneratorsettings$factory.andesiteMaxHeight = JsonUtils.getInt(jsonobject, "andesiteMaxHeight", chunkgeneratorsettings$factory.andesiteMaxHeight);
chunkgeneratorsettings$factory.coalSize = JsonUtils.getInt(jsonobject, "coalSize", chunkgeneratorsettings$factory.coalSize);
chunkgeneratorsettings$factory.coalCount = JsonUtils.getInt(jsonobject, "coalCount", chunkgeneratorsettings$factory.coalCount);
chunkgeneratorsettings$factory.coalMinHeight = JsonUtils.getInt(jsonobject, "coalMinHeight", chunkgeneratorsettings$factory.coalMinHeight);
chunkgeneratorsettings$factory.coalMaxHeight = JsonUtils.getInt(jsonobject, "coalMaxHeight", chunkgeneratorsettings$factory.coalMaxHeight);
chunkgeneratorsettings$factory.ironSize = JsonUtils.getInt(jsonobject, "ironSize", chunkgeneratorsettings$factory.ironSize);
chunkgeneratorsettings$factory.ironCount = JsonUtils.getInt(jsonobject, "ironCount", chunkgeneratorsettings$factory.ironCount);
chunkgeneratorsettings$factory.ironMinHeight = JsonUtils.getInt(jsonobject, "ironMinHeight", chunkgeneratorsettings$factory.ironMinHeight);
chunkgeneratorsettings$factory.ironMaxHeight = JsonUtils.getInt(jsonobject, "ironMaxHeight", chunkgeneratorsettings$factory.ironMaxHeight);
chunkgeneratorsettings$factory.goldSize = JsonUtils.getInt(jsonobject, "goldSize", chunkgeneratorsettings$factory.goldSize);
chunkgeneratorsettings$factory.goldCount = JsonUtils.getInt(jsonobject, "goldCount", chunkgeneratorsettings$factory.goldCount);
chunkgeneratorsettings$factory.goldMinHeight = JsonUtils.getInt(jsonobject, "goldMinHeight", chunkgeneratorsettings$factory.goldMinHeight);
chunkgeneratorsettings$factory.goldMaxHeight = JsonUtils.getInt(jsonobject, "goldMaxHeight", chunkgeneratorsettings$factory.goldMaxHeight);
chunkgeneratorsettings$factory.redstoneSize = JsonUtils.getInt(jsonobject, "redstoneSize", chunkgeneratorsettings$factory.redstoneSize);
chunkgeneratorsettings$factory.redstoneCount = JsonUtils.getInt(jsonobject, "redstoneCount", chunkgeneratorsettings$factory.redstoneCount);
chunkgeneratorsettings$factory.redstoneMinHeight = JsonUtils.getInt(jsonobject, "redstoneMinHeight", chunkgeneratorsettings$factory.redstoneMinHeight);
chunkgeneratorsettings$factory.redstoneMaxHeight = JsonUtils.getInt(jsonobject, "redstoneMaxHeight", chunkgeneratorsettings$factory.redstoneMaxHeight);
chunkgeneratorsettings$factory.diamondSize = JsonUtils.getInt(jsonobject, "diamondSize", chunkgeneratorsettings$factory.diamondSize);
chunkgeneratorsettings$factory.diamondCount = JsonUtils.getInt(jsonobject, "diamondCount", chunkgeneratorsettings$factory.diamondCount);
chunkgeneratorsettings$factory.diamondMinHeight = JsonUtils.getInt(jsonobject, "diamondMinHeight", chunkgeneratorsettings$factory.diamondMinHeight);
chunkgeneratorsettings$factory.diamondMaxHeight = JsonUtils.getInt(jsonobject, "diamondMaxHeight", chunkgeneratorsettings$factory.diamondMaxHeight);
chunkgeneratorsettings$factory.lapisSize = JsonUtils.getInt(jsonobject, "lapisSize", chunkgeneratorsettings$factory.lapisSize);
chunkgeneratorsettings$factory.lapisCount = JsonUtils.getInt(jsonobject, "lapisCount", chunkgeneratorsettings$factory.lapisCount);
chunkgeneratorsettings$factory.lapisCenterHeight = JsonUtils.getInt(jsonobject, "lapisCenterHeight", chunkgeneratorsettings$factory.lapisCenterHeight);
chunkgeneratorsettings$factory.lapisSpread = JsonUtils.getInt(jsonobject, "lapisSpread", chunkgeneratorsettings$factory.lapisSpread);
}
catch (Exception var7)
{
;
}
return chunkgeneratorsettings$factory;
}
public JsonElement serialize(ChunkGeneratorSettings.Factory p_serialize_1_, Type p_serialize_2_, JsonSerializationContext p_serialize_3_)
{
JsonObject jsonobject = new JsonObject();
jsonobject.addProperty("coordinateScale", Float.valueOf(p_serialize_1_.coordinateScale));
jsonobject.addProperty("heightScale", Float.valueOf(p_serialize_1_.heightScale));
jsonobject.addProperty("lowerLimitScale", Float.valueOf(p_serialize_1_.lowerLimitScale));
jsonobject.addProperty("upperLimitScale", Float.valueOf(p_serialize_1_.upperLimitScale));
jsonobject.addProperty("depthNoiseScaleX", Float.valueOf(p_serialize_1_.depthNoiseScaleX));
jsonobject.addProperty("depthNoiseScaleZ", Float.valueOf(p_serialize_1_.depthNoiseScaleZ));
jsonobject.addProperty("depthNoiseScaleExponent", Float.valueOf(p_serialize_1_.depthNoiseScaleExponent));
jsonobject.addProperty("mainNoiseScaleX", Float.valueOf(p_serialize_1_.mainNoiseScaleX));
jsonobject.addProperty("mainNoiseScaleY", Float.valueOf(p_serialize_1_.mainNoiseScaleY));
jsonobject.addProperty("mainNoiseScaleZ", Float.valueOf(p_serialize_1_.mainNoiseScaleZ));
jsonobject.addProperty("baseSize", Float.valueOf(p_serialize_1_.baseSize));
jsonobject.addProperty("stretchY", Float.valueOf(p_serialize_1_.stretchY));
jsonobject.addProperty("biomeDepthWeight", Float.valueOf(p_serialize_1_.biomeDepthWeight));
jsonobject.addProperty("biomeDepthOffset", Float.valueOf(p_serialize_1_.biomeDepthOffset));
jsonobject.addProperty("biomeScaleWeight", Float.valueOf(p_serialize_1_.biomeScaleWeight));
jsonobject.addProperty("biomeScaleOffset", Float.valueOf(p_serialize_1_.biomeScaleOffset));
jsonobject.addProperty("seaLevel", Integer.valueOf(p_serialize_1_.seaLevel));
jsonobject.addProperty("useCaves", Boolean.valueOf(p_serialize_1_.useCaves));
jsonobject.addProperty("useDungeons", Boolean.valueOf(p_serialize_1_.useDungeons));
jsonobject.addProperty("dungeonChance", Integer.valueOf(p_serialize_1_.dungeonChance));
jsonobject.addProperty("useStrongholds", Boolean.valueOf(p_serialize_1_.useStrongholds));
jsonobject.addProperty("useVillages", Boolean.valueOf(p_serialize_1_.useVillages));
jsonobject.addProperty("useMineShafts", Boolean.valueOf(p_serialize_1_.useMineShafts));
jsonobject.addProperty("useTemples", Boolean.valueOf(p_serialize_1_.useTemples));
jsonobject.addProperty("useMonuments", Boolean.valueOf(p_serialize_1_.useMonuments));
jsonobject.addProperty("useMansions", Boolean.valueOf(p_serialize_1_.useMansions));
jsonobject.addProperty("useRavines", Boolean.valueOf(p_serialize_1_.useRavines));
jsonobject.addProperty("useWaterLakes", Boolean.valueOf(p_serialize_1_.useWaterLakes));
jsonobject.addProperty("waterLakeChance", Integer.valueOf(p_serialize_1_.waterLakeChance));
jsonobject.addProperty("useLavaLakes", Boolean.valueOf(p_serialize_1_.useLavaLakes));
jsonobject.addProperty("lavaLakeChance", Integer.valueOf(p_serialize_1_.lavaLakeChance));
jsonobject.addProperty("useLavaOceans", Boolean.valueOf(p_serialize_1_.useLavaOceans));
jsonobject.addProperty("fixedBiome", Integer.valueOf(p_serialize_1_.fixedBiome));
jsonobject.addProperty("biomeSize", Integer.valueOf(p_serialize_1_.biomeSize));
jsonobject.addProperty("riverSize", Integer.valueOf(p_serialize_1_.riverSize));
jsonobject.addProperty("dirtSize", Integer.valueOf(p_serialize_1_.dirtSize));
jsonobject.addProperty("dirtCount", Integer.valueOf(p_serialize_1_.dirtCount));
jsonobject.addProperty("dirtMinHeight", Integer.valueOf(p_serialize_1_.dirtMinHeight));
jsonobject.addProperty("dirtMaxHeight", Integer.valueOf(p_serialize_1_.dirtMaxHeight));
jsonobject.addProperty("gravelSize", Integer.valueOf(p_serialize_1_.gravelSize));
jsonobject.addProperty("gravelCount", Integer.valueOf(p_serialize_1_.gravelCount));
jsonobject.addProperty("gravelMinHeight", Integer.valueOf(p_serialize_1_.gravelMinHeight));
jsonobject.addProperty("gravelMaxHeight", Integer.valueOf(p_serialize_1_.gravelMaxHeight));
jsonobject.addProperty("graniteSize", Integer.valueOf(p_serialize_1_.graniteSize));
jsonobject.addProperty("graniteCount", Integer.valueOf(p_serialize_1_.graniteCount));
jsonobject.addProperty("graniteMinHeight", Integer.valueOf(p_serialize_1_.graniteMinHeight));
jsonobject.addProperty("graniteMaxHeight", Integer.valueOf(p_serialize_1_.graniteMaxHeight));
jsonobject.addProperty("dioriteSize", Integer.valueOf(p_serialize_1_.dioriteSize));
jsonobject.addProperty("dioriteCount", Integer.valueOf(p_serialize_1_.dioriteCount));
jsonobject.addProperty("dioriteMinHeight", Integer.valueOf(p_serialize_1_.dioriteMinHeight));
jsonobject.addProperty("dioriteMaxHeight", Integer.valueOf(p_serialize_1_.dioriteMaxHeight));
jsonobject.addProperty("andesiteSize", Integer.valueOf(p_serialize_1_.andesiteSize));
jsonobject.addProperty("andesiteCount", Integer.valueOf(p_serialize_1_.andesiteCount));
jsonobject.addProperty("andesiteMinHeight", Integer.valueOf(p_serialize_1_.andesiteMinHeight));
jsonobject.addProperty("andesiteMaxHeight", Integer.valueOf(p_serialize_1_.andesiteMaxHeight));
jsonobject.addProperty("coalSize", Integer.valueOf(p_serialize_1_.coalSize));
jsonobject.addProperty("coalCount", Integer.valueOf(p_serialize_1_.coalCount));
jsonobject.addProperty("coalMinHeight", Integer.valueOf(p_serialize_1_.coalMinHeight));
jsonobject.addProperty("coalMaxHeight", Integer.valueOf(p_serialize_1_.coalMaxHeight));
jsonobject.addProperty("ironSize", Integer.valueOf(p_serialize_1_.ironSize));
jsonobject.addProperty("ironCount", Integer.valueOf(p_serialize_1_.ironCount));
jsonobject.addProperty("ironMinHeight", Integer.valueOf(p_serialize_1_.ironMinHeight));
jsonobject.addProperty("ironMaxHeight", Integer.valueOf(p_serialize_1_.ironMaxHeight));
jsonobject.addProperty("goldSize", Integer.valueOf(p_serialize_1_.goldSize));
jsonobject.addProperty("goldCount", Integer.valueOf(p_serialize_1_.goldCount));
jsonobject.addProperty("goldMinHeight", Integer.valueOf(p_serialize_1_.goldMinHeight));
jsonobject.addProperty("goldMaxHeight", Integer.valueOf(p_serialize_1_.goldMaxHeight));
jsonobject.addProperty("redstoneSize", Integer.valueOf(p_serialize_1_.redstoneSize));
jsonobject.addProperty("redstoneCount", Integer.valueOf(p_serialize_1_.redstoneCount));
jsonobject.addProperty("redstoneMinHeight", Integer.valueOf(p_serialize_1_.redstoneMinHeight));
jsonobject.addProperty("redstoneMaxHeight", Integer.valueOf(p_serialize_1_.redstoneMaxHeight));
jsonobject.addProperty("diamondSize", Integer.valueOf(p_serialize_1_.diamondSize));
jsonobject.addProperty("diamondCount", Integer.valueOf(p_serialize_1_.diamondCount));
jsonobject.addProperty("diamondMinHeight", Integer.valueOf(p_serialize_1_.diamondMinHeight));
jsonobject.addProperty("diamondMaxHeight", Integer.valueOf(p_serialize_1_.diamondMaxHeight));
jsonobject.addProperty("lapisSize", Integer.valueOf(p_serialize_1_.lapisSize));
jsonobject.addProperty("lapisCount", Integer.valueOf(p_serialize_1_.lapisCount));
jsonobject.addProperty("lapisCenterHeight", Integer.valueOf(p_serialize_1_.lapisCenterHeight));
jsonobject.addProperty("lapisSpread", Integer.valueOf(p_serialize_1_.lapisSpread));
return jsonobject;
}
}
}

View File

@@ -0,0 +1,354 @@
package net.minecraft.world.gen;
import com.google.common.collect.Lists;
import com.google.common.collect.Sets;
import it.unimi.dsi.fastutil.longs.Long2ObjectMap;
import it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap;
import it.unimi.dsi.fastutil.objects.ObjectIterator;
import java.io.IOException;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
import javax.annotation.Nullable;
import net.minecraft.crash.CrashReport;
import net.minecraft.crash.CrashReportCategory;
import net.minecraft.entity.EnumCreatureType;
import net.minecraft.util.ReportedException;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.ChunkPos;
import net.minecraft.world.MinecraftException;
import net.minecraft.world.World;
import net.minecraft.world.WorldServer;
import net.minecraft.world.biome.Biome;
import net.minecraft.world.chunk.Chunk;
import net.minecraft.world.chunk.IChunkProvider;
import net.minecraft.world.chunk.storage.IChunkLoader;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
public class ChunkProviderServer implements IChunkProvider
{
private static final Logger LOGGER = LogManager.getLogger();
private final Set<Long> droppedChunksSet = Sets.<Long>newHashSet();
public final IChunkGenerator chunkGenerator;
public final IChunkLoader chunkLoader;
/** map of chunk Id's to Chunk instances */
public final Long2ObjectMap<Chunk> id2ChunkMap = new Long2ObjectOpenHashMap<Chunk>(8192);
public final WorldServer world;
private final Set<Long> loadingChunks = com.google.common.collect.Sets.newHashSet();
public ChunkProviderServer(WorldServer worldObjIn, IChunkLoader chunkLoaderIn, IChunkGenerator chunkGeneratorIn)
{
this.world = worldObjIn;
this.chunkLoader = chunkLoaderIn;
this.chunkGenerator = chunkGeneratorIn;
}
public Collection<Chunk> getLoadedChunks()
{
return this.id2ChunkMap.values();
}
/**
* Marks the chunk for unload if the {@link WorldProvider} allows it.
*
* Queueing a chunk for unload does <b>not</b> guarantee that it will be unloaded, as any request for the chunk will
* unqueue the chunk.
*/
public void queueUnload(Chunk chunkIn)
{
if (this.world.provider.canDropChunk(chunkIn.x, chunkIn.z))
{
this.droppedChunksSet.add(Long.valueOf(ChunkPos.asLong(chunkIn.x, chunkIn.z)));
chunkIn.unloadQueued = true;
}
}
/**
* Marks all chunks for unload
*
* @see #queueUnload(Chunk)
*/
public void queueUnloadAll()
{
ObjectIterator objectiterator = this.id2ChunkMap.values().iterator();
while (objectiterator.hasNext())
{
Chunk chunk = (Chunk)objectiterator.next();
this.queueUnload(chunk);
}
}
@Nullable
public Chunk getLoadedChunk(int x, int z)
{
long i = ChunkPos.asLong(x, z);
Chunk chunk = (Chunk)this.id2ChunkMap.get(i);
if (chunk != null)
{
chunk.unloadQueued = false;
}
return chunk;
}
@Nullable
public Chunk loadChunk(int x, int z)
{
return loadChunk(x, z, null);
}
@Nullable
public Chunk loadChunk(int x, int z, @Nullable Runnable runnable)
{
Chunk chunk = this.getLoadedChunk(x, z);
if (chunk == null)
{
long pos = ChunkPos.asLong(x, z);
chunk = net.minecraftforge.common.ForgeChunkManager.fetchDormantChunk(pos, this.world);
if (chunk != null || !(this.chunkLoader instanceof net.minecraft.world.chunk.storage.AnvilChunkLoader))
{
if (!loadingChunks.add(pos)) net.minecraftforge.fml.common.FMLLog.bigWarning("There is an attempt to load a chunk ({},{}) in dimension {} that is already being loaded. This will cause weird chunk breakages.", x, z, this.world.provider.getDimension());
if (chunk == null) chunk = this.loadChunkFromFile(x, z);
if (chunk != null)
{
this.id2ChunkMap.put(ChunkPos.asLong(x, z), chunk);
chunk.onLoad();
chunk.populate(this, this.chunkGenerator);
}
loadingChunks.remove(pos);
}
else
{
net.minecraft.world.chunk.storage.AnvilChunkLoader loader = (net.minecraft.world.chunk.storage.AnvilChunkLoader) this.chunkLoader;
if (runnable == null || !net.minecraftforge.common.ForgeChunkManager.asyncChunkLoading)
chunk = net.minecraftforge.common.chunkio.ChunkIOExecutor.syncChunkLoad(this.world, loader, this, x, z);
else if (loader.isChunkGeneratedAt(x, z))
{
// We can only use the async queue for already generated chunks
net.minecraftforge.common.chunkio.ChunkIOExecutor.queueChunkLoad(this.world, loader, this, x, z, runnable);
return null;
}
}
}
// If we didn't load the chunk async and have a callback run it now
if (runnable != null) runnable.run();
return chunk;
}
public Chunk provideChunk(int x, int z)
{
Chunk chunk = this.loadChunk(x, z);
if (chunk == null)
{
long i = ChunkPos.asLong(x, z);
try
{
chunk = this.chunkGenerator.generateChunk(x, z);
}
catch (Throwable throwable)
{
CrashReport crashreport = CrashReport.makeCrashReport(throwable, "Exception generating new chunk");
CrashReportCategory crashreportcategory = crashreport.makeCategory("Chunk to be generated");
crashreportcategory.addCrashSection("Location", String.format("%d,%d", x, z));
crashreportcategory.addCrashSection("Position hash", Long.valueOf(i));
crashreportcategory.addCrashSection("Generator", this.chunkGenerator);
throw new ReportedException(crashreport);
}
this.id2ChunkMap.put(i, chunk);
chunk.onLoad();
chunk.populate(this, this.chunkGenerator);
}
return chunk;
}
@Nullable
private Chunk loadChunkFromFile(int x, int z)
{
try
{
Chunk chunk = this.chunkLoader.loadChunk(this.world, x, z);
if (chunk != null)
{
chunk.setLastSaveTime(this.world.getTotalWorldTime());
this.chunkGenerator.recreateStructures(chunk, x, z);
}
return chunk;
}
catch (Exception exception)
{
LOGGER.error("Couldn't load chunk", (Throwable)exception);
return null;
}
}
private void saveChunkExtraData(Chunk chunkIn)
{
try
{
this.chunkLoader.saveExtraChunkData(this.world, chunkIn);
}
catch (Exception exception)
{
LOGGER.error("Couldn't save entities", (Throwable)exception);
}
}
private void saveChunkData(Chunk chunkIn)
{
try
{
chunkIn.setLastSaveTime(this.world.getTotalWorldTime());
this.chunkLoader.saveChunk(this.world, chunkIn);
}
catch (IOException ioexception)
{
LOGGER.error("Couldn't save chunk", (Throwable)ioexception);
}
catch (MinecraftException minecraftexception)
{
LOGGER.error("Couldn't save chunk; already in use by another instance of Minecraft?", (Throwable)minecraftexception);
}
}
public boolean saveChunks(boolean all)
{
int i = 0;
List<Chunk> list = Lists.newArrayList(this.id2ChunkMap.values());
for (int j = 0; j < list.size(); ++j)
{
Chunk chunk = list.get(j);
if (all)
{
this.saveChunkExtraData(chunk);
}
if (chunk.needsSaving(all))
{
this.saveChunkData(chunk);
chunk.setModified(false);
++i;
if (i == 24 && !all)
{
return false;
}
}
}
return true;
}
/**
* Flushes all pending chunks fully back to disk
*/
public void flushToDisk()
{
this.chunkLoader.flush();
}
/**
* Unloads chunks that are marked to be unloaded. This is not guaranteed to unload every such chunk.
*/
public boolean tick()
{
if (!this.world.disableLevelSaving)
{
if (!this.droppedChunksSet.isEmpty())
{
for (ChunkPos forced : this.world.getPersistentChunks().keySet())
{
this.droppedChunksSet.remove(ChunkPos.asLong(forced.x, forced.z));
}
Iterator<Long> iterator = this.droppedChunksSet.iterator();
for (int i = 0; i < 100 && iterator.hasNext(); iterator.remove())
{
Long olong = iterator.next();
Chunk chunk = (Chunk)this.id2ChunkMap.get(olong);
if (chunk != null && chunk.unloadQueued)
{
chunk.onUnload();
net.minecraftforge.common.ForgeChunkManager.putDormantChunk(ChunkPos.asLong(chunk.x, chunk.z), chunk);
this.saveChunkData(chunk);
this.saveChunkExtraData(chunk);
this.id2ChunkMap.remove(olong);
++i;
}
}
}
if (this.id2ChunkMap.isEmpty()) net.minecraftforge.common.DimensionManager.unloadWorld(this.world.provider.getDimension());
this.chunkLoader.chunkTick();
}
return false;
}
/**
* Returns if the IChunkProvider supports saving.
*/
public boolean canSave()
{
return !this.world.disableLevelSaving;
}
/**
* Converts the instance data to a readable string.
*/
public String makeString()
{
return "ServerChunkCache: " + this.id2ChunkMap.size() + " Drop: " + this.droppedChunksSet.size();
}
public List<Biome.SpawnListEntry> getPossibleCreatures(EnumCreatureType creatureType, BlockPos pos)
{
return this.chunkGenerator.getPossibleCreatures(creatureType, pos);
}
@Nullable
public BlockPos getNearestStructurePos(World worldIn, String structureName, BlockPos position, boolean findUnexplored)
{
return this.chunkGenerator.getNearestStructurePos(worldIn, structureName, position, findUnexplored);
}
public boolean isInsideStructure(World worldIn, String structureName, BlockPos pos)
{
return this.chunkGenerator.isInsideStructure(worldIn, structureName, pos);
}
public int getLoadedChunkCount()
{
return this.id2ChunkMap.size();
}
/**
* Checks to see if a chunk exists at x, z
*/
public boolean chunkExists(int x, int z)
{
return this.id2ChunkMap.containsKey(ChunkPos.asLong(x, z));
}
public boolean isChunkGeneratedAt(int x, int z)
{
return this.id2ChunkMap.containsKey(ChunkPos.asLong(x, z)) || this.chunkLoader.isChunkGeneratedAt(x, z);
}
}

View File

@@ -0,0 +1,338 @@
package net.minecraft.world.gen;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Map.Entry;
import net.minecraft.block.Block;
import net.minecraft.init.Biomes;
import net.minecraft.init.Blocks;
import net.minecraft.util.math.MathHelper;
import net.minecraft.world.biome.Biome;
public class FlatGeneratorInfo
{
/** List of layers on this preset. */
private final List<FlatLayerInfo> flatLayers = Lists.<FlatLayerInfo>newArrayList();
/** List of world features enabled on this preset. */
private final Map<String, Map<String, String>> worldFeatures = Maps.<String, Map<String, String>>newHashMap();
private int biomeToUse;
/**
* Return the biome used on this preset.
*/
public int getBiome()
{
return this.biomeToUse;
}
/**
* Set the biome used on this preset.
*/
public void setBiome(int biome)
{
this.biomeToUse = biome;
}
/**
* Return the list of world features enabled on this preset.
*/
public Map<String, Map<String, String>> getWorldFeatures()
{
return this.worldFeatures;
}
/**
* Return the list of layers on this preset.
*/
public List<FlatLayerInfo> getFlatLayers()
{
return this.flatLayers;
}
public void updateLayers()
{
int i = 0;
for (FlatLayerInfo flatlayerinfo : this.flatLayers)
{
flatlayerinfo.setMinY(i);
i += flatlayerinfo.getLayerCount();
}
}
public String toString()
{
StringBuilder stringbuilder = new StringBuilder();
stringbuilder.append((int)3);
stringbuilder.append(";");
for (int i = 0; i < this.flatLayers.size(); ++i)
{
if (i > 0)
{
stringbuilder.append(",");
}
stringbuilder.append(this.flatLayers.get(i));
}
stringbuilder.append(";");
stringbuilder.append(this.biomeToUse);
if (this.worldFeatures.isEmpty())
{
stringbuilder.append(";");
}
else
{
stringbuilder.append(";");
int k = 0;
for (Entry<String, Map<String, String>> entry : this.worldFeatures.entrySet())
{
if (k++ > 0)
{
stringbuilder.append(",");
}
stringbuilder.append(((String)entry.getKey()).toLowerCase(Locale.ROOT));
Map<String, String> map = (Map)entry.getValue();
if (!map.isEmpty())
{
stringbuilder.append("(");
int j = 0;
for (Entry<String, String> entry1 : map.entrySet())
{
if (j++ > 0)
{
stringbuilder.append(" ");
}
stringbuilder.append(entry1.getKey());
stringbuilder.append("=");
stringbuilder.append(entry1.getValue());
}
stringbuilder.append(")");
}
}
}
return stringbuilder.toString();
}
private static FlatLayerInfo getLayerFromString(int p_180715_0_, String p_180715_1_, int p_180715_2_)
{
String[] astring = p_180715_0_ >= 3 ? p_180715_1_.split("\\*", 2) : p_180715_1_.split("x", 2);
int i = 1;
int j = 0;
if (astring.length == 2)
{
try
{
i = Integer.parseInt(astring[0]);
if (p_180715_2_ + i >= 256)
{
i = 256 - p_180715_2_;
}
if (i < 0)
{
i = 0;
}
}
catch (Throwable var8)
{
return null;
}
}
Block block;
try
{
String s = astring[astring.length - 1];
if (p_180715_0_ < 3)
{
astring = s.split(":", 2);
if (astring.length > 1)
{
j = Integer.parseInt(astring[1]);
}
block = Block.getBlockById(Integer.parseInt(astring[0]));
}
else
{
astring = s.split(":", 3);
block = astring.length > 1 ? Block.getBlockFromName(astring[0] + ":" + astring[1]) : null;
if (block != null)
{
j = astring.length > 2 ? Integer.parseInt(astring[2]) : 0;
}
else
{
block = Block.getBlockFromName(astring[0]);
if (block != null)
{
j = astring.length > 1 ? Integer.parseInt(astring[1]) : 0;
}
}
if (block == null)
{
return null;
}
}
if (block == Blocks.AIR)
{
j = 0;
}
if (j < 0 || j > 15)
{
j = 0;
}
}
catch (Throwable var9)
{
return null;
}
FlatLayerInfo flatlayerinfo = new FlatLayerInfo(p_180715_0_, i, block, j);
flatlayerinfo.setMinY(p_180715_2_);
return flatlayerinfo;
}
private static List<FlatLayerInfo> getLayersFromString(int p_180716_0_, String p_180716_1_)
{
if (p_180716_1_ != null && p_180716_1_.length() >= 1)
{
List<FlatLayerInfo> list = Lists.<FlatLayerInfo>newArrayList();
String[] astring = p_180716_1_.split(",");
int i = 0;
for (String s : astring)
{
FlatLayerInfo flatlayerinfo = getLayerFromString(p_180716_0_, s, i);
if (flatlayerinfo == null)
{
return null;
}
list.add(flatlayerinfo);
i += flatlayerinfo.getLayerCount();
}
return list;
}
else
{
return null;
}
}
public static FlatGeneratorInfo createFlatGeneratorFromString(String flatGeneratorSettings)
{
if (flatGeneratorSettings == null)
{
return getDefaultFlatGenerator();
}
else
{
String[] astring = flatGeneratorSettings.split(";", -1);
int i = astring.length == 1 ? 0 : MathHelper.getInt(astring[0], 0);
if (i >= 0 && i <= 3)
{
FlatGeneratorInfo flatgeneratorinfo = new FlatGeneratorInfo();
int j = astring.length == 1 ? 0 : 1;
List<FlatLayerInfo> list = getLayersFromString(i, astring[j++]);
if (list != null && !list.isEmpty())
{
flatgeneratorinfo.getFlatLayers().addAll(list);
flatgeneratorinfo.updateLayers();
int k = Biome.getIdForBiome(Biomes.PLAINS);
if (i > 0 && astring.length > j)
{
k = MathHelper.getInt(astring[j++], k);
}
flatgeneratorinfo.setBiome(k);
if (i > 0 && astring.length > j)
{
String[] astring1 = astring[j++].toLowerCase(Locale.ROOT).split(",");
for (String s : astring1)
{
String[] astring2 = s.split("\\(", 2);
Map<String, String> map = Maps.<String, String>newHashMap();
if (!astring2[0].isEmpty())
{
flatgeneratorinfo.getWorldFeatures().put(astring2[0], map);
if (astring2.length > 1 && astring2[1].endsWith(")") && astring2[1].length() > 1)
{
String[] astring3 = astring2[1].substring(0, astring2[1].length() - 1).split(" ");
for (String s1 : astring3)
{
String[] astring4 = s1.split("=", 2);
if (astring4.length == 2)
{
map.put(astring4[0], astring4[1]);
}
}
}
}
}
}
else
{
flatgeneratorinfo.getWorldFeatures().put("village", Maps.newHashMap());
}
return flatgeneratorinfo;
}
else
{
return getDefaultFlatGenerator();
}
}
else
{
return getDefaultFlatGenerator();
}
}
}
public static FlatGeneratorInfo getDefaultFlatGenerator()
{
FlatGeneratorInfo flatgeneratorinfo = new FlatGeneratorInfo();
flatgeneratorinfo.setBiome(Biome.getIdForBiome(Biomes.PLAINS));
flatgeneratorinfo.getFlatLayers().add(new FlatLayerInfo(1, Blocks.BEDROCK));
flatgeneratorinfo.getFlatLayers().add(new FlatLayerInfo(2, Blocks.DIRT));
flatgeneratorinfo.getFlatLayers().add(new FlatLayerInfo(1, Blocks.GRASS));
flatgeneratorinfo.updateLayers();
flatgeneratorinfo.getWorldFeatures().put("village", Maps.newHashMap());
return flatgeneratorinfo;
}
}

Some files were not shown because too many files have changed in this diff Show More