Exemple #1
0
void GetDarkoakTreeImage(int a_BlockX, int a_BlockY, int a_BlockZ, cNoise & a_Noise, int a_Seq, sSetBlockVector & a_LogBlocks, sSetBlockVector & a_OtherBlocks)
{
	// Pick a height
	int Height = 5 + (a_Noise.IntNoise3DInt(a_BlockX + 32 * a_Seq, a_BlockY, a_BlockZ + 32 * a_Seq) / 11) % 4;

	// Create the trunk
	for (int i = 0; i < Height; i++)
	{
		a_LogBlocks.push_back(sSetBlock(a_BlockX, a_BlockY + i, a_BlockZ, E_BLOCK_NEW_LOG, E_META_NEW_LOG_DARK_OAK_WOOD));
		a_LogBlocks.push_back(sSetBlock(a_BlockX + 1, a_BlockY + i, a_BlockZ, E_BLOCK_NEW_LOG, E_META_NEW_LOG_DARK_OAK_WOOD));
		a_LogBlocks.push_back(sSetBlock(a_BlockX, a_BlockY + i, a_BlockZ + 1, E_BLOCK_NEW_LOG, E_META_NEW_LOG_DARK_OAK_WOOD));
		a_LogBlocks.push_back(sSetBlock(a_BlockX + 1, a_BlockY + i, a_BlockZ + 1, E_BLOCK_NEW_LOG, E_META_NEW_LOG_DARK_OAK_WOOD));
	}

	// Create branches
	for (int i = 0; i < 3; i++)
	{
		int x = (a_Noise.IntNoise3DInt(a_BlockX + 32 * a_Seq, a_BlockY * i, a_BlockZ + 32 * a_Seq) % 3) - 1;
		int z = (a_Noise.IntNoise3DInt(a_BlockX - 32 * a_Seq, a_BlockY * i, a_BlockZ - 32 * a_Seq) % 3) - 1;

		// The branches would end up in the trunk.
		if ((x >= a_BlockX) && (x <= a_BlockX + 1) && (z >= a_BlockZ) && (z <= a_BlockZ + 1))
		{
			NOISE_DATATYPE Val1 = a_Noise.IntNoise2D(x, z);
			if (Val1 < 0)
			{
				x = a_BlockX + ((Val1 < -0.5) ? -1 : 3);
			}
			else
			{
				z = a_BlockZ + ((Val1 < 0.5) ? -1 : 3);
			}
		}

		int y = Height - (a_Noise.IntNoise3DInt(a_BlockX + x, a_BlockY * i, a_BlockZ - z) % (Height - (Height / 4)));

		for (int Y = y; Y < Height; Y++)
		{
			a_LogBlocks.push_back(sSetBlock(a_BlockX + x, a_BlockY + Y, a_BlockZ + z, E_BLOCK_NEW_LOG, E_META_NEW_LOG_DARK_OAK_WOOD));
		}
	}

	int hei = a_BlockY + Height - 2;

	// The lower two leaves layers are BigO4 with log in the middle and possibly corners:
	for (int i = 0; i < 2; i++)
	{
		PushCoordBlocks(a_BlockX, hei, a_BlockZ, a_OtherBlocks, BigO4, ARRAYCOUNT(BigO4), E_BLOCK_NEW_LEAVES, E_META_NEW_LEAVES_DARK_OAK_WOOD);
		PushCornerBlocks(a_BlockX, hei, a_BlockZ, a_Seq, a_Noise, 0x5fffffff, a_OtherBlocks, 3, E_BLOCK_NEW_LEAVES, E_META_NEW_LEAVES_DARK_OAK_WOOD);
		hei++;
	}  // for i < 2

	// The top leaves layer is a BigO3 with leaves in the middle and possibly corners:
	PushCoordBlocks(a_BlockX, hei, a_BlockZ, a_OtherBlocks, BigO3, ARRAYCOUNT(BigO3), E_BLOCK_NEW_LEAVES, E_META_NEW_LEAVES_DARK_OAK_WOOD);
	PushCornerBlocks(a_BlockX, hei, a_BlockZ, a_Seq, a_Noise, 0x5fffffff, a_OtherBlocks, 3, E_BLOCK_NEW_LEAVES, E_META_NEW_LEAVES_DARK_OAK_WOOD);
	a_OtherBlocks.push_back(sSetBlock(a_BlockX, hei, a_BlockZ, E_BLOCK_NEW_LEAVES, E_META_NEW_LEAVES_DARK_OAK_WOOD));
}
Exemple #2
0
void GetBirchTreeImage(int a_BlockX, int a_BlockY, int a_BlockZ, cNoise & a_Noise, int a_Seq, sSetBlockVector & a_LogBlocks, sSetBlockVector & a_OtherBlocks)
{
	int Height = 5 + (a_Noise.IntNoise3DInt(a_BlockX + 64 * a_Seq, a_BlockY, a_BlockZ) % 3);
	
	// Prealloc, so that we don't realloc too often later:
	a_LogBlocks.reserve(Height);
	a_OtherBlocks.reserve(80);
	
	// The entire trunk, out of logs:
	for (int i = Height - 1; i >= 0; --i)
	{
		a_LogBlocks.push_back(sSetBlock(a_BlockX, a_BlockY + i, a_BlockZ, E_BLOCK_LOG, E_META_LOG_BIRCH));
	}
	int h = a_BlockY + Height;
	
	// Top layer - just the Plus:
	PushCoordBlocks(a_BlockX, h, a_BlockZ, a_OtherBlocks, BigO1, ARRAYCOUNT(BigO1), E_BLOCK_LEAVES, E_META_LEAVES_BIRCH);
	a_OtherBlocks.push_back(sSetBlock(a_BlockX, h, a_BlockZ, E_BLOCK_LEAVES, E_META_LEAVES_BIRCH));  // There's no log at this layer
	h--;
	
	// Second layer - log, Plus and maybe Corners:
	PushCoordBlocks (a_BlockX, h, a_BlockZ, a_OtherBlocks, BigO1, ARRAYCOUNT(BigO1), E_BLOCK_LEAVES, E_META_LEAVES_BIRCH);
	PushCornerBlocks(a_BlockX, h, a_BlockZ, a_Seq, a_Noise, 0x5fffffff, a_OtherBlocks, 1, E_BLOCK_LEAVES, E_META_LEAVES_BIRCH);
	h--;
	
	// Third and fourth layers - BigO2 and maybe 2*Corners:
	for (int Row = 0; Row < 2; Row++)
	{
		PushCoordBlocks (a_BlockX, h, a_BlockZ, a_OtherBlocks, BigO2, ARRAYCOUNT(BigO2), E_BLOCK_LEAVES, E_META_LEAVES_BIRCH);
		PushCornerBlocks(a_BlockX, h, a_BlockZ, a_Seq, a_Noise, 0x3fffffff + Row * 0x10000000, a_OtherBlocks, 2, E_BLOCK_LEAVES, E_META_LEAVES_BIRCH);
		h--;
	}  // for Row - 2*
}
Exemple #3
0
void GetJungleTreeImage(int a_BlockX, int a_BlockY, int a_BlockZ, cNoise & a_Noise, int a_Seq, sSetBlockVector & a_LogBlocks, sSetBlockVector & a_OtherBlocks)
{
	if (a_Noise.IntNoise3DInt(a_BlockX + 32 * a_Seq, a_BlockY + 32 * a_Seq, a_BlockZ) < 0x60000000)
	{
		GetSmallJungleTreeImage(a_BlockX, a_BlockY, a_BlockZ, a_Noise, a_Seq, a_LogBlocks, a_OtherBlocks);
	}
	else
	{
		GetLargeJungleTreeImage(a_BlockX, a_BlockY, a_BlockZ, a_Noise, a_Seq, a_LogBlocks, a_OtherBlocks);
	}
}
Exemple #4
0
static float GetMarbleNoise( float x, float y, float z, cNoise & a_Noise )
{
	static const float PI_2 = 1.57079633f;
	float oct1 = (a_Noise.CubicNoise3D(x * 0.1f, y * 0.1f, z * 0.1f )) * 4;

	oct1 = oct1 * oct1 * oct1;
	if (oct1 < 0.f)  oct1 = PI_2;
	if (oct1 > PI_2) oct1 = PI_2;

	return oct1;
}
Exemple #5
0
cStructGenWormNestCaves::cCaveSystem::cCaveSystem(int a_GridX, int a_GridZ, int a_OriginX, int a_OriginZ, int a_MaxOffset, int a_Size, cNoise & a_Noise) :
	super(a_GridX, a_GridZ, a_OriginX, a_OriginZ),
	m_Size(a_Size)
{
	int Num = 1 + a_Noise.IntNoise2DInt(a_OriginX, a_OriginZ) % 3;
	for (int i = 0; i < Num; i++)
	{
		int OriginX = a_OriginX + (a_Noise.IntNoise3DInt(13 * a_OriginX, 17 * a_OriginZ, 11 * i) / 19) % a_MaxOffset;
		int OriginZ = a_OriginZ + (a_Noise.IntNoise3DInt(17 * a_OriginX, 13 * a_OriginZ, 11 * i) / 23) % a_MaxOffset;
		int OriginY  = 20 + (a_Noise.IntNoise3DInt(19 * a_OriginX, 13 * a_OriginZ, 11 * i) / 17) % 20;

		// Generate three branches from the origin point:
		// The tunnels generated depend on X, Y, Z and Branches,
		// for the same set of numbers it generates the same offsets!
		// That's why we add a +1 to X in the third line
		GenerateTunnelsFromPoint(OriginX,     OriginY, OriginZ, a_Noise, 3);
		GenerateTunnelsFromPoint(OriginX,     OriginY, OriginZ, a_Noise, 2);
		GenerateTunnelsFromPoint(OriginX + 1, OriginY, OriginZ, a_Noise, 3);
	}
}
Exemple #6
0
void GetConiferTreeImage(int a_BlockX, int a_BlockY, int a_BlockZ, cNoise & a_Noise, int a_Seq, sSetBlockVector & a_LogBlocks, sSetBlockVector & a_OtherBlocks)
{
	// Half chance for a spruce, half for a pine:
	if (a_Noise.IntNoise3DInt(a_BlockX + 64 * a_Seq, a_BlockY, a_BlockZ + 32 * a_Seq) < 0x40000000)
	{
		GetSpruceTreeImage(a_BlockX, a_BlockY, a_BlockZ, a_Noise, a_Seq, a_LogBlocks, a_OtherBlocks);
	}
	else
	{
		GetPineTreeImage(a_BlockX, a_BlockY, a_BlockZ, a_Noise, a_Seq, a_LogBlocks, a_OtherBlocks);
	}
}
Exemple #7
0
	void InitPerHeightRadius(int a_GridX, int a_GridZ)
	{
		int h = 0;
		while (h < cChunkDef::Height)
		{
			m_Noise.SetSeed(m_Seed + h);
			int rnd = m_Noise.IntNoise2DInt(a_GridX, a_GridZ) / 13;
			int NumBlocks = (rnd % 3) + 2;
			rnd = rnd / 4;
			float Val = (float)(rnd % 256) / 128 - 1;  // Random float in range [-1, +1]
			if (h + NumBlocks > cChunkDef::Height)
			{
				NumBlocks = cChunkDef::Height - h;
			}
			for (int i = 0; i < NumBlocks; i++)
			{
				m_PerHeightRadius[h + i] = Val;
			}
			h += NumBlocks;
		}
	}
Exemple #8
0
void cStructGenWormNestCaves::cCaveSystem::GenerateTunnelsFromPoint(
	int a_OriginX, int a_OriginY, int a_OriginZ,
	cNoise & a_Noise, int a_NumSegments
)
{
	int DoubleSize = m_Size * 2;
	int Radius = GetRadius(a_Noise, a_OriginX + a_OriginY, a_OriginY + a_OriginZ, a_OriginZ + a_OriginX);
	for (int i = a_NumSegments - 1; i >= 0; --i)
	{
		int EndX = a_OriginX + (((a_Noise.IntNoise3DInt(a_OriginX, a_OriginY, a_OriginZ + 11 * a_NumSegments) / 7) % DoubleSize) - m_Size) / 2;
		int EndY = a_OriginY + (((a_Noise.IntNoise3DInt(a_OriginY, 13 * a_NumSegments, a_OriginZ + a_OriginX) / 7) % DoubleSize) - m_Size) / 4;
		int EndZ = a_OriginZ + (((a_Noise.IntNoise3DInt(a_OriginZ + 17 * a_NumSegments, a_OriginX, a_OriginY) / 7) % DoubleSize) - m_Size) / 2;
		int EndR = GetRadius(a_Noise, a_OriginX + 7 * i, a_OriginY + 11 * i, a_OriginZ + a_OriginX);
		m_Tunnels.push_back(new cCaveTunnel(a_OriginX, a_OriginY, a_OriginZ, Radius, EndX, EndY, EndZ, EndR, a_Noise));
		GenerateTunnelsFromPoint(EndX, EndY, EndZ, a_Noise, i);
		a_OriginX = EndX;
		a_OriginY = EndY;
		a_OriginZ = EndZ;
		Radius = EndR;
	}  // for i - a_NumSegments
}
Exemple #9
0
inline void PushCornerBlocks(int a_BlockX, int a_Height, int a_BlockZ, int a_Seq, cNoise & a_Noise, int a_Chance, sSetBlockVector & a_Blocks, int a_CornersDist, BLOCKTYPE a_BlockType, NIBBLETYPE a_Meta)
{
	for (size_t i = 0; i < ARRAYCOUNT(Corners); i++)
	{
		int x = a_BlockX + Corners[i].x;
		int z = a_BlockZ + Corners[i].z;
		if (a_Noise.IntNoise3DInt(x + 64 * a_Seq, a_Height, z + 64 * a_Seq) <= a_Chance)
		{
			a_Blocks.push_back(sSetBlock(x, a_Height, z, a_BlockType, a_Meta));
		}
	}  // for i - Corners[]
}
Exemple #10
0
void GetSmallJungleTreeImage(int a_BlockX, int a_BlockY, int a_BlockZ, cNoise & a_Noise, int a_Seq, sSetBlockVector & a_LogBlocks, sSetBlockVector & a_OtherBlocks)
{
	// Vines are around the BigO3, but not in the corners; need proper meta for direction
	static const sMetaCoords Vines[] =
	{
		{-2, -4, 1}, {-1, -4, 1}, {0, -4, 1}, {1, -4, 1}, {2, -4, 1},  // North face
		{-2,  4, 4}, {-1,  4, 4}, {0,  4, 4}, {1,  4, 4}, {2,  4, 4},  // South face
		{4,  -2, 2}, {4,  -1, 2}, {4,  0, 2}, {4,  1, 2}, {4,  2, 2},  // East face
		{-4, -2, 8}, {-4, -1, 8}, {-4, 0, 8}, {-4, 1, 8},              // West face
		// TODO: proper metas and height: {0,  1, 1},  {0, -1, 4},  {-1, 0, 2}, {1,  1, 8},  // Around the tunk
	} ;

	int Height = 7 + (a_Noise.IntNoise3DInt(a_BlockX + 5 * a_Seq, a_BlockY, a_BlockZ + 5 * a_Seq) / 5) % 3;
	
	a_LogBlocks.reserve(Height);
	a_OtherBlocks.reserve(
		2 * ARRAYCOUNT(BigO3) +      // O3 layer, 2x
		2 * ARRAYCOUNT(BigO2) +      // O2 layer, 2x
		ARRAYCOUNT(BigO1) + 1 +      // Plus on the top
		Height * ARRAYCOUNT(Vines) + // Vines
		50  // some safety
	);
	
	for (int i = 0; i < Height; i++)
	{
		a_LogBlocks.push_back(sSetBlock(a_BlockX, a_BlockY + i, a_BlockZ, E_BLOCK_LOG, E_META_LOG_JUNGLE));
	}
	int hei = a_BlockY + Height - 3;
	
	// Put vines around the lowermost leaves layer:
	PushSomeColumns(a_BlockX, hei, a_BlockZ, Height, a_Seq, a_Noise, 0x3fffffff, a_OtherBlocks, Vines, ARRAYCOUNT(Vines), E_BLOCK_VINES);
	
	// The lower two leaves layers are BigO3 with log in the middle and possibly corners:
	for (int i = 0; i < 2; i++)
	{
		PushCoordBlocks(a_BlockX, hei, a_BlockZ, a_OtherBlocks, BigO3, ARRAYCOUNT(BigO3), E_BLOCK_LEAVES, E_META_LEAVES_JUNGLE);
		PushCornerBlocks(a_BlockX, hei, a_BlockZ, a_Seq, a_Noise, 0x5fffffff, a_OtherBlocks, 3, E_BLOCK_LEAVES, E_META_LEAVES_JUNGLE);
		hei++;
	}  // for i - 2*

	// Two layers of BigO2 leaves, possibly with corners:
	for (int i = 0; i < 1; i++)
	{
		PushCoordBlocks(a_BlockX, hei, a_BlockZ, a_OtherBlocks, BigO2, ARRAYCOUNT(BigO2), E_BLOCK_LEAVES, E_META_LEAVES_JUNGLE);
		PushCornerBlocks(a_BlockX, hei, a_BlockZ, a_Seq, a_Noise, 0x5fffffff, a_OtherBlocks, 2, E_BLOCK_LEAVES, E_META_LEAVES_JUNGLE);
		hei++;
	}  // for i - 2*
	
	// Top plus, all leaves:
	PushCoordBlocks(a_BlockX, hei, a_BlockZ, a_OtherBlocks, BigO1, ARRAYCOUNT(BigO1), E_BLOCK_LEAVES, E_META_LEAVES_JUNGLE);
	a_OtherBlocks.push_back(sSetBlock(a_BlockX, hei, a_BlockZ, E_BLOCK_LEAVES, E_META_LEAVES_JUNGLE));
}
Exemple #11
0
void cStructGenRavines::cRavine::GenerateBaseDefPoints(int a_BlockX, int a_BlockZ, int a_Size, cNoise & a_Noise)
{
	// Modify the size slightly to have different-sized ravines (1 / 2 to 1 / 1 of a_Size):
	a_Size = (512 + ((a_Noise.IntNoise3DInt(19 * a_BlockX, 11 * a_BlockZ, a_BlockX + a_BlockZ) / 17) % 512)) * a_Size / 1024;

	// The complete offset of the ravine from its cellpoint, up to 2 * a_Size in each direction
	int OffsetX = (((a_Noise.IntNoise3DInt(50 * a_BlockX, 30 * a_BlockZ, 0)    / 9) % (2 * a_Size)) + ((a_Noise.IntNoise3DInt(30 * a_BlockX, 50 * a_BlockZ, 1000) / 7) % (2 * a_Size)) - 2 * a_Size) / 2;
	int OffsetZ = (((a_Noise.IntNoise3DInt(50 * a_BlockX, 30 * a_BlockZ, 2000) / 7) % (2 * a_Size)) + ((a_Noise.IntNoise3DInt(30 * a_BlockX, 50 * a_BlockZ, 3000) / 9) % (2 * a_Size)) - 2 * a_Size) / 2;
	int CenterX = a_BlockX + OffsetX;
	int CenterZ = a_BlockZ + OffsetZ;

	// Get the base angle in which the ravine "axis" goes:
	float Angle = static_cast<float>((static_cast<float>((a_Noise.IntNoise3DInt(20 * a_BlockX, 70 * a_BlockZ, 6000) / 9) % 16384)) / 16384.0 * M_PI);
	float xc = sinf(Angle);
	float zc = cosf(Angle);

	// Calculate the definition points and radii:
	int MaxRadius = static_cast<int>(sqrt(12.0 + ((a_Noise.IntNoise2DInt(61 * a_BlockX, 97 * a_BlockZ) / 13) % a_Size) / 16));
	int Top       = 32 + ((a_Noise.IntNoise2DInt(13 * a_BlockX, 17 * a_BlockZ) / 23) % 32);
	int Bottom    = 5 + ((a_Noise.IntNoise2DInt(17 * a_BlockX, 29 * a_BlockZ) / 13) % 32);
	int Mid = (Top + Bottom) / 2;
	int DefinitionPointX = CenterX - static_cast<int>(xc * a_Size / 2);
	int DefinitionPointZ = CenterZ - static_cast<int>(zc * a_Size / 2);
	m_Points.push_back(cRavDefPoint(DefinitionPointX, DefinitionPointZ, 0, (Mid + Top) / 2, (Mid + Bottom) / 2));
	for (int i = 1; i < NUM_RAVINE_POINTS - 1; i++)
	{
		int LineX = CenterX + static_cast<int>(xc * a_Size * (i - NUM_RAVINE_POINTS / 2) / NUM_RAVINE_POINTS);
		int LineZ = CenterZ + static_cast<int>(zc * a_Size * (i - NUM_RAVINE_POINTS / 2) / NUM_RAVINE_POINTS);
		// Amplitude is the amount of blocks that this point is away from the ravine "axis"
		int Amplitude = (a_Noise.IntNoise3DInt(70 * a_BlockX, 20 * a_BlockZ + 31 * i, 10000 * i) / 9) % a_Size;
		Amplitude = Amplitude / 4 - a_Size / 8;  // Amplitude is in interval [-a_Size / 4, a_Size / 4]
		int PointX = LineX + static_cast<int>(zc * Amplitude);
		int PointZ = LineZ - static_cast<int>(xc * Amplitude);
		int Radius = MaxRadius - abs(i - NUM_RAVINE_POINTS / 2);  // TODO: better radius function
		int ThisTop    = Top    + ((a_Noise.IntNoise3DInt(7 *  a_BlockX, 19 * a_BlockZ, i * 31) / 13) % 8) - 4;
		int ThisBottom = Bottom + ((a_Noise.IntNoise3DInt(19 * a_BlockX, 7 *  a_BlockZ, i * 31) / 13) % 8) - 4;
		m_Points.push_back(cRavDefPoint(PointX, PointZ, Radius, ThisTop, ThisBottom));
	}  // for i - m_Points[]
	DefinitionPointX = CenterX + static_cast<int>(xc * a_Size / 2);
	DefinitionPointZ = CenterZ + static_cast<int>(zc * a_Size / 2);
	m_Points.push_back(cRavDefPoint(DefinitionPointX, DefinitionPointZ, 0, Mid, Mid));
}
Exemple #12
0
inline void PushSomeColumns(int a_BlockX, int a_Height, int a_BlockZ, int a_ColumnHeight, int a_Seq, cNoise & a_Noise, int a_Chance, sSetBlockVector & a_Blocks, const sMetaCoords * a_Coords, size_t a_NumCoords, BLOCKTYPE a_BlockType)
{
	for (size_t i = 0; i < a_NumCoords; i++)
	{
		int x = a_BlockX + a_Coords[i].x;
		int z = a_BlockZ + a_Coords[i].z;
		if (a_Noise.IntNoise3DInt(x + 64 * a_Seq, a_Height + i, z + 64 * a_Seq) <= a_Chance)
		{
			for (int j = 0; j < a_ColumnHeight; j++)
			{
				a_Blocks.push_back(sSetBlock(x, a_Height - j, z, a_BlockType, a_Coords[i].Meta));
			}
		}
	}  // for i - a_Coords[]
}
Exemple #13
0
void GetPineTreeImage(int a_BlockX, int a_BlockY, int a_BlockZ, cNoise & a_Noise, int a_Seq, sSetBlockVector & a_LogBlocks, sSetBlockVector & a_OtherBlocks)
{
	// Tall, little leaves on top. The top leaves are arranged in a shape of two cones joined by their bases.
	// There can be one or two layers representing the cone bases (SameSizeMax)
	
	int MyRandom = a_Noise.IntNoise3DInt(a_BlockX + 32 * a_Seq, a_BlockY, a_BlockZ + 32 * a_Seq) / 8;
	int TrunkHeight = 8 + (MyRandom % 3);
	int SameSizeMax = ((MyRandom & 8) == 0) ? 1 : 0;
	MyRandom >>= 3;
	int NumLeavesLayers = 2 + (MyRandom % 3);  // Number of layers that have leaves in them
	if (NumLeavesLayers == 2)
	{
		SameSizeMax = 0;
	}
	
	// Pre-allocate the vector:
	a_LogBlocks.reserve(TrunkHeight);
	a_OtherBlocks.reserve(NumLeavesLayers * 25);

	// The entire trunk, out of logs:
	for (int i = TrunkHeight; i >= 0; --i)
	{
		a_LogBlocks.push_back(sSetBlock(a_BlockX, a_BlockY + i, a_BlockZ, E_BLOCK_LOG, E_META_LOG_CONIFER));
	}
	int h = a_BlockY + TrunkHeight + 2;

	// Top layer - just a single leaves block:	
	a_OtherBlocks.push_back(sSetBlock(a_BlockX, h, a_BlockZ, E_BLOCK_LEAVES, E_META_LEAVES_CONIFER));
	h--;

	// One more layer is above the trunk, push the central leaves:	
	a_OtherBlocks.push_back(sSetBlock(a_BlockX, h, a_BlockZ, E_BLOCK_LEAVES, E_META_LEAVES_CONIFER));

	// Layers expanding in size, then collapsing again:
	// LOGD("Generating %d layers of pine leaves, SameSizeMax = %d", NumLeavesLayers, SameSizeMax);
	for (int i = 0; i < NumLeavesLayers; ++i)
	{
		int LayerSize = std::min(i, NumLeavesLayers - i + SameSizeMax - 1);
		// LOGD("LayerSize %d: %d", i, LayerSize);
		if (LayerSize < 0)
		{
			break;
		}
		ASSERT(LayerSize < ARRAYCOUNT(BigOs));
		PushCoordBlocks(a_BlockX, h, a_BlockZ, a_OtherBlocks, BigOs[LayerSize].Coords, BigOs[LayerSize].Count, E_BLOCK_LEAVES, E_META_LEAVES_CONIFER);
		h--;
	}
}
Exemple #14
0
int cStructGenWormNestCaves::cCaveSystem::GetRadius(cNoise & a_Noise, int a_OriginX, int a_OriginY, int a_OriginZ)
{
	// Instead of a flat distribution noise function, we need to shape it, so that most caves are smallish and only a few select are large
	int rnd = a_Noise.IntNoise3DInt(a_OriginX, a_OriginY, a_OriginZ) / 11;
	/*
	// Not good enough:
	// The algorithm of choice: emulate gauss-distribution noise by adding 3 flat noises, then fold it in half using absolute value.
	// To save on processing, use one random value and extract 3 bytes to be separately added as the gaussian noise
	int sum = (rnd & 0xff) + ((rnd >> 8) & 0xff) + ((rnd >> 16) & 0xff);
	// sum is now a gaussian-distribution noise within [0 .. 767], with center at 384.
	// We want mapping 384 -> 3, 0 -> 19, 768 -> 19, so divide by 24 to get [0 .. 31] with center at 16, then use abs() to fold around the center
	int res = 3 + abs((sum / 24) - 16);
	*/

	// Algorithm of choice: random value in the range of zero to random value - heavily towards zero
	int res = MIN_RADIUS + (rnd >> 8) % ((rnd % (MAX_RADIUS - MIN_RADIUS)) + 1);
	return res;
}
Exemple #15
0
void GetLargeJungleTreeImage(int a_BlockX, int a_BlockY, int a_BlockZ, cNoise & a_Noise, int a_Seq, sSetBlockVector & a_LogBlocks, sSetBlockVector & a_OtherBlocks)
{
	// TODO: Generate proper jungle trees with branches

	// Vines are around the BigO4, but not in the corners; need proper meta for direction
	static const sMetaCoords Vines[] =
	{
		{-2, -5, 1}, {-1, -5, 1}, {0, -5, 1}, {1, -5, 1}, {2, -5, 1},  // North face
		{-2,  5, 4}, {-1,  5, 4}, {0,  5, 4}, {1,  5, 4}, {2,  5, 4},  // South face
		{5,  -2, 2}, {5,  -1, 2}, {5,  0, 2}, {5,  1, 2}, {5,  2, 2},  // East face
		{-5, -2, 8}, {-5, -1, 8}, {-5, 0, 8}, {-5, 1, 8}, {-5, 2, 8},  // West face
		// TODO: vines around the trunk, proper metas and height
	} ;
	
	int Height = 24 + (a_Noise.IntNoise3DInt(a_BlockX + 32 * a_Seq, a_BlockY, a_BlockZ + 32 * a_Seq) / 11) % 24;
	
	a_LogBlocks.reserve(Height * 4);
	a_OtherBlocks.reserve(2 * ARRAYCOUNT(BigO4) + ARRAYCOUNT(BigO3) + Height * ARRAYCOUNT(Vines) + 50);
	
	for (int i = 0; i < Height; i++)
	{
		a_LogBlocks.push_back(sSetBlock(a_BlockX,     a_BlockY + i, a_BlockZ,     E_BLOCK_LOG, E_META_LOG_JUNGLE));
		a_LogBlocks.push_back(sSetBlock(a_BlockX + 1, a_BlockY + i, a_BlockZ,     E_BLOCK_LOG, E_META_LOG_JUNGLE));
		a_LogBlocks.push_back(sSetBlock(a_BlockX,     a_BlockY + i, a_BlockZ + 1, E_BLOCK_LOG, E_META_LOG_JUNGLE));
		a_LogBlocks.push_back(sSetBlock(a_BlockX + 1, a_BlockY + i, a_BlockZ + 1, E_BLOCK_LOG, E_META_LOG_JUNGLE));
	}
	int hei = a_BlockY + Height - 2;
	
	// Put vines around the lowermost leaves layer:
	PushSomeColumns(a_BlockX, hei, a_BlockZ, Height, a_Seq, a_Noise, 0x3fffffff, a_OtherBlocks, Vines, ARRAYCOUNT(Vines), E_BLOCK_VINES);
	
	// The lower two leaves layers are BigO4 with log in the middle and possibly corners:
	for (int i = 0; i < 2; i++)
	{
		PushCoordBlocks(a_BlockX, hei, a_BlockZ, a_OtherBlocks, BigO4, ARRAYCOUNT(BigO4), E_BLOCK_LEAVES, E_META_LEAVES_JUNGLE);
		PushCornerBlocks(a_BlockX, hei, a_BlockZ, a_Seq, a_Noise, 0x5fffffff, a_OtherBlocks, 3, E_BLOCK_LEAVES, E_META_LEAVES_JUNGLE);
		hei++;
	}  // for i - 2*

	// The top leaves layer is a BigO3 with leaves in the middle and possibly corners:
	PushCoordBlocks(a_BlockX, hei, a_BlockZ, a_OtherBlocks, BigO3, ARRAYCOUNT(BigO3), E_BLOCK_LEAVES, E_META_LEAVES_JUNGLE);
	PushCornerBlocks(a_BlockX, hei, a_BlockZ, a_Seq, a_Noise, 0x5fffffff, a_OtherBlocks, 3, E_BLOCK_LEAVES, E_META_LEAVES_JUNGLE);
	a_OtherBlocks.push_back(sSetBlock(a_BlockX, hei, a_BlockZ, E_BLOCK_LEAVES, E_META_LEAVES_JUNGLE));
}
Exemple #16
0
void GetSwampTreeImage(int a_BlockX, int a_BlockY, int a_BlockZ, cNoise & a_Noise, int a_Seq, sSetBlockVector & a_LogBlocks, sSetBlockVector & a_OtherBlocks)
{
	// Vines are around the BigO3, but not in the corners; need proper meta for direction
	static const sMetaCoords Vines[] =
	{
		{-2, -4, 1}, {-1, -4, 1}, {0, -4, 1}, {1, -4, 1}, {2, -4, 1},  // North face
		{-2,  4, 4}, {-1,  4, 4}, {0,  4, 4}, {1,  4, 4}, {2,  4, 4},  // South face
		{4,  -2, 2}, {4,  -1, 2}, {4,  0, 2}, {4,  1, 2}, {4,  2, 2},  // East face
		{-4, -2, 8}, {-4, -1, 8}, {-4, 0, 8}, {-4, 1, 8}, {-4, 2, 8},  // West face
	} ;

	int Height = 3 + (a_Noise.IntNoise3DInt(a_BlockX + 32 * a_Seq, a_BlockY, a_BlockZ + 32 * a_Seq) / 8) % 3;
	
	a_LogBlocks.reserve(Height);
	a_OtherBlocks.reserve(2 * ARRAYCOUNT(BigO2) + 2 * ARRAYCOUNT(BigO3) + Height * ARRAYCOUNT(Vines) + 20);
	
	for (int i = 0; i < Height; i++)
	{
		a_LogBlocks.push_back(sSetBlock(a_BlockX, a_BlockY + i, a_BlockZ, E_BLOCK_LOG, E_META_LOG_APPLE));
	}
	int hei = a_BlockY + Height - 2;
	
	// Put vines around the lowermost leaves layer:
	PushSomeColumns(a_BlockX, hei, a_BlockZ, Height, a_Seq, a_Noise, 0x3fffffff, a_OtherBlocks, Vines, ARRAYCOUNT(Vines), E_BLOCK_VINES);
	
	// The lower two leaves layers are BigO3 with log in the middle and possibly corners:
	for (int i = 0; i < 2; i++)
	{
		PushCoordBlocks(a_BlockX, hei, a_BlockZ, a_OtherBlocks, BigO3, ARRAYCOUNT(BigO3), E_BLOCK_LEAVES, E_META_LEAVES_APPLE);
		PushCornerBlocks(a_BlockX, hei, a_BlockZ, a_Seq, a_Noise, 0x5fffffff, a_OtherBlocks, 3, E_BLOCK_LEAVES, E_META_LEAVES_APPLE);
		hei++;
	}  // for i - 2*

	// The upper two leaves layers are BigO2 with leaves in the middle and possibly corners:
	for (int i = 0; i < 2; i++)
	{
		PushCoordBlocks(a_BlockX, hei, a_BlockZ, a_OtherBlocks, BigO2, ARRAYCOUNT(BigO2), E_BLOCK_LEAVES, E_META_LEAVES_APPLE);
		PushCornerBlocks(a_BlockX, hei, a_BlockZ, a_Seq, a_Noise, 0x5fffffff, a_OtherBlocks, 3, E_BLOCK_LEAVES, E_META_LEAVES_APPLE);
		a_OtherBlocks.push_back(sSetBlock(a_BlockX, hei, a_BlockZ, E_BLOCK_LEAVES, E_META_LEAVES_APPLE));
		hei++;
	}  // for i - 2*
}
Exemple #17
0
	virtual int GetPieceWeight(
		const cPlacedPiece & a_PlacedPiece,
		const cPiece::cConnector & a_ExistingConnector,
		const cPiece & a_NewPiece
	) override
	{
		// Check against the density:
		if (a_ExistingConnector.m_Type == 1)
		{
			const Vector3i & Coords = a_PlacedPiece.GetRotatedConnector(a_ExistingConnector).m_Pos;
			int rnd = (m_Noise.IntNoise3DInt(Coords.x, Coords.y, Coords.z) / 7) % 100;
			if (rnd > m_Density)
			{
				return 0;
			}
		}
		
		// Density check passed, relay to m_Prefabs:
		return m_Prefabs.GetPieceWeight(a_PlacedPiece, a_ExistingConnector, a_NewPiece);
	}
Exemple #18
0
void cCaveTunnel::Randomize(cNoise & a_Noise)
{
	// Repeat 4 times:
	for (int i = 0; i < 4; i++)
	{
		// For each already present point, insert a point in between it and its predecessor, shifted randomly.
		cCaveDefPoint & Point = m_Points.front();
		int PrevX = Point.m_BlockX;
		int PrevY = Point.m_BlockY;
		int PrevZ = Point.m_BlockZ;
		int PrevR = Point.m_Radius;
		cCaveDefPoints Pts;
		Pts.reserve(m_Points.size() * 2 + 1);
		Pts.push_back(Point);
		for (cCaveDefPoints::const_iterator itr = m_Points.begin() + 1, end = m_Points.end(); itr != end; ++itr)
		{
			int Random = a_Noise.IntNoise3DInt(PrevX, PrevY, PrevZ + i) / 11;
			int len = (PrevX - itr->m_BlockX) * (PrevX - itr->m_BlockX);
			len += (PrevY - itr->m_BlockY) * (PrevY - itr->m_BlockY);
			len += (PrevZ - itr->m_BlockZ) * (PrevZ - itr->m_BlockZ);
			len = 3 * static_cast<int>(sqrt(static_cast<double>(len))) / 4;
			int Rad = std::min(MAX_RADIUS, std::max(MIN_RADIUS, (PrevR + itr->m_Radius) / 2 + (Random % 3) - 1));
			Random /= 4;
			int x = (itr->m_BlockX + PrevX) / 2 + (Random % (len + 1) - len / 2);
			Random /= 256;
			int y = (itr->m_BlockY + PrevY) / 2 + (Random % (len / 2 + 1) - len / 4);
			Random /= 256;
			int z = (itr->m_BlockZ + PrevZ) / 2 + (Random % (len + 1) - len / 2);
			Pts.push_back(cCaveDefPoint(x, y, z, Rad));
			Pts.push_back(*itr);
			PrevX = itr->m_BlockX;
			PrevY = itr->m_BlockY;
			PrevZ = itr->m_BlockZ;
			PrevR = itr->m_Radius;
		}
		std::swap(Pts, m_Points);
	}
}
Exemple #19
0
	/** Returns the pattern to use for an ocean floor in the specified column.
	The returned pattern is guaranteed to be 256 blocks long. */
	const cPattern::BlockInfo * ChooseOceanFloorPattern(int a_ChunkX, int a_ChunkZ, int a_RelX, int a_RelZ)
	{
		// Frequencies for the ocean floor selecting noise:
		const NOISE_DATATYPE FrequencyX = 3;
		const NOISE_DATATYPE FrequencyZ = 3;

		// Select the ocean-floor pattern to use:
		NOISE_DATATYPE NoiseX = ((NOISE_DATATYPE)(a_ChunkX * cChunkDef::Width + a_RelX)) / FrequencyX;
		NOISE_DATATYPE NoiseY = ((NOISE_DATATYPE)(a_ChunkZ * cChunkDef::Width + a_RelZ)) / FrequencyZ;
		NOISE_DATATYPE Val = m_OceanFloorSelect.CubicNoise2D(NoiseX, NoiseY);
		if (Val < -0.95)
		{
			return patOFClay.Get();
		}
		else if (Val < 0)
		{
			return patOFSand.Get();
		}
		else
		{
			return patDirt.Get();
		}
	}
Exemple #20
0
	/** Recursively subdivides the line between the points of the specified index.
	Sets the midpoint to the center of the line plus or minus a random offset, then calls itself for each half
	of the new line. */
	void SubdivideLine(int a_Idx1, int a_Idx2)
	{
		// Calculate the midpoint:
		const sRavineDefPoint & p1 = m_DefPoints[a_Idx1];
		const sRavineDefPoint & p2 = m_DefPoints[a_Idx2];
		float MidX = (p1.m_X + p2.m_X) / 2;
		float MidZ = (p1.m_Z + p2.m_Z) / 2;
		float MidR = (p1.m_Radius + p2.m_Radius) / 2 + 0.1f;
		float MidT = (p1.m_Top    + p2.m_Top)    / 2;
		float MidB = (p1.m_Bottom + p2.m_Bottom) / 2;

		// Adjust the midpoint by a small amount of perpendicular vector in a random one of its two directions:
		float dx = p2.m_X - p1.m_X;
		float dz = p2.m_Z - p1.m_Z;
		if ((m_Noise.IntNoise2DInt((int)MidX, (int)MidZ) / 11) % 2 == 0)
		{
			MidX += dz * m_Roughness;
			MidZ -= dx * m_Roughness;
		}
		else
		{
			MidX -= dz * m_Roughness;
			MidZ += dx * m_Roughness;
		}
		int MidIdx = (a_Idx1 + a_Idx2) / 2;
		m_DefPoints[MidIdx].Set(MidX, MidZ, MidR, MidT, MidB);
		
		// Recurse the two halves, if they are worth recursing:
		if (MidIdx - a_Idx1 > 1)
		{
			SubdivideLine(a_Idx1, MidIdx);
		}
		if (a_Idx2 - MidIdx > 1)
		{
			SubdivideLine(MidIdx, a_Idx2);
		}
	}
Exemple #21
0
void GetAcaciaTreeImage(int a_BlockX, int a_BlockY, int a_BlockZ, cNoise & a_Noise, int a_Seq, sSetBlockVector & a_LogBlocks, sSetBlockVector & a_OtherBlocks)
{
	// Calculate a base height
	int Height = 2 + (a_Noise.IntNoise3DInt(a_BlockX, a_BlockY, a_BlockZ) / 11 % 3);
	
	// Create the trunk
	for (int i = 0; i < Height; i++)
	{
		a_LogBlocks.push_back(sSetBlock(a_BlockX, a_BlockY + i, a_BlockZ, E_BLOCK_NEW_LOG, E_META_NEW_LOG_ACACIA_WOOD));
	}

	// Array with possible directions for a branch to go to.
	const Vector3i AvailableDirections[] =
	{
		{ -1, 1, 0 }, { 0, 1, -1 },
		{ -1, 1, 1 }, { -1, 1, -1 },
		{ 1, 1, 1 }, { 1, 1, -1 },
		{ 1, 1, 0 }, { 0, 1, 1 },
	};

	// Set the starting point of the branch
	Vector3i BranchPos = Vector3i(a_BlockX, a_BlockY + Height - 1, a_BlockZ);

	// Get a direction for the trunk to go to.
	Vector3i BranchDirection = AvailableDirections[a_Noise.IntNoise3DInt(a_BlockX, a_BlockY, a_BlockZ) % 8];

	// Calculate a height for the branch between 1 and 3
	int BranchHeight = a_Noise.IntNoise3DInt(a_BlockX, a_BlockY, a_BlockZ) % 3 + 1;

	// Place the logs of the branch.
	for (int i = 0; i < BranchHeight; i++)
	{
		BranchPos = BranchPos + BranchDirection;
		a_LogBlocks.push_back(sSetBlock(BranchPos.x, BranchPos.y, BranchPos.z, E_BLOCK_NEW_LOG, E_META_NEW_LOG_ACACIA_WOOD));
	}

	// Add the leaves to the top of the branch
	PushCoordBlocks(BranchPos.x, BranchPos.y, BranchPos.z, a_OtherBlocks, BigO2, ARRAYCOUNT(BigO2), E_BLOCK_NEW_LEAVES, E_META_NEW_LEAVES_ACACIA_WOOD);
	PushCoordBlocks(BranchPos.x, BranchPos.y + 1, BranchPos.z, a_OtherBlocks, BigO1, ARRAYCOUNT(BigO1), E_BLOCK_NEW_LEAVES, E_META_NEW_LEAVES_ACACIA_WOOD);
	a_OtherBlocks.push_back(sSetBlock(BranchPos.x, BranchPos.y + 1, BranchPos.z, E_BLOCK_NEW_LEAVES, E_META_NEW_LEAVES_ACACIA_WOOD));

	// Choose if we have to add another branch
	bool TwoTop = (a_Noise.IntNoise3D(a_BlockX, a_BlockY, a_BlockZ) < 0 ? true : false);
	if (!TwoTop)
	{
		return;
	}

	// Reset the starting point of the branch
	BranchPos = Vector3i(a_BlockX, a_BlockY + Height - 1, a_BlockZ);

	// Invert the direction of the previous branch.
	BranchDirection = Vector3d(-BranchDirection.x, 1, -BranchDirection.z);

	// Calculate a new height for the second branch
	BranchHeight = a_Noise.IntNoise3DInt(a_BlockX * a_Seq, a_BlockY * a_Seq * 10, a_BlockZ * a_Seq) % 3 + 1;

	// Place the logs in the same way as the first branch
	for (int i = 0; i < BranchHeight; i++)
	{
		BranchPos = BranchPos + BranchDirection;
		a_LogBlocks.push_back(sSetBlock(BranchPos.x, BranchPos.y, BranchPos.z, E_BLOCK_NEW_LOG, E_META_NEW_LOG_ACACIA_WOOD));
	}

	// And add the leaves ontop of the second branch
	PushCoordBlocks(BranchPos.x, BranchPos.y, BranchPos.z, a_OtherBlocks, BigO2, ARRAYCOUNT(BigO2), E_BLOCK_NEW_LEAVES, E_META_NEW_LEAVES_ACACIA_WOOD);
	PushCoordBlocks(BranchPos.x, BranchPos.y + 1, BranchPos.z, a_OtherBlocks, BigO1, ARRAYCOUNT(BigO1), E_BLOCK_NEW_LEAVES, E_META_NEW_LEAVES_ACACIA_WOOD);
	a_OtherBlocks.push_back(sSetBlock(BranchPos.x, BranchPos.y + 1, BranchPos.z, E_BLOCK_NEW_LEAVES, E_META_NEW_LEAVES_ACACIA_WOOD));
}
Exemple #22
0
void GetTreeImageByBiome(int a_BlockX, int a_BlockY, int a_BlockZ, cNoise & a_Noise, int a_Seq, EMCSBiome a_Biome, sSetBlockVector & a_LogBlocks, sSetBlockVector & a_OtherBlocks)
{
	switch (a_Biome)
	{
		case biPlains:
		case biExtremeHills:
		case biExtremeHillsEdge:
		case biForest:
		case biMushroomIsland:
		case biMushroomShore:
		case biForestHills:
		case biDeepOcean:
		case biStoneBeach:
		case biColdBeach:
		{
			// Apple or birch trees:
			if (a_Noise.IntNoise3DInt(a_BlockX, a_BlockY + 16 * a_Seq, a_BlockZ + 16 * a_Seq) < 0x5fffffff)
			{
				GetAppleTreeImage(a_BlockX, a_BlockY, a_BlockZ, a_Noise, a_Seq, a_LogBlocks, a_OtherBlocks);
			}
			else
			{
				GetBirchTreeImage(a_BlockX, a_BlockY, a_BlockZ, a_Noise, a_Seq, a_LogBlocks, a_OtherBlocks);
			}
			break;
		}
		
		case biTaiga:
		case biIcePlains:
		case biIceMountains:
		case biTaigaHills:
		{
			// Conifers
			GetConiferTreeImage(a_BlockX, a_BlockY, a_BlockZ, a_Noise, a_Seq, a_LogBlocks, a_OtherBlocks);
			break;
		}
		
		case biSwampland:
		{
			// Swamp trees:
			GetSwampTreeImage(a_BlockX, a_BlockY, a_BlockZ, a_Noise, a_Seq, a_LogBlocks, a_OtherBlocks);
			break;
		}
		
		case biJungle:
		case biJungleHills:
		case biJungleEdge:
		{
			// Apple bushes, large jungle trees, small jungle trees
			if (a_Noise.IntNoise3DInt(a_BlockX, a_BlockY + 16 * a_Seq, a_BlockZ + 16 * a_Seq) < 0x6fffffff)
			{
				GetAppleBushImage(a_BlockX, a_BlockY, a_BlockZ, a_Noise, a_Seq, a_LogBlocks, a_OtherBlocks);
			}
			else 
			{
				GetJungleTreeImage(a_BlockX, a_BlockY, a_BlockZ, a_Noise, a_Seq, a_LogBlocks, a_OtherBlocks);
			}
			break;
		}
		
		case biBirchForest:
		case biBirchForestHills:
		{
			GetBirchTreeImage(a_BlockX, a_BlockY, a_BlockZ, a_Noise, a_Seq, a_LogBlocks, a_OtherBlocks);
			break;
		}
		
		case biRoofedForest:
		case biColdTaiga:
		case biColdTaigaHills:
		case biMegaTaiga:
		case biMegaTaigaHills:
		case biExtremeHillsPlus:
		case biSavanna:
		case biSavannaPlateau:
		case biMesa:
		case biMesaPlateauF:
		case biMesaPlateau:
		case biSunflowerPlains:
		case biDesertM:
		case biExtremeHillsM:
		case biFlowerForest:
		case biTaigaM:
		case biSwamplandM:
		case biIcePlainsSpikes:
		case biJungleM:
		case biJungleEdgeM:
		case biBirchForestM:
		case biBirchForestHillsM:
		case biRoofedForestM:
		case biColdTaigaM:
		case biMegaSpruceTaiga:
		case biMegaSpruceTaigaHills:
		case biExtremeHillsPlusM:
		case biSavannaM:
		case biSavannaPlateauM:
		case biMesaBryce:
		case biMesaPlateauFM:
		case biMesaPlateauM:
		{
			// TODO: These need their special trees
			GetBirchTreeImage(a_BlockX, a_BlockY, a_BlockZ, a_Noise, a_Seq, a_LogBlocks, a_OtherBlocks);
			break;
		}
	}
}
Exemple #23
0
void GetTreeImageByBiome(int a_BlockX, int a_BlockY, int a_BlockZ, cNoise & a_Noise, int a_Seq, EMCSBiome a_Biome, sSetBlockVector & a_LogBlocks, sSetBlockVector & a_OtherBlocks)
{
	switch (a_Biome)
	{
		case biPlains:
		case biExtremeHills:
		case biExtremeHillsEdge:
		case biForest:
		case biMushroomIsland:
		case biMushroomShore:
		case biForestHills:
		case biDeepOcean:
		case biStoneBeach:
		case biColdBeach:
		{
			// Apple or birch trees:
			if (a_Noise.IntNoise3DInt(a_BlockX, a_BlockY + 16 * a_Seq, a_BlockZ + 16 * a_Seq) < 0x5fffffff)
			{
				GetAppleTreeImage(a_BlockX, a_BlockY, a_BlockZ, a_Noise, a_Seq, a_LogBlocks, a_OtherBlocks);
			}
			else
			{
				GetBirchTreeImage(a_BlockX, a_BlockY, a_BlockZ, a_Noise, a_Seq, a_LogBlocks, a_OtherBlocks);
			}
			return;
		}
		
		case biTaiga:
		case biIcePlains:
		case biIceMountains:
		case biTaigaHills:
		{
			// Conifers
			GetConiferTreeImage(a_BlockX, a_BlockY, a_BlockZ, a_Noise, a_Seq, a_LogBlocks, a_OtherBlocks);
			return;
		}
		
		case biSwamplandM:
		case biSwampland:
		{
			// Swamp trees:
			GetSwampTreeImage(a_BlockX, a_BlockY, a_BlockZ, a_Noise, a_Seq, a_LogBlocks, a_OtherBlocks);
			return;
		}
		
		case biJungle:
		case biJungleHills:
		case biJungleEdge:
		{
			// Apple bushes, large jungle trees, small jungle trees
			if (a_Noise.IntNoise3DInt(a_BlockX, a_BlockY + 16 * a_Seq, a_BlockZ + 16 * a_Seq) < 0x6fffffff)
			{
				GetAppleBushImage(a_BlockX, a_BlockY, a_BlockZ, a_Noise, a_Seq, a_LogBlocks, a_OtherBlocks);
			}
			else
			{
				bool IsLarge = a_Noise.IntNoise3DInt(a_BlockX + 32 * a_Seq, a_BlockY + 32 * a_Seq, a_BlockZ) < 0x60000000;
				GetJungleTreeImage(a_BlockX, a_BlockY, a_BlockZ, a_Noise, a_Seq, a_LogBlocks, a_OtherBlocks, IsLarge);
			}
			return;
		}
		
		case biBirchForest:
		case biBirchForestHills:
		{
			GetBirchTreeImage(a_BlockX, a_BlockY, a_BlockZ, a_Noise, a_Seq, a_LogBlocks, a_OtherBlocks);
			return;
		}

		case biBirchForestM:
		case biBirchForestHillsM:
		{
			GetTallBirchTreeImage(a_BlockX, a_BlockY, a_BlockZ, a_Noise, a_Seq, a_LogBlocks, a_OtherBlocks);
			return;
		}

		case biColdTaiga:
		case biColdTaigaHills:
		case biMegaTaiga:
		case biMegaTaigaHills:
		case biExtremeHillsPlus:
		case biSunflowerPlains:
		case biDesertM:
		case biExtremeHillsM:
		case biFlowerForest:
		case biTaigaM:
		case biIcePlainsSpikes:
		case biJungleM:
		case biJungleEdgeM:
		case biColdTaigaM:
		case biMegaSpruceTaiga:
		case biMegaSpruceTaigaHills:
		case biExtremeHillsPlusM:
		{
			// TODO: These need their special trees
			GetBirchTreeImage(a_BlockX, a_BlockY, a_BlockZ, a_Noise, a_Seq, a_LogBlocks, a_OtherBlocks);
			return;
		}

		case biSavanna:
		case biSavannaPlateau:
		case biSavannaM:
		case biSavannaPlateauM:
		{
			GetAcaciaTreeImage(a_BlockX, a_BlockY, a_BlockZ, a_Noise, a_Seq, a_LogBlocks, a_OtherBlocks);
			return;
		}

		case biRoofedForest:
		case biRoofedForestM:
		{
			GetDarkoakTreeImage(a_BlockX, a_BlockY, a_BlockZ, a_Noise, a_Seq, a_LogBlocks, a_OtherBlocks);
			return;
		}
			
		case biMesa:
		case biMesaPlateauF:
		case biMesaPlateau:
		case biMesaBryce:
		case biMesaPlateauFM:
		case biMesaPlateauM:
		{
			GetSmallAppleTreeImage(a_BlockX, a_BlockY, a_BlockZ, a_Noise, a_Seq, a_LogBlocks, a_OtherBlocks);
		}

		case biDesert:
		case biDesertHills:
		case biRiver:
		case biBeach:
		case biHell:
		case biSky:
		case biOcean:
		case biFrozenOcean:
		case biFrozenRiver:
		case biVariant:
		case biNumBiomes:
		case biNumVariantBiomes:
		case biInvalidBiome:
		{
			// These biomes have no trees, or are non-biome members of the enum.
			return;
		}
	}
	
	ASSERT(!"Invalid biome type!");
}
Exemple #24
0
	/** Fills the specified column with mesa pattern, based on the column height */
	void FillColumnMesa(cChunkDesc & a_ChunkDesc, int a_RelX, int a_RelZ, const Byte * a_ShapeColumn)
	{
		// Frequencies for the clay floor noise:
		const NOISE_DATATYPE FrequencyX = 50;
		const NOISE_DATATYPE FrequencyZ = 50;

		int Top = a_ChunkDesc.GetHeight(a_RelX, a_RelZ);
		if (Top < m_SeaLevel)
		{
			// The terrain is below sealevel, handle as regular ocean with red sand floor:
			FillColumnPattern(a_ChunkDesc, a_RelX, a_RelZ, patOFOrangeClay.Get(), a_ShapeColumn);
			return;
		}

		NOISE_DATATYPE NoiseX = ((NOISE_DATATYPE)(a_ChunkDesc.GetChunkX() * cChunkDef::Width + a_RelX)) / FrequencyX;
		NOISE_DATATYPE NoiseY = ((NOISE_DATATYPE)(a_ChunkDesc.GetChunkZ() * cChunkDef::Width + a_RelZ)) / FrequencyZ;
		int ClayFloor = m_SeaLevel - 6 + (int)(4.f * m_MesaFloor.CubicNoise2D(NoiseX, NoiseY));
		if (ClayFloor >= Top)
		{
			ClayFloor = Top - 1;
		}
	
		if (Top - m_SeaLevel < 5)
		{
			// Simple case: top is red sand, then hardened clay down to ClayFloor, then stone:
			a_ChunkDesc.SetBlockTypeMeta(a_RelX, Top, a_RelZ, E_BLOCK_SAND, E_META_SAND_RED);
			for (int y = Top - 1; y >= ClayFloor; y--)
			{
				a_ChunkDesc.SetBlockType(a_RelX, y, a_RelZ, E_BLOCK_HARDENED_CLAY);
			}
			for (int y = ClayFloor - 1; y > 0; y--)
			{
				a_ChunkDesc.SetBlockType(a_RelX, y, a_RelZ, E_BLOCK_STONE);
			}
			a_ChunkDesc.SetBlockType(a_RelX, 0, a_RelZ, E_BLOCK_BEDROCK);
			return;
		}
	
		// Difficult case: use the mesa pattern and watch for overhangs:
		int PatternIdx = cChunkDef::Height - (Top - ClayFloor);  // We want the block at index ClayFloor to be pattern's 256th block (first stone)
		const cPattern::BlockInfo * Pattern = m_MesaPattern;
		bool HasHadWater = false;
		for (int y = Top; y > 0; y--)
		{
			if (a_ShapeColumn[y] > 0)
			{
				// "ground" part, use the pattern:
				a_ChunkDesc.SetBlockTypeMeta(a_RelX, y, a_RelZ, Pattern[PatternIdx].m_BlockType, Pattern[PatternIdx].m_BlockMeta);
				PatternIdx++;
				continue;
			}

			if (y >= m_SeaLevel)
			{
				// "air" part, do nothing
				continue;
			}
		
			// "water" part, fill with water and choose new pattern for ocean floor, if not chosen already:
			PatternIdx = 0;
			a_ChunkDesc.SetBlockType(a_RelX, y, a_RelZ, E_BLOCK_STATIONARY_WATER);
			if (HasHadWater)
			{
				continue;
			}
		
			// Select the ocean-floor pattern to use:
			Pattern = ChooseOceanFloorPattern(a_ChunkDesc.GetChunkX(), a_ChunkDesc.GetChunkZ(), a_RelX, a_RelZ);
			HasHadWater = true;
		}  // for y
		a_ChunkDesc.SetBlockType(a_RelX, 0, a_RelZ, E_BLOCK_BEDROCK);

		EMCSBiome MesaVersion = a_ChunkDesc.GetBiome(a_RelX, a_RelZ);
		if ((MesaVersion == biMesaPlateauF) || (MesaVersion == biMesaPlateauFM))
		{
			if (Top < 95 + static_cast<int>(m_MesaFloor.CubicNoise2D(NoiseY * 2, NoiseX * 2) * 6))
			{
				return;
			}

			BLOCKTYPE Block = (m_MesaFloor.CubicNoise2D(NoiseX * 4, NoiseY * 4) < 0) ? E_BLOCK_DIRT : E_BLOCK_GRASS;
			NIBBLETYPE Meta = (Block == E_BLOCK_GRASS) ? 0 : 1;

			a_ChunkDesc.SetBlockTypeMeta(a_RelX, Top, a_RelZ, Block, Meta);
		}
	}
Exemple #25
0
void GetLargeAppleTreeImage(int a_BlockX, int a_BlockY, int a_BlockZ, cNoise & a_Noise, int a_Seq, sSetBlockVector & a_LogBlocks, sSetBlockVector & a_OtherBlocks)
{
	int Height = 7 + a_Noise.IntNoise3DInt(a_BlockX, a_BlockY, a_BlockZ) % 4;

	// Array with possible directions for a branch to go to.
	const Vector3d AvailableDirections[] =
	{
		{ -1, 0, 0 }, { 0, 0, -1  },
		{ -1, 0, 1 }, { -1, 0, -1 },
		{ 1, 0, 1  }, { 1, 0, -1  },
		{ 1, 0, 0  }, { 0, 0, 1   },

		{ -0.5, 0, 0   }, { 0, 0, -0.5    },
		{ -0.5, 0, 0.5 }, { -0.5, 0, -0.5 },
		{ 0.5, 0, 0.5  }, { 0.5, 0, -0.5  },
		{ 0.5, 0, 0    }, { 0, 0, 0.5     },

		{ -1, 0.5, 0 }, { 0, 0.5, -1  },
		{ -1, 0.5, 1 }, { -1, 0.5, -1 },
		{ 1, 0.5, 1  }, { 1, 0.5, -1  },
		{ 1, 0.5, 0  }, { 0, 0.5, 1   },

		{ -0.5, 0.5, 0   },  { 0, 0.5, -0.5    },
		{ -0.5, 0.5, 0.5 },  { -0.5, 0.5, -0.5 },
		{ 0.5, 0.5, 0.5  },  { 0.5, 0.5, -0.5  },
		{ 0.5, 0.5, 0    },  { 0, 0.5, 0.5     },

	};

	// Create branches
	for (int i = 4; i < Height; i++)
	{
		// Get a direction for the trunk to go to.
		Vector3d BranchStartDirection = AvailableDirections[static_cast<size_t>(a_Noise.IntNoise3DInt(a_BlockX, a_BlockY + i, a_BlockZ)) % ARRAYCOUNT(AvailableDirections)];
		Vector3d BranchDirection = AvailableDirections[static_cast<size_t>(a_Noise.IntNoise3DInt(a_BlockX, a_BlockY / i, a_BlockZ)) % ARRAYCOUNT(AvailableDirections)] / 3;

		int BranchLength = 2 + a_Noise.IntNoise3DInt(a_BlockX * a_Seq, a_BlockY * a_Seq, a_BlockZ * a_Seq) % 3;
		GetLargeAppleTreeBranch(a_BlockX, a_BlockY + i, a_BlockZ, BranchLength, BranchStartDirection, BranchDirection, a_BlockY + Height, a_Noise, a_LogBlocks);
	}

	// Place leaves around each log block
	for (auto itr : a_LogBlocks)
	{
		// Get the log's X and Z coordinates
		int X = itr.GetX();
		int Z = itr.GetZ();

		a_OtherBlocks.push_back(sSetBlock(X, itr.m_RelY - 2, Z, E_BLOCK_LEAVES, E_META_LEAVES_APPLE));
		PushCoordBlocks(X, itr.m_RelY - 2, Z, a_OtherBlocks, BigO1, ARRAYCOUNT(BigO1), E_BLOCK_LEAVES, E_META_LEAVES_APPLE);
		for (int y = -1; y <= 1; y++)
		{
			PushCoordBlocks (X, itr.m_RelY + y, Z, a_OtherBlocks, BigO2, ARRAYCOUNT(BigO2), E_BLOCK_LEAVES, E_META_LEAVES_APPLE);
		}
		PushCoordBlocks(X, itr.m_RelY + 2, Z, a_OtherBlocks, BigO1, ARRAYCOUNT(BigO1), E_BLOCK_LEAVES, E_META_LEAVES_APPLE);
		a_OtherBlocks.push_back(sSetBlock(X, itr.m_RelY + 2, Z, E_BLOCK_LEAVES, E_META_LEAVES_APPLE));
	}

	// Trunk:
	for (int i = 0; i < Height; i++)
	{
		a_LogBlocks.push_back(sSetBlock(a_BlockX, a_BlockY + i, a_BlockZ, E_BLOCK_LOG, E_META_LOG_APPLE));
	}
}
Exemple #26
0
void GetSpruceTreeImage(int a_BlockX, int a_BlockY, int a_BlockZ, cNoise & a_Noise, int a_Seq, sSetBlockVector & a_LogBlocks, sSetBlockVector & a_OtherBlocks)
{
	// Spruces have a top section with layer sizes of (0, 1, 0) or only (1, 0),
	// then 1 - 3 sections of ascending sizes (1, 2) [most often], (1, 3) or (1, 2, 3)
	// and an optional bottom section of size 1, followed by 1 - 3 clear trunk blocks
	
	// We'll use bits from this number as partial random numbers; but the noise function has mod8 irregularities
	// (each of the mod8 remainders has a very different chance of occurrence) - that's why we divide by 8
	int MyRandom = a_Noise.IntNoise3DInt(a_BlockX + 32 * a_Seq, a_BlockY + 32 * a_Seq, a_BlockZ) / 8;
	
	static const int  sHeights[] = {1, 2, 2, 3};
	int Height = sHeights[MyRandom & 3];
	MyRandom >>= 2;

	// Prealloc, so that we don't realloc too often later:
	a_LogBlocks.reserve(Height);
	a_OtherBlocks.reserve(180);
	
	// Clear trunk blocks:
	for (int i = 0; i < Height; i++)
	{
		a_LogBlocks.push_back(sSetBlock(a_BlockX, a_BlockY + i, a_BlockZ, E_BLOCK_LOG, E_META_LOG_CONIFER));
	}
	Height += a_BlockY;
	
	// Optional size-1 bottom leaves layer:
	if ((MyRandom & 1) == 0)
	{
		PushCoordBlocks(a_BlockX, Height, a_BlockZ, a_OtherBlocks, BigO1, ARRAYCOUNT(BigO1), E_BLOCK_LEAVES, E_META_LEAVES_CONIFER);
		a_OtherBlocks.push_back(sSetBlock(a_BlockX, Height, a_BlockZ, E_BLOCK_LOG, E_META_LOG_CONIFER));
		Height++;
	}
	MyRandom >>= 1;
	
	// 1 to 3 sections of leaves layers:
	static const int sNumSections[] = {1, 2, 2, 3};
	int NumSections = sNumSections[MyRandom & 3];
	MyRandom >>= 2;
	for (int i = 0; i < NumSections; i++)
	{
		switch (MyRandom & 3)  // SectionType; (1, 2) twice as often as the other two
		{
			case 0:
			case 1:
			{
				PushCoordBlocks(a_BlockX, Height,     a_BlockZ, a_OtherBlocks, BigO2, ARRAYCOUNT(BigO2), E_BLOCK_LEAVES, E_META_LEAVES_CONIFER);
				PushCoordBlocks(a_BlockX, Height + 1, a_BlockZ, a_OtherBlocks, BigO1, ARRAYCOUNT(BigO1), E_BLOCK_LEAVES, E_META_LEAVES_CONIFER);
				a_LogBlocks.push_back(sSetBlock(a_BlockX, Height,     a_BlockZ, E_BLOCK_LOG, E_META_LOG_CONIFER));
				a_LogBlocks.push_back(sSetBlock(a_BlockX, Height + 1, a_BlockZ, E_BLOCK_LOG, E_META_LOG_CONIFER));
				Height += 2;
				break;
			}
			case 2:
			{
				PushCoordBlocks(a_BlockX, Height,     a_BlockZ, a_OtherBlocks, BigO3, ARRAYCOUNT(BigO3), E_BLOCK_LEAVES, E_META_LEAVES_CONIFER);
				PushCoordBlocks(a_BlockX, Height + 1, a_BlockZ, a_OtherBlocks, BigO1, ARRAYCOUNT(BigO1), E_BLOCK_LEAVES, E_META_LEAVES_CONIFER);
				a_LogBlocks.push_back(sSetBlock(a_BlockX, Height,     a_BlockZ, E_BLOCK_LOG, E_META_LOG_CONIFER));
				a_LogBlocks.push_back(sSetBlock(a_BlockX, Height + 1, a_BlockZ, E_BLOCK_LOG, E_META_LOG_CONIFER));
				Height += 2;
				break;
			}
			case 3:
			{
				PushCoordBlocks(a_BlockX, Height,     a_BlockZ, a_OtherBlocks, BigO3, ARRAYCOUNT(BigO3), E_BLOCK_LEAVES, E_META_LEAVES_CONIFER);
				PushCoordBlocks(a_BlockX, Height + 1, a_BlockZ, a_OtherBlocks, BigO2, ARRAYCOUNT(BigO2), E_BLOCK_LEAVES, E_META_LEAVES_CONIFER);
				PushCoordBlocks(a_BlockX, Height + 2, a_BlockZ, a_OtherBlocks, BigO1, ARRAYCOUNT(BigO1), E_BLOCK_LEAVES, E_META_LEAVES_CONIFER);
				a_LogBlocks.push_back(sSetBlock(a_BlockX, Height,     a_BlockZ, E_BLOCK_LOG, E_META_LOG_CONIFER));
				a_LogBlocks.push_back(sSetBlock(a_BlockX, Height + 1, a_BlockZ, E_BLOCK_LOG, E_META_LOG_CONIFER));
				a_LogBlocks.push_back(sSetBlock(a_BlockX, Height + 2, a_BlockZ, E_BLOCK_LOG, E_META_LOG_CONIFER));
				Height += 3;
				break;
			}
		}  // switch (SectionType)
		MyRandom >>= 2;
	}  // for i - Sections
	
	if ((MyRandom & 1) == 0)
	{
		// (0, 1, 0) top:
		a_LogBlocks.push_back  (sSetBlock(a_BlockX, Height,     a_BlockZ, E_BLOCK_LOG, E_META_LOG_CONIFER));
		PushCoordBlocks                  (a_BlockX, Height + 1, a_BlockZ, a_OtherBlocks, BigO1, ARRAYCOUNT(BigO1), E_BLOCK_LEAVES, E_META_LEAVES_CONIFER);
		a_OtherBlocks.push_back(sSetBlock(a_BlockX, Height + 1, a_BlockZ, E_BLOCK_LEAVES, E_META_LEAVES_CONIFER));
		a_OtherBlocks.push_back(sSetBlock(a_BlockX, Height + 2, a_BlockZ, E_BLOCK_LEAVES, E_META_LEAVES_CONIFER));
	}
	else
	{
		// (1, 0) top:
		a_OtherBlocks.push_back(sSetBlock(a_BlockX, Height,     a_BlockZ, E_BLOCK_LEAVES, E_META_LEAVES_CONIFER));
		PushCoordBlocks                  (a_BlockX, Height + 1, a_BlockZ, a_OtherBlocks, BigO1, ARRAYCOUNT(BigO1), E_BLOCK_LEAVES, E_META_LEAVES_CONIFER);
		a_OtherBlocks.push_back(sSetBlock(a_BlockX, Height + 1, a_BlockZ, E_BLOCK_LEAVES, E_META_LEAVES_CONIFER));
	}
}
Exemple #27
0
	/** Composes a single column in a_ChunkDesc. Chooses what to do based on the biome in that column. */
	void ComposeColumn(cChunkDesc & a_ChunkDesc, int a_RelX, int a_RelZ, const Byte * a_ShapeColumn)
	{
		// Frequencies for the podzol floor selecting noise:
		const NOISE_DATATYPE FrequencyX = 8;
		const NOISE_DATATYPE FrequencyZ = 8;
	
		EMCSBiome Biome = a_ChunkDesc.GetBiome(a_RelX, a_RelZ);
		switch (Biome)
		{
			case biOcean:
			case biPlains:
			case biForest:
			case biTaiga:
			case biSwampland:
			case biRiver:
			case biFrozenOcean:
			case biFrozenRiver:
			case biIcePlains:
			case biIceMountains:
			case biForestHills:
			case biTaigaHills:
			case biExtremeHillsEdge:
			case biExtremeHillsPlus:
			case biExtremeHills:
			case biJungle:
			case biJungleHills:
			case biJungleEdge:
			case biDeepOcean:
			case biStoneBeach:
			case biColdBeach:
			case biBirchForest:
			case biBirchForestHills:
			case biRoofedForest:
			case biColdTaiga:
			case biColdTaigaHills:
			case biSavanna:
			case biSavannaPlateau:
			case biSunflowerPlains:
			case biFlowerForest:
			case biTaigaM:
			case biSwamplandM:
			case biIcePlainsSpikes:
			case biJungleM:
			case biJungleEdgeM:
			case biBirchForestM:
			case biBirchForestHillsM:
			case biRoofedForestM:
			case biColdTaigaM:
			case biSavannaM:
			case biSavannaPlateauM:
			{
				FillColumnPattern(a_ChunkDesc, a_RelX, a_RelZ, patGrass.Get(), a_ShapeColumn);
				return;
			}

			case biMegaTaiga:
			case biMegaTaigaHills:
			case biMegaSpruceTaiga:
			case biMegaSpruceTaigaHills:
			{
				// Select the pattern to use - podzol, grass or grassless dirt:
				NOISE_DATATYPE NoiseX = ((NOISE_DATATYPE)(a_ChunkDesc.GetChunkX() * cChunkDef::Width + a_RelX)) / FrequencyX;
				NOISE_DATATYPE NoiseY = ((NOISE_DATATYPE)(a_ChunkDesc.GetChunkZ() * cChunkDef::Width + a_RelZ)) / FrequencyZ;
				NOISE_DATATYPE Val = m_OceanFloorSelect.CubicNoise2D(NoiseX, NoiseY);
				const cPattern::BlockInfo * Pattern = (Val < -0.9) ? patGrassLess.Get() : ((Val > 0) ? patPodzol.Get() : patGrass.Get());
				FillColumnPattern(a_ChunkDesc, a_RelX, a_RelZ, Pattern, a_ShapeColumn);
				return;
			}

			case biDesertHills:
			case biDesert:
			case biDesertM:
			case biBeach:
			{
				FillColumnPattern(a_ChunkDesc, a_RelX, a_RelZ, patSand.Get(), a_ShapeColumn);
				return;
			}
		
			case biMushroomIsland:
			case biMushroomShore:
			{
				FillColumnPattern(a_ChunkDesc, a_RelX, a_RelZ, patMycelium.Get(), a_ShapeColumn);
				return;
			}

			case biMesa:
			case biMesaPlateauF:
			case biMesaPlateau:
			case biMesaBryce:
			case biMesaPlateauFM:
			case biMesaPlateauM:
			{
				// Mesa biomes need special handling, because they don't follow the usual "4 blocks from top pattern",
				// instead, they provide a "from bottom" pattern with varying base height,
				// usually 4 blocks below the ocean level
				FillColumnMesa(a_ChunkDesc, a_RelX, a_RelZ, a_ShapeColumn);
				return;
			}

			case biExtremeHillsPlusM:
			case biExtremeHillsM:
			{
				// Select the pattern to use - gravel, stone or grass:
				NOISE_DATATYPE NoiseX = ((NOISE_DATATYPE)(a_ChunkDesc.GetChunkX() * cChunkDef::Width + a_RelX)) / FrequencyX;
				NOISE_DATATYPE NoiseY = ((NOISE_DATATYPE)(a_ChunkDesc.GetChunkZ() * cChunkDef::Width + a_RelZ)) / FrequencyZ;
				NOISE_DATATYPE Val = m_OceanFloorSelect.CubicNoise2D(NoiseX, NoiseY);
				const cPattern::BlockInfo * Pattern = (Val < 0.0) ? patStone.Get() : patGrass.Get();
				FillColumnPattern(a_ChunkDesc, a_RelX, a_RelZ, Pattern, a_ShapeColumn);
				return;
			}
			case biInvalidBiome:
			case biHell:
			case biSky:
			case biNumBiomes:
			case biVariant:
			case biNumVariantBiomes:
			{
				ASSERT(!"Unhandled biome");
				return;
			}
		}  // switch (Biome)
	}