mirror of
https://github.com/Minecraft-Community-Edition/client.git
synced 2026-05-24 01:54:34 +00:00
generate aerclouds in the aether
This commit is contained in:
142
Minecraft.World/AerCloudFeature.cpp
Normal file
142
Minecraft.World/AerCloudFeature.cpp
Normal file
@@ -0,0 +1,142 @@
|
||||
#include "stdafx.h"
|
||||
#include "AerCloudFeature.h"
|
||||
#include "net.minecraft.world.level.h"
|
||||
#include "net.minecraft.world.level.tile.h"
|
||||
|
||||
AerCloudFeature::AerCloudFeature(int tileId, int minRadius, int maxRadius, int minHeight, int maxHeight, bool islandBottom)
|
||||
: Feature(false)
|
||||
{
|
||||
this->tileId = tileId;
|
||||
this->minRadius = minRadius;
|
||||
this->maxRadius = maxRadius;
|
||||
this->minHeight = minHeight;
|
||||
this->maxHeight = maxHeight;
|
||||
this->islandBottom = islandBottom;
|
||||
}
|
||||
|
||||
int AerCloudFeature::findIslandBottom(Level *level, int x, int startY, int z)
|
||||
{
|
||||
// Scan down from startY to find the lowest solid block in this column that's part of an island
|
||||
for (int yy = startY; yy >= 1; yy--)
|
||||
{
|
||||
int tile = level->getTile(x, yy, z);
|
||||
if (tile != 0)
|
||||
{
|
||||
// Found solid — now find the bottom of this solid section
|
||||
for (int by = yy; by >= 1; by--)
|
||||
{
|
||||
int belowTile = level->getTile(x, by - 1, z);
|
||||
if (belowTile == 0)
|
||||
{
|
||||
return by; // This is the bottom of the island
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
return -1; // No solid block found
|
||||
}
|
||||
|
||||
void AerCloudFeature::generateCloudBlob(Level *level, Random *random, int cx, int cy, int cz, int rx, int rz, int ry)
|
||||
{
|
||||
// Generate an ellipsoidal cloud using distance checks with randomization for organic shape
|
||||
float rxSq = (float)(rx * rx);
|
||||
float rySq = (float)(ry * ry);
|
||||
float rzSq = (float)(rz * rz);
|
||||
|
||||
for (int dx = -rx; dx <= rx; dx++)
|
||||
{
|
||||
for (int dz = -rz; dz <= rz; dz++)
|
||||
{
|
||||
for (int dy = -ry; dy <= ry; dy++)
|
||||
{
|
||||
float distSq = (dx * dx) / rxSq + (dy * dy) / rySq + (dz * dz) / rzSq;
|
||||
|
||||
// Ellipsoid check with randomized edges for organic cloud shapes
|
||||
if (distSq < 1.0f + (random->nextFloat() * 0.3f - 0.15f))
|
||||
{
|
||||
int bx = cx + dx;
|
||||
int by = cy + dy;
|
||||
int bz = cz + dz;
|
||||
|
||||
if (by < 1 || by >= Level::genDepth) continue;
|
||||
|
||||
// Only place in air
|
||||
if (level->getTile(bx, by, bz) == 0)
|
||||
{
|
||||
placeBlock(level, bx, by, bz, tileId);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool AerCloudFeature::place(Level *level, Random *random, int x, int y, int z)
|
||||
{
|
||||
if (islandBottom)
|
||||
{
|
||||
// Large cloud formation at the underside of islands
|
||||
// Find the bottom of the nearest island
|
||||
int bottomY = findIslandBottom(level, x, y, z);
|
||||
if (bottomY < 2) return false;
|
||||
|
||||
// Verify there's actually an island above (at least a few solid blocks)
|
||||
int solidCount = 0;
|
||||
for (int cy = bottomY; cy <= bottomY + 5 && cy < Level::genDepth; cy++)
|
||||
{
|
||||
if (level->getTile(x, cy, z) != 0) solidCount++;
|
||||
}
|
||||
if (solidCount < 3) return false;
|
||||
|
||||
// Verify there's open air below the island bottom
|
||||
bool hasAirBelow = false;
|
||||
for (int cy = bottomY - 1; cy >= bottomY - 4 && cy >= 0; cy--)
|
||||
{
|
||||
if (level->getTile(x, cy, z) == 0)
|
||||
{
|
||||
hasAirBelow = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!hasAirBelow) return false;
|
||||
|
||||
// Generate a large cloud clump beneath the island
|
||||
int rx = minRadius + random->nextInt(maxRadius - minRadius + 1);
|
||||
int rz = minRadius + random->nextInt(maxRadius - minRadius + 1);
|
||||
int ry = minHeight + random->nextInt(maxHeight - minHeight + 1);
|
||||
|
||||
int cloudY = bottomY - ry - 1;
|
||||
if (cloudY < 1) return false;
|
||||
|
||||
// Place multiple overlapping blobs for a more natural cloud appearance
|
||||
int blobCount = 2 + random->nextInt(3); // 2-4 overlapping blobs
|
||||
for (int i = 0; i < blobCount; i++)
|
||||
{
|
||||
int blobX = x + random->nextInt(rx) - rx / 2;
|
||||
int blobZ = z + random->nextInt(rz) - rz / 2;
|
||||
int blobY = cloudY + random->nextInt(ry > 1 ? ry : 1);
|
||||
int blobRx = rx / 2 + random->nextInt(rx / 2 + 1);
|
||||
int blobRz = rz / 2 + random->nextInt(rz / 2 + 1);
|
||||
int blobRy = max(1, ry / 2 + random->nextInt(max(1, ry / 2)));
|
||||
|
||||
generateCloudBlob(level, random, blobX, blobY, blobZ, blobRx, blobRz, blobRy);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Small floating cloud in the sky at the given position
|
||||
// Only place in air — verify the position is actually open
|
||||
if (level->getTile(x, y, z) != 0) return false;
|
||||
|
||||
int rx = minRadius + random->nextInt(maxRadius - minRadius + 1);
|
||||
int rz = minRadius + random->nextInt(maxRadius - minRadius + 1);
|
||||
int ry = minHeight + random->nextInt(maxHeight - minHeight + 1);
|
||||
|
||||
generateCloudBlob(level, random, x, y, z, rx, rz, ry);
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
28
Minecraft.World/AerCloudFeature.h
Normal file
28
Minecraft.World/AerCloudFeature.h
Normal file
@@ -0,0 +1,28 @@
|
||||
#pragma once
|
||||
#include "Feature.h"
|
||||
|
||||
class AerCloudFeature : public Feature
|
||||
{
|
||||
public:
|
||||
// tileId: which aercloud tile to place (aercloud, gold, blue)
|
||||
// minRadius/maxRadius: horizontal radius range for the cloud blob
|
||||
// minHeight/maxHeight: vertical thickness range
|
||||
// islandBottom: if true, generates large clouds at island undersides; if false, generates floating sky clouds
|
||||
AerCloudFeature(int tileId, int minRadius, int maxRadius, int minHeight, int maxHeight, bool islandBottom);
|
||||
|
||||
virtual bool place(Level *level, Random *random, int x, int y, int z);
|
||||
|
||||
private:
|
||||
int tileId;
|
||||
int minRadius;
|
||||
int maxRadius;
|
||||
int minHeight;
|
||||
int maxHeight;
|
||||
bool islandBottom;
|
||||
|
||||
// Generate an ellipsoidal cloud blob centered at (cx, cy, cz)
|
||||
void generateCloudBlob(Level *level, Random *random, int cx, int cy, int cz, int rx, int rz, int ry);
|
||||
|
||||
// Find the bottom of an island by scanning down from y
|
||||
int findIslandBottom(Level *level, int x, int startY, int z);
|
||||
};
|
||||
@@ -12,4 +12,5 @@ public:
|
||||
virtual void fallOn(Level *level, int x, int y, int z, shared_ptr<Entity> entity, float fallDistance);
|
||||
virtual void entityInside(Level *level, int x, int y, int z, shared_ptr<Entity> entity);
|
||||
virtual bool isSolidRender(bool isServerLevel = false);
|
||||
virtual bool shouldRenderFace(LevelSource *level, int x, int y, int z, int face);
|
||||
};
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
#include "net.minecraft.world.level.levelgen.feature.h"
|
||||
#include "net.minecraft.world.level.biome.h"
|
||||
#include "QuicksoilShelfFeature.h"
|
||||
#include "AerCloudFeature.h"
|
||||
|
||||
AetherBiomeDecorator::AetherBiomeDecorator(Biome *biome) : BiomeDecorator(biome)
|
||||
{
|
||||
@@ -16,6 +17,16 @@ AetherBiomeDecorator::AetherBiomeDecorator(Biome *biome) : BiomeDecorator(biome)
|
||||
// Quicksoil shelves on island undersides
|
||||
quicksoilShelfFeature = new QuicksoilShelfFeature();
|
||||
|
||||
// AerCloud features
|
||||
// Large clouds at island bottoms: radius 6-10, height 2-4, island-bottom mode
|
||||
largeAerCloudFeature = new AerCloudFeature(Tile::aercloud_Id, 6, 10, 2, 4, true);
|
||||
// Small white sky clouds: radius 3-6, height 1-2, free-floating
|
||||
smallAerCloudFeature = new AerCloudFeature(Tile::aercloud_Id, 3, 6, 1, 2, false);
|
||||
// Small gold sky clouds: radius 2-4, height 1-2, free-floating
|
||||
smallGoldAerCloudFeature = new AerCloudFeature(Tile::goldAercloud_Id, 2, 4, 1, 2, false);
|
||||
// Small blue sky clouds: radius 2-4, height 1-2, free-floating
|
||||
smallBlueAerCloudFeature = new AerCloudFeature(Tile::blueAercloud_Id, 2, 4, 1, 2, false);
|
||||
|
||||
// Aether decoration counts
|
||||
treeCount = 2;
|
||||
grassCount = 5;
|
||||
@@ -90,6 +101,52 @@ void AetherBiomeDecorator::decorate()
|
||||
}
|
||||
}
|
||||
PIXEndNamedEvent();
|
||||
|
||||
PIXBeginNamedEvent(0, "Decorate Aether clouds");
|
||||
|
||||
// Large aercloud formations at island undersides — gives players a safety net when falling (1 in 5 chunks)
|
||||
if (random->nextInt(5) == 0)
|
||||
{
|
||||
int x = xo + random->nextInt(16) + 8;
|
||||
int z = zo + random->nextInt(16) + 8;
|
||||
int y = level->getHeightmap(x, z);
|
||||
if (y > 0)
|
||||
{
|
||||
largeAerCloudFeature->place(level, random, x, y, z);
|
||||
}
|
||||
}
|
||||
|
||||
// Sky clouds spawn at y=80 or higher
|
||||
const int minCloudY = 80;
|
||||
|
||||
// Small white aerclouds floating in the sky (1 in 10 chunks)
|
||||
if (random->nextInt(10) == 0)
|
||||
{
|
||||
int x = xo + random->nextInt(16) + 8;
|
||||
int z = zo + random->nextInt(16) + 8;
|
||||
int y = minCloudY + random->nextInt(Level::genDepth - 10 - minCloudY);
|
||||
smallAerCloudFeature->place(level, random, x, y, z);
|
||||
}
|
||||
|
||||
// Small gold aerclouds — rare (1 in 30 chunks)
|
||||
if (random->nextInt(30) == 0)
|
||||
{
|
||||
int x = xo + random->nextInt(16) + 8;
|
||||
int z = zo + random->nextInt(16) + 8;
|
||||
int y = minCloudY + random->nextInt(Level::genDepth - 10 - minCloudY);
|
||||
smallGoldAerCloudFeature->place(level, random, x, y, z);
|
||||
}
|
||||
|
||||
// Small blue aerclouds — rarest (1 in 60 chunks)
|
||||
if (random->nextInt(60) == 0)
|
||||
{
|
||||
int x = xo + random->nextInt(16) + 8;
|
||||
int z = zo + random->nextInt(16) + 8;
|
||||
int y = minCloudY + random->nextInt(Level::genDepth - 10 - minCloudY);
|
||||
smallBlueAerCloudFeature->place(level, random, x, y, z);
|
||||
}
|
||||
|
||||
PIXEndNamedEvent();
|
||||
}
|
||||
|
||||
void AetherBiomeDecorator::decorateAetherOres()
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
#pragma once
|
||||
#include "BiomeDecorator.h"
|
||||
|
||||
class AerCloudFeature;
|
||||
|
||||
class AetherBiomeDecorator : public BiomeDecorator
|
||||
{
|
||||
public:
|
||||
@@ -15,6 +17,12 @@ protected:
|
||||
// Quicksoil shelf feature for island undersides
|
||||
Feature *quicksoilShelfFeature;
|
||||
|
||||
// AerCloud features
|
||||
Feature *largeAerCloudFeature; // Big cloud clumps at island undersides
|
||||
Feature *smallAerCloudFeature; // Small white clouds in the sky
|
||||
Feature *smallGoldAerCloudFeature; // Small gold clouds (rare)
|
||||
Feature *smallBlueAerCloudFeature; // Small blue clouds (rarest)
|
||||
|
||||
virtual void decorate();
|
||||
void decorateAetherOres();
|
||||
};
|
||||
|
||||
@@ -86,6 +86,16 @@ bool AetherDimension::isFoggyAt(int x, int z)
|
||||
return false;
|
||||
}
|
||||
|
||||
bool AetherDimension::hasBedrockFog()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
double AetherDimension::getClearColorScale()
|
||||
{
|
||||
return 1.0;
|
||||
}
|
||||
|
||||
int AetherDimension::getSpawnYPosition()
|
||||
{
|
||||
return 64;
|
||||
|
||||
@@ -17,4 +17,6 @@ public:
|
||||
virtual Pos *getSpawnPos();
|
||||
virtual int getSpawnYPosition();
|
||||
virtual bool isFoggyAt(int x, int z);
|
||||
virtual bool hasBedrockFog();
|
||||
virtual double getClearColorScale();
|
||||
};
|
||||
|
||||
@@ -308,7 +308,7 @@ doubleArray AetherLevelSource::getHeights(doubleArray buffer, int x, int y, int
|
||||
val = val * (1 - slide) + -3000 * slide;
|
||||
}
|
||||
// Slide down at the bottom of the world
|
||||
r = 8;
|
||||
r = 10;
|
||||
if (yy < r)
|
||||
{
|
||||
double slide = (r - yy) / (r - 1.0f);
|
||||
|
||||
@@ -54,7 +54,7 @@ public:
|
||||
|
||||
int getSpawnYPosition();
|
||||
virtual bool hasBedrockFog();
|
||||
double getClearColorScale();
|
||||
virtual double getClearColorScale();
|
||||
virtual bool isFoggyAt(int x, int z);
|
||||
|
||||
// 4J Added
|
||||
|
||||
@@ -2514,6 +2514,7 @@
|
||||
<ClInclude Include="OldChunkStorage.h" />
|
||||
<ClInclude Include="OreFeature.h" />
|
||||
<ClInclude Include="QuicksoilShelfFeature.h" />
|
||||
<ClInclude Include="AerCloudFeature.h" />
|
||||
<ClInclude Include="OreRecipies.h" />
|
||||
<ClInclude Include="OreTile.h" />
|
||||
<ClInclude Include="OutputStream.h" />
|
||||
@@ -3540,6 +3541,7 @@
|
||||
<ClCompile Include="OldChunkStorage.cpp" />
|
||||
<ClCompile Include="OreFeature.cpp" />
|
||||
<ClCompile Include="QuicksoilShelfFeature.cpp" />
|
||||
<ClCompile Include="AerCloudFeature.cpp" />
|
||||
<ClCompile Include="OreRecipies.cpp" />
|
||||
<ClCompile Include="OreTile.cpp" />
|
||||
<ClCompile Include="Packet.cpp" />
|
||||
|
||||
@@ -466,6 +466,9 @@
|
||||
<ClInclude Include="QuicksoilShelfFeature.h">
|
||||
<Filter>net\minecraft\world\level\levelgen\feature</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="AerCloudFeature.h">
|
||||
<Filter>net\minecraft\world\level\levelgen\feature</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="PumpkinFeature.h">
|
||||
<Filter>net\minecraft\world\level\levelgen\feature</Filter>
|
||||
</ClInclude>
|
||||
@@ -3006,6 +3009,9 @@
|
||||
<ClCompile Include="QuicksoilShelfFeature.cpp">
|
||||
<Filter>net\minecraft\world\level\levelgen\feature</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="AerCloudFeature.cpp">
|
||||
<Filter>net\minecraft\world\level\levelgen\feature</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="PumpkinFeature.cpp">
|
||||
<Filter>net\minecraft\world\level\levelgen\feature</Filter>
|
||||
</ClCompile>
|
||||
|
||||
@@ -37,5 +37,6 @@
|
||||
|
||||
#include "SkyrootTreeFeature.h"
|
||||
#include "GoldenOakTreeFeature.h"
|
||||
#include "AerCloudFeature.h"
|
||||
#include "VinesFeature.h"
|
||||
#include "GroundBushFeature.h"
|
||||
Reference in New Issue
Block a user