function chunkSO::generateChunk( %this )
{
	if ( %this.blockCount )
	{
		return;
	}
	
	switch$ ( %this.dimension )
	{
		case 2: %this.generateTheEnd();
		case 1: %this.generateAether();
		case 0: %this.generateOverworld();
		case -1: %this.generateNether();
	}
	
	%this.initializing = false;
	%this.saveChunk();
	%this.unloadCheckTick();
}

// Overworld
function chunkSO::generateOverworld( %this )
{
	// Generate base terrain.
	for ( %x = 0 ; %x < 16 ; %x++ )
	{
		for ( %y = 0 ; %y < 16 ; %y++ )
		{
			%height = %this.getTerrainHeight( %x, %y );
			%biome = %this.getBiome( %x, %y );
			%ground = getBiomeGroundMaterial( %biome );

			if ( !strLen( %ground ) )
			{
				%ground = "smoothStone";
			}
			%this.setBlock( %x, %y, %height, %ground );
			if(%ground $= "grass" && getRandom() <= 0.3)
				%this.setBlock(%x,%y,%height+1,"veggrass");
		}
	}
	
	// Generate trees.
	%tree_count = getRandom( -5, 3 );
		
	for ( %i = 0 ; %i < %tree_count ; %i++ )
	{
		%x = getRandom( 4, 12 );
		%y = getRandom( 4, 12 );
		
		%x = mFloor( %x / 2 ) * 2;
		%y = mFloor( %y / 2 ) * 2;
		
		if ( %water[ %x, %y ] )
		{
			continue;
		}
		
		if ( %madeTree[ %x, %y ] )
		{
			continue;
		}
		
		%madeTree[ %x, %y ] = true;
		
		%this.generateTree( %x, %y );
	}
}

function chunkSO::generateTree( %this, %x, %y )
{
	%terr = %this.getTerrainHeight( %x, %y );
	
	%height = getRandom( 4, 10 );
	%width = getRandom( 3, 5 );
	
	if ( %width >= %height )
	{
		%width = %height - 1;
	}
	
	for ( %z = 1 ; %z <= %height ; %z++ )
	{
		%this.setBlock( %x, %y, %terr + %z, "log" );
	}
	
	%trp = %x SPC %y SPC %terr + %height;
	
	for ( %xi = %x - %width ; %xi <= %x + %width ; %xi++ )
	{
		for ( %yi = %y - %width ; %yi <= %y + %width ; %yi++ )
		{
			for ( %zi = %terr + 1 ; %zi <= %terr + %height + %width ; %zi++ )
			{
				if ( %xi == %x && %yi == %y && %zi <= %terr + %height )
				{
					continue;
				}
				
				if ( vectorDist( %xi SPC %yi SPC %zi, %trp ) > %width )
				{
					continue;
				}
				
				%this.setBlock( %xi, %yi, %zi, "leaves" );
			}
		}
	}
}

function chunkSO::generateBelowTerrain( %px, %py, %pz, %bl, %th, %obj )
{
	if ( $MC::Clearing )
	{
		return;
	}
	
	// px: generate 1 block out from this starting point
	// py: generate 1 block out from this starting point
	// pz: generate 1 block out from this starting point
	// bl: the starting point is this amount of blocks below ground level
	// th: ground level at starting point
	// obj: an object at starting point
	
	//if ( getRandom() <= 0.02 ) // Create a cave system?
	//{
	//	chunkSO::generateBelowCaveSystem( %px, %py, %pz ); // Generate the cave system.
	//	return; // Don't do normal underground generation.
	//}
	
	for ( %x = -1 ; %x <= 1 ; %x++ )
	{
		for ( %y = -1 ; %y <= 1 ; %y++ )
		{
			for ( %z = -1 ; %z <= 1 ; %z++ )
			{
				%rx = %px + %x;
				%ry = %py + %y;
				%rz = %pz + %z;
				
				if ( %x == 0 && %y == 0 && %z == 0 )
				{
					continue;
				}
				
				if ( %rz > %th )  // Does this cause us to arrive on ground?
				{
					continue; // If so, don't screw with ground level; go to next iteration.
				}
				
				if ( %rz < 0 )     // Does this cause us to arrive below bedrock?
				{
					continue; // If so, don't cause index errors; go to next iteration.
				}
				
				if ( %rz > 255 )   // Does this cause us to arrive above world?
				{		  // (note: I'm not sure how this could happen)
					continue; // If so, don't cause index errors; go to next iteration.
				}
				
				if ( strLen( getBlock( %rx, %ry, %rz ) ) ) // Is there already something here?
				{
					continue;			// If so, don't overwrite it; go to next iteration.
				}
				
				if ( generatedPoint( %rx, %ry, %rz ) ) // Did we already generate something here ..
				{					 // .. which was destroyed by some force?
					continue;			 // If so, don't generate it again; go to next iteration.
				}
				
				%dp = %bl - %z; // Determine distance to ground at current point.
				%block = "";
				
				if ( %dp < 3 )
				{
					%block = "dirt";
					
					//if ( getRandom() <= 0.15 )
					//{
					//	%block = "gravel";
					//}
				}
				else
				{
					if ( %rz <= 7 )
					{
						%block = "smoothStone";
					}
					//else if ( %rz <= 10 )
					//{
					//	%block = "lava";
					//}
					else
					{
						%block = "smoothStone";
						
						//if ( getRandom() <= 0.1 )
						//{
						//	%block = "gravel";
						//}
						//else
						//{
						if ( %rz <= 63 && getRandom() <= 0.05 )
						{
							%block = "ironOre";
						}
						else if ( %rz <= 31 && getRandom() <= 0.05 )
						{
							%block = "goldOre";
						}
						
					}
				}
				
				setBlock( %rx, %ry, %rz, %block );
			}
		}
	}
}

// Nether
function chunkSO::generateNether( %this )
{
	%this.generateOverworld();
}

// Aether
function chunkSO::generateAether( %this )
{
	%this.generateOverworld();
}

// The End
function chunkSO::generateTheEnd( %this )
{
	%this.generateOverworld();
}