base mod created
This commit is contained in:
123
build/tmp/recompileMc/sources/net/minecraft/world/BossInfo.java
Normal file
123
build/tmp/recompileMc/sources/net/minecraft/world/BossInfo.java
Normal 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;
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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];
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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_);
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
297
build/tmp/recompileMc/sources/net/minecraft/world/Explosion.java
Normal file
297
build/tmp/recompileMc/sources/net/minecraft/world/Explosion.java
Normal 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; }
|
||||
}
|
||||
208
build/tmp/recompileMc/sources/net/minecraft/world/GameRules.java
Normal file
208
build/tmp/recompileMc/sources/net/minecraft/world/GameRules.java
Normal 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;
|
||||
}
|
||||
}
|
||||
137
build/tmp/recompileMc/sources/net/minecraft/world/GameType.java
Normal file
137
build/tmp/recompileMc/sources/net/minecraft/world/GameType.java
Normal 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;
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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();
|
||||
}
|
||||
@@ -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();
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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();
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
package net.minecraft.world;
|
||||
|
||||
public class MinecraftException extends Exception
|
||||
{
|
||||
public MinecraftException(String msg)
|
||||
{
|
||||
super(msg);
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
4387
build/tmp/recompileMc/sources/net/minecraft/world/World.java
Normal file
4387
build/tmp/recompileMc/sources/net/minecraft/world/World.java
Normal file
File diff suppressed because it is too large
Load Diff
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
1463
build/tmp/recompileMc/sources/net/minecraft/world/WorldServer.java
Normal file
1463
build/tmp/recompileMc/sources/net/minecraft/world/WorldServer.java
Normal file
File diff suppressed because it is too large
Load Diff
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
296
build/tmp/recompileMc/sources/net/minecraft/world/WorldType.java
Normal file
296
build/tmp/recompileMc/sources/net/minecraft/world/WorldType.java
Normal 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;
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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];
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
@@ -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)
|
||||
{
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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));
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
package net.minecraft.world.biome;
|
||||
|
||||
public class BiomeRiver extends Biome
|
||||
{
|
||||
public BiomeRiver(Biome.BiomeProperties properties)
|
||||
{
|
||||
super(properties);
|
||||
this.spawnableCreatureList.clear();
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
// Auto generated package-info by MCP
|
||||
@ParametersAreNonnullByDefault
|
||||
@MethodsReturnNonnullByDefault
|
||||
package net.minecraft.world.biome;
|
||||
|
||||
import mcp.MethodsReturnNonnullByDefault;
|
||||
import javax.annotation.ParametersAreNonnullByDefault;
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
// Auto generated package-info by MCP
|
||||
@ParametersAreNonnullByDefault
|
||||
@MethodsReturnNonnullByDefault
|
||||
package net.minecraft.world.border;
|
||||
|
||||
import mcp.MethodsReturnNonnullByDefault;
|
||||
import javax.annotation.ParametersAreNonnullByDefault;
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
1668
build/tmp/recompileMc/sources/net/minecraft/world/chunk/Chunk.java
Normal file
1668
build/tmp/recompileMc/sources/net/minecraft/world/chunk/Chunk.java
Normal file
File diff suppressed because it is too large
Load Diff
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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();
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
package net.minecraft.world.chunk;
|
||||
|
||||
import net.minecraft.block.state.IBlockState;
|
||||
|
||||
interface IBlockStatePaletteResizer
|
||||
{
|
||||
int onResize(int bits, IBlockState state);
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
// Auto generated package-info by MCP
|
||||
@ParametersAreNonnullByDefault
|
||||
@MethodsReturnNonnullByDefault
|
||||
package net.minecraft.world.chunk;
|
||||
|
||||
import mcp.MethodsReturnNonnullByDefault;
|
||||
import javax.annotation.ParametersAreNonnullByDefault;
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
// Auto generated package-info by MCP
|
||||
@ParametersAreNonnullByDefault
|
||||
@MethodsReturnNonnullByDefault
|
||||
package net.minecraft.world.end;
|
||||
|
||||
import mcp.MethodsReturnNonnullByDefault;
|
||||
import javax.annotation.ParametersAreNonnullByDefault;
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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)
|
||||
{
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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
Reference in New Issue
Block a user