GenLayerRiverInit
这个生成的不是生物群系ID,而是2~300000的随机数
public int[] getInts(int areaX, int areaY, int areaWidth, int areaHeight)
{
// parent是GenLayerDeepOcean
int[] parentRes = this.parent.getInts(areaX, areaY, areaWidth, areaHeight);
int[] result = IntCache.getIntCache(areaWidth * areaHeight);
for (int y = 0; y < areaHeight; ++y)
{
for (int x = 0; x < areaWidth; ++x)
{
this.initChunkSeed(x + areaX, y + areaY);
// parent不是海洋则生成2~300000的随机数
result[x + y * areaWidth] = parentRes[x + y * areaWidth] > 0 ? this.nextInt(299999) + 2 : 0;
}
}
return result;
}
GenLayerHills
从名字来看貌似是用来添加山的
public int[] getInts(int areaX, int areaY, int areaWidth, int areaHeight)
{
int[] parentRes1 = this.parent.getInts(areaX - 1, areaY - 1, areaWidth + 2, areaHeight + 2);
// field_151628_d是经过放大的GenLayerRiverInit
int[] parentRes2 = this.field_151628_d.getInts(areaX - 1, areaY - 1, areaWidth + 2, areaHeight + 2);
int[] result = IntCache.getIntCache(areaWidth * areaHeight);
for (int y = 0; y < areaHeight; ++y)
{
for (int x = 0; x < areaWidth; ++x)
{
this.initChunkSeed(x + areaX, y + areaY);
int parentValue1X1Y1 = parentRes1[x + 1 + (y + 1) * (areaWidth + 2)];
int parentValue2X1Y1 = parentRes2[x + 1 + (y + 1) * (areaWidth + 2)];
boolean flag = (parentValue2X1Y1 - 2) % 29 == 0; // 1/29的概率
if (parentValue1X1Y1 > 255) // 旧版本?
{
logger.debug("old! " + parentValue1X1Y1);
}
if ( parentValue1X1Y1 != 0 // parent1不是海洋
&& parentValue2X1Y1 >= 2 // parent2是2~300000的随机数
&& (parentValue2X1Y1 - 2) % 29 == 1 // 1/29的概率
&& parentValue1X1Y1 < 128)
{
// 生物群系ID+128是它的突变版,初始化见net.minecraft.world.biome.BiomeGenBase
// 658行开始的一堆createMutation()
if (BiomeGenBase.getBiome(parentValue1X1Y1 + 128) != null)
{
result[x + y * areaWidth] = parentValue1X1Y1 + 128;
}
else
{
result[x + y * areaWidth] = parentValue1X1Y1;
}
}
else if (this.nextInt(3) != 0 && !flag)
{
// 1/3 * 1/29的概率不替换
result[x + y * areaWidth] = parentValue1X1Y1;
}
else
{
int value = parentValue1X1Y1;
// 替换成对应生物群系的山
if (parentValue1X1Y1 == BiomeGenBase.desert.biomeID)
{
value = BiomeGenBase.desertHills.biomeID;
}
else if (parentValue1X1Y1 == BiomeGenBase.forest.biomeID)
{
value = BiomeGenBase.forestHills.biomeID;
}
else if (parentValue1X1Y1 == BiomeGenBase.birchForest.biomeID)
{
value = BiomeGenBase.birchForestHills.biomeID;
}
else if (parentValue1X1Y1 == BiomeGenBase.roofedForest.biomeID)
{
value = BiomeGenBase.plains.biomeID;
}
else if (parentValue1X1Y1 == BiomeGenBase.taiga.biomeID)
{
value = BiomeGenBase.taigaHills.biomeID;
}
else if (parentValue1X1Y1 == BiomeGenBase.megaTaiga.biomeID)
{
value = BiomeGenBase.megaTaigaHills.biomeID;
}
else if (parentValue1X1Y1 == BiomeGenBase.coldTaiga.biomeID)
{
value = BiomeGenBase.coldTaigaHills.biomeID;
}
else if (parentValue1X1Y1 == BiomeGenBase.plains.biomeID)
{
if (this.nextInt(3) == 0)
{
value = BiomeGenBase.forestHills.biomeID;
}
else
{
value = BiomeGenBase.forest.biomeID;
}
}
else if (parentValue1X1Y1 == BiomeGenBase.icePlains.biomeID)
{
value = BiomeGenBase.iceMountains.biomeID;
}
else if (parentValue1X1Y1 == BiomeGenBase.jungle.biomeID)
{
value = BiomeGenBase.jungleHills.biomeID;
}
else if (parentValue1X1Y1 == BiomeGenBase.ocean.biomeID)
{
value = BiomeGenBase.deepOcean.biomeID;
}
else if (parentValue1X1Y1 == BiomeGenBase.extremeHills.biomeID)
{
value = BiomeGenBase.extremeHillsPlus.biomeID;
}
else if (parentValue1X1Y1 == BiomeGenBase.savanna.biomeID)
{
value = BiomeGenBase.savannaPlateau.biomeID;
}
else if (biomesEqualOrMesaPlateau(parentValue1X1Y1, BiomeGenBase.mesaPlateau_F.biomeID))
{
value = BiomeGenBase.mesa.biomeID;
}
else if (parentValue1X1Y1 == BiomeGenBase.deepOcean.biomeID && this.nextInt(3) == 0)
{
if (this.nextInt(2) == 0)
{
value = BiomeGenBase.plains.biomeID;
}
else
{
value = BiomeGenBase.forest.biomeID;
}
}
if (flag && value != parentValue1X1Y1)
{
if (BiomeGenBase.getBiome(value + 128) != null)
{
value += 128;
}
else
{
value = parentValue1X1Y1;
}
}
if (value == parentValue1X1Y1)
{
result[x + y * areaWidth] = parentValue1X1Y1;
}
else
{
int parentValue1X1 = parentRes1[x + 1 + y * (areaWidth + 2)];
int parentValue1X2Y1 = parentRes1[x + 2 + (y + 1) * (areaWidth + 2)];
int parentValue1Y1 = parentRes1[x + (y + 1) * (areaWidth + 2)];
int parentValue1X1Y2 = parentRes1[x + 1 + (y + 2) * (areaWidth + 2)];
int equalCount = 0;
if (biomesEqualOrMesaPlateau(parentValue1X1, parentValue1X1Y1))
{
++equalCount;
}
if (biomesEqualOrMesaPlateau(parentValue1X2Y1, parentValue1X1Y1))
{
++equalCount;
}
if (biomesEqualOrMesaPlateau(parentValue1Y1, parentValue1X1Y1))
{
++equalCount;
}
if (biomesEqualOrMesaPlateau(parentValue1X1Y2, parentValue1X1Y1))
{
++equalCount;
}
if (equalCount >= 3)
{
result[x + y * areaWidth] = value;
}
else
{
result[x + y * areaWidth] = parentValue1X1Y1;
}
}
}
}
}
return result;
}
GenLayerRareBiome
这个用来生成突变版平原(看名字好像是太阳花平原)
public int[] getInts(int areaX, int areaY, int areaWidth, int areaHeight)
{
int[] parentRes = this.parent.getInts(areaX - 1, areaY - 1, areaWidth + 2, areaHeight + 2);
int[] result = IntCache.getIntCache(areaWidth * areaHeight);
for (int y = 0; y < areaHeight; ++y)
{
for (int x = 0; x < areaWidth; ++x)
{
this.initChunkSeed(x + areaX, y + areaY);
int parentValueX1Y1 = parentRes[x + 1 + (y + 1) * (areaWidth + 2)];
if (this.nextInt(57) == 0)
{
if (parentValueX1Y1 == BiomeGenBase.plains.biomeID)
{
// 1/57的概率把平原变成突变版
result[x + y * areaWidth] = BiomeGenBase.plains.biomeID + 128;
}
else
{
result[x + y * areaWidth] = parentValueX1Y1;
}
}
else
{
result[x + y * areaWidth] = parentValueX1Y1;
}
}
}
return result;
}
GenLayerShore
用来生成陆地和海洋之间的沙滩
public int[] getInts(int areaX, int areaY, int areaWidth, int areaHeight)
{
int[] parentRes = this.parent.getInts(areaX - 1, areaY - 1, areaWidth + 2, areaHeight + 2);
int[] result = IntCache.getIntCache(areaWidth * areaHeight);
for (int y = 0; y < areaHeight; ++y)
{
for (int x = 0; x < areaWidth; ++x)
{
this.initChunkSeed(x + areaX, y + areaY);
int parentValueX1Y1 = parentRes[x + 1 + (y + 1) * (areaWidth + 2)];
BiomeGenBase biome = BiomeGenBase.getBiome(parentValueX1Y1);
if (parentValueX1Y1 == BiomeGenBase.mushroomIsland.biomeID) // 蘑菇岛
{
int parentValueX1 = parentRes[x + 1 + y * (areaWidth + 2)];
int parentValueX2Y1 = parentRes[x + 2 + (y + 1) * (areaWidth + 2)];
int parentValueY1 = parentRes[x + (y + 1) * (areaWidth + 2)];
int parentValueX1Y2 = parentRes[x + 1 + (y + 2) * (areaWidth + 2)];
if ( parentValueX1 != BiomeGenBase.ocean.biomeID
&& parentValueX2Y1 != BiomeGenBase.ocean.biomeID
&& parentValueY1 != BiomeGenBase.ocean.biomeID
&& parentValueX1Y2 != BiomeGenBase.ocean.biomeID)
{
result[x + y * areaWidth] = parentValueX1Y1;
}
else
{
// 如果是陆地和海洋边界则换为海滨,后同
result[x + y * areaWidth] = BiomeGenBase.mushroomIslandShore.biomeID;
}
}
else if (biome != null && biome.getBiomeClass() == BiomeGenJungle.class) // 丛林
{
int parentValueX1 = parentRes[x + 1 + y * (areaWidth + 2)];
int parentValueX2Y1 = parentRes[x + 2 + (y + 1) * (areaWidth + 2)];
int parentValueY1 = parentRes[x + (y + 1) * (areaWidth + 2)];
int parentValueX1Y2 = parentRes[x + 1 + (y + 2) * (areaWidth + 2)];
if ( this.func_151631_c(parentValueX1)
&& this.func_151631_c(parentValueX2Y1)
&& this.func_151631_c(parentValueY1)
&& this.func_151631_c(parentValueX1Y2))
{
if ( !isBiomeOceanic(parentValueX1)
&& !isBiomeOceanic(parentValueX2Y1)
&& !isBiomeOceanic(parentValueY1)
&& !isBiomeOceanic(parentValueX1Y2))
{
result[x + y * areaWidth] = parentValueX1Y1;
}
else
{
result[x + y * areaWidth] = BiomeGenBase.beach.biomeID;
}
}
else
{
result[x + y * areaWidth] = BiomeGenBase.jungleEdge.biomeID;
}
}
else if ( parentValueX1Y1 != BiomeGenBase.extremeHills.biomeID
&& parentValueX1Y1 != BiomeGenBase.extremeHillsPlus.biomeID
&& parentValueX1Y1 != BiomeGenBase.extremeHillsEdge.biomeID) // 不是高山
{
if (biome != null && biome.isSnowyBiome()) // 会下雪
{
this.func_151632_a(parentRes, result, x, y, areaWidth, parentValueX1Y1, BiomeGenBase.coldBeach.biomeID);
}
else if ( parentValueX1Y1 != BiomeGenBase.mesa.biomeID
&& parentValueX1Y1 != BiomeGenBase.mesaPlateau_F.biomeID) // 不是高原
{
if (parentValueX1Y1 != BiomeGenBase.ocean.biomeID
&& parentValueX1Y1 != BiomeGenBase.deepOcean.biomeID
&& parentValueX1Y1 != BiomeGenBase.river.biomeID
&& parentValueX1Y1 != BiomeGenBase.swampland.biomeID) // 不是海、河、沼泽
{
int parentValueX1 = parentRes[x + 1 + y * (areaWidth + 2)];
int parentValueX2Y1 = parentRes[x + 2 + (y + 1) * (areaWidth + 2)];
int parentValueY1 = parentRes[x + (y + 1) * (areaWidth + 2)];
int parentValueX1Y2 = parentRes[x + 1 + (y + 2) * (areaWidth + 2)];
if ( !isBiomeOceanic(parentValueX1)
&& !isBiomeOceanic(parentValueX2Y1)
&& !isBiomeOceanic(parentValueY1)
&& !isBiomeOceanic(parentValueX1Y2))
{
result[x + y * areaWidth] = parentValueX1Y1;
}
else
{
result[x + y * areaWidth] = BiomeGenBase.beach.biomeID;
}
}
else
{
result[x + y * areaWidth] = parentValueX1Y1;
}
}
else
{
int parentValueX1 = parentRes[x + 1 + y * (areaWidth + 2)];
int parentValueX2Y1 = parentRes[x + 2 + (y + 1) * (areaWidth + 2)];
int parentValueY1 = parentRes[x + (y + 1) * (areaWidth + 2)];
int parentValueX1Y2 = parentRes[x + 1 + (y + 2) * (areaWidth + 2)];
if ( !isBiomeOceanic(parentValueX1)
&& !isBiomeOceanic(parentValueX2Y1)
&& !isBiomeOceanic(parentValueY1)
&& !isBiomeOceanic(parentValueX1Y2))
{
if ( this.func_151633_d(parentValueX1)
&& this.func_151633_d(parentValueX2Y1)
&& this.func_151633_d(parentValueY1)
&& this.func_151633_d(parentValueX1Y2))
{
result[x + y * areaWidth] = parentValueX1Y1;
}
else
{
result[x + y * areaWidth] = BiomeGenBase.desert.biomeID;
}
}
else
{
result[x + y * areaWidth] = parentValueX1Y1;
}
}
}
else
{
this.func_151632_a(parentRes, result, x, y, areaWidth, parentValueX1Y1, BiomeGenBase.stoneBeach.biomeID);
}
}
}
return result;
}
// 如果是陆地和海洋边界则换为newBiome
private void func_151632_a(int[] parentRes, int[] result, int x, int y, int areaWidth, int parentValueX1Y1, int newBiome)
{
if (isBiomeOceanic(parentValueX1Y1))
{
result[x + y * areaWidth] = parentValueX1Y1;
}
else
{
int parentValueX1 = parentRes[x + 1 + y * (areaWidth + 2)];
int parentValueX2Y1 = parentRes[x + 2 + (y + 1) * (areaWidth + 2)];
int parentValueY1 = parentRes[x + (y + 1) * (areaWidth + 2)];
int parentValueX1Y2 = parentRes[x + 1 + (y + 2) * (areaWidth + 2)];
if ( !isBiomeOceanic(parentValueX1)
&& !isBiomeOceanic(parentValueX2Y1)
&& !isBiomeOceanic(parentValueY1)
&& !isBiomeOceanic(parentValueX1Y2))
{
result[x + y * areaWidth] = parentValueX1Y1;
}
else
{
result[x + y * areaWidth] = newBiome;
}
}
}
// 判断是不是森林
private boolean func_151631_c(int biomeId)
{
return BiomeGenBase.getBiome(biomeId) != null
&& BiomeGenBase.getBiome(biomeId).getBiomeClass() == BiomeGenJungle.class ?
true :
biomeId == BiomeGenBase.jungleEdge.biomeID
|| biomeId == BiomeGenBase.jungle.biomeID
|| biomeId == BiomeGenBase.jungleHills.biomeID
|| biomeId == BiomeGenBase.forest.biomeID
|| biomeId == BiomeGenBase.taiga.biomeID
|| isBiomeOceanic(biomeId);
}
// 判断是不是高原
private boolean func_151633_d(int biomeId)
{
return BiomeGenBase.getBiome(biomeId) instanceof BiomeGenMesa;
}
GenLayerSmooth
用来使上一层的结果更平滑
public int[] getInts(int areaX, int areaY, int areaWidth, int areaHeight)
{
int parentAreaX = areaX - 1;
int parentAreaY = areaY - 1;
int parentWidth = areaWidth + 2;
int parentHeight = areaHeight + 2;
int[] parentRes = this.parent.getInts(parentAreaX, parentAreaY, parentWidth, parentHeight);
int[] result = IntCache.getIntCache(areaWidth * areaHeight);
for (int y = 0; y < areaHeight; ++y)
{
for (int x = 0; x < areaWidth; ++x)
{
// 以x+1 y+1为中心,十字型采样5个点
int parentValueY1 = parentRes[x + (y + 1) * parentWidth];
int parentValueX2Y1 = parentRes[x + 2 + (y + 1) * parentWidth];
int parentValueX1 = parentRes[x + 1 + y * parentWidth];
int parentValueX1Y2 = parentRes[x + 1 + (y + 2) * parentWidth];
int parentValueX1Y1 = parentRes[x + 1 + (y + 1) * parentWidth];
if ( parentValueY1 == parentValueX2Y1
&& parentValueX1 == parentValueX1Y2)
{
this.initChunkSeed(x + areaX, y + areaY);
// 如果横、竖相对点各自相等则随机取一个
if (this.nextInt(2) == 0)
{
parentValueX1Y1 = parentValueY1;
}
else
{
parentValueX1Y1 = parentValueX1;
}
}
else
{
if (parentValueY1 == parentValueX2Y1)
{
// 如果横相对两点相等则取其值
parentValueX1Y1 = parentValueY1;
}
if (parentValueX1 == parentValueX1Y2)
{
// 如果竖相对两点相等则取其值
parentValueX1Y1 = parentValueX1;
}
} // 其他情况则不变
result[x + y * areaWidth] = parentValueX1Y1;
}
}
return result;
}
GenLayerRiver
用来生成河流
public int[] getInts(int areaX, int areaY, int areaWidth, int areaHeight)
{
int parentAreaX = areaX - 1;
int parentAreaY = areaY - 1;
int parentWidth = areaWidth + 2;
int parentHeight = areaHeight + 2;
// parent是经过放大的GenLayerRiverInit
int[] parentRes = this.parent.getInts(parentAreaX, parentAreaY, parentWidth, parentHeight);
int[] result = IntCache.getIntCache(areaWidth * areaHeight);
for (int y = 0; y < areaHeight; ++y)
{
for (int x = 0; x < areaWidth; ++x)
{
// 由上层决定的0、2、3随机数
int randomValueY1 = this.func_151630_c(parentRes[x + (y + 1) * parentWidth]);
int randomValueX2Y1 = this.func_151630_c(parentRes[x + 2 + (y + 1) * parentWidth]);
int randomValueX1 = this.func_151630_c(parentRes[x + 1 + y * parentWidth]);
int randomValueX1Y2 = this.func_151630_c(parentRes[x + 1 + (y + 2) * parentWidth]);
int randomValueX1Y1 = this.func_151630_c(parentRes[x + 1 + (y + 1) * parentWidth]);
if ( randomValueX1Y1 == randomValueY1
&& randomValueX1Y1 == randomValueX1
&& randomValueX1Y1 == randomValueX2Y1
&& randomValueX1Y1 == randomValueX1Y2)
{
// 中心和周围相等则取-1
result[x + y * areaWidth] = -1;
}
else
{
// 河流
result[x + y * areaWidth] = BiomeGenBase.river.biomeID;
}
}
}
return result;
}
// value >= 2则返回2~3的随机数,否则返回value
private int func_151630_c(int value)
{
return value >= 2 ? 2 + value % 2 : value;
}
GenLayerRiverMix
用来把原有的生物群系和河流混合
public int[] getInts(int areaX, int areaY, int areaWidth, int areaHeight)
{
// 上层是平滑和放大的GenLayerShore
int[] biomeRes = this.biomePatternGeneratorChain.getInts(areaX, areaY, areaWidth, areaHeight);
// 上层是平滑的GenLayerRiver
int[] riverRes = this.riverPatternGeneratorChain.getInts(areaX, areaY, areaWidth, areaHeight);
int[] result = IntCache.getIntCache(areaWidth * areaHeight);
for (int i = 0; i < areaWidth * areaHeight; ++i)
{
// biomeRes不是海洋
if (biomeRes[i] != BiomeGenBase.ocean.biomeID && biomeRes[i] != BiomeGenBase.deepOcean.biomeID)
{
// riverRes是河流
if (riverRes[i] == BiomeGenBase.river.biomeID)
{
// biomeRes是冰原
if (biomeRes[i] == BiomeGenBase.icePlains.biomeID)
{
// 生成冰冻的河流
result[i] = BiomeGenBase.frozenRiver.biomeID;
}
else if (biomeRes[i] != BiomeGenBase.mushroomIsland.biomeID && biomeRes[i] != BiomeGenBase.mushroomIslandShore.biomeID) // biomeRes不是蘑菇岛
{
// 生成河流
result[i] = riverRes[i] & 0xFF;
}
else
{
// 生成蘑菇岛海滨(所以蘑菇岛上没有河流...
result[i] = BiomeGenBase.mushroomIslandShore.biomeID;
}
}
else
{
// riverRes不是河流则取原来的生物群系ID
result[i] = biomeRes[i];
}
}
else
{
result[i] = biomeRes[i];
}
}
return result;
}
第二篇终于写完了,我太难了....
本文详细解析了Minecraft中地形生成的多个阶段,包括河流、沙滩、山脉等特征的生成逻辑,展示了如何通过不同的生成层来实现多样化的生物群系。
1470

被折叠的 条评论
为什么被折叠?



