brickImage.stateTransitionOnTriggerDown[ 0 ] = "Ready";

$MC::GlobalBlockOffsetZ = 0.5;

exec( "./support.cs" );
exec( "./tick.cs" );
exec( "./mobs.cs" );
exec( "./sun.cs" );

exec( "./sound.cs" );
exec( "./emitters.cs" );
exec( "./bricks.cs" );
exec("./player/player.cs");

exec( "./datablocks.cs" );
exec( "./inventory.cs" );
exec( "./damage.cs" );
exec( "./clear.cs" );

exec( "./biomes.cs" );
exec( "./chunk.cs" );
exec( "./chunk_properties.cs" );
exec( "./chunk_generate.cs" );
exec( "./chunk_saving.cs" );

exec("./testers.cs");
exec("./help.cs");
exec("./adventure.cs");

function initWorld( %name )
{
	if ( strLen( $MC::CurrWorld ) )
	{
		return;
	}
	
	$MC::CurrWorld = %name;
	
	mcTickSO();
	mobGroup();
	chunkGroup();
	createSpawnRegion();
}

function playerMinecraftArmor::onNewDataBlock( %this, %obj )
{
	parent::onNewDataBlock( %this, %obj );
	
	%obj.setScale( "0.65 0.65 0.65" );
	%obj.chunkTick = %obj.schedule( 500, "chunkTick" );
}

function Player::setDimension( %this, %dim )
{
	if ( !strLen( %dim ) )
	{
		return false;
	}
	
	%this.dimension = %dim;
	%this.setTransform( "0 0" SPC 1024 * %dim + 64 );
	
	return true;
}

function Player::chunkTick( %this )
{
	cancel( %this.chunkTick );
	
	%pos = %this.getTransform();
	%pz = getWord( %pos, 2 );
	%pn = 1024 * %this.dimension;
	%pm = 1024 * %this.dimension + 256;
	
	if ( %pz < %pn || %pz > %pm )
	{
		%this.setDimension( %this.dimension );
	}
	
	if ( $MC::Clearing )
	{
		return;
	}
	
	%pos = roundToChunkIndex( %this.getPosition() );
	%px = getWord( %pos, 0 );
	%py = getWord( %pos, 1 );
	
	%radius = 2;
	
	for ( %x = %radius * -1 ; %x <= %radius ; %x++ )
	{
		for ( %y = %radius * -1 ; %y <= %radius ; %y++ )
		{
			%npos = %px + %x SPC %py + %y SPC 0;
			
			if ( vectorDist( %pos, %npos ) > %radius )
			{
				continue;
			}
			
			%chunk = chunkSO( %px + %x, %py + %y, %this.dimension );
		}
	}
	
	%this.chunkTick = %this.schedule( 500, "chunkTick" );
}

function createChunk( %x, %y, %dim )
{
	%chunk = chunkSO( %x, %y, %dim );
}

function createSpawnRegion( %dim )
{
	createChunk( 0, 0, %dim );
	
	for ( %x = -3 ; %x <= 3 ; %x++ )
	{
		for ( %y = -3 ; %y <= 3 ; %y++ )
		{
			if ( vectorDist( %x SPC %y SPC 0, "0 0 0" ) > 3 )
			{
				continue;
			}
			
			if ( %x == 0 && %y == 0 )
			{
				continue;
			}
			
			createChunk( %x, %y, %dim );
		}
	}
}

package mcGame
{
	function gameConnection::onConnectRequest( %this, %a, %b, %c, %d, %e, %f, %g, %h, %i, %j, %k, %l, %m, %n )
	{
		%p = parent::onConnectRequest( %this, %a, %b, %c, %d, %e, %f, %g, %h, %i, %j, %k, %l, %m, %n );
		
		if ( !strLen( $MC::CurrWorld ) )
		{
			return "MC_NO_WORLD";
		}
		
		return %p;
	}
	
	function serverCmdChangeMap() { }
	
	function player::giveDefaultEquipment( %this )
	{
		%this.clearTools();
	}
	
	function gameConnection::getSpawnPoint( %this )
	{
		%start = "0 0 512";
		%mask = $TypeMasks::All;
		%end = "0 0 -1";
		%ray = containerRayCast( %start, %end, %mask );
		
		if ( !%ray )
		{
			return "0 0 0.1";
		}
		
		return getWords( %ray, 1, 3 );
	}
	
	function gameConnection::spawnPlayer( %this )
	{
		%par = parent::spawnPlayer( %this );
		
		if ( isObject( %pl = %this.player ) )
		{
			%pl.setDimension( 0 );
			%pl.changeDataBlock( playerMinecraftArmor );
		}
		
		return %par;
	}
};

activatePackage( "mcGame" );

function getMCBrickGroup()
{
	if ( isObject( %obj = nameToID( "mcBrickGroup" ) ) )
	{
		return %obj;
	}
	
	%obj = new simGroup( "mcBrickGroup" )
	{
		name = "Server";
		bl_id = 50;
		isVirtualBrickGroup = true;
	};
	
	mainBrickGroup.add( %obj );
	
	return %obj;
}

function setBlock( %x, %y, %z, %type, %dim )
{
	if ( !strLen( %dim ) )
	{
		%dim = 0;
	}
	
	%x = mFloor( %x );
	%y = mFloor( %y );
	%z = mFloor( %z );
	
	%chi = roundToChunkIndex( %x SPC %y SPC %z );
	%chx = getWord( %chi, 0 );
	%chy = getWord( %chi, 1 );
	
	if ( !isObject( %chn = chunkSO( %chx, %chy, %dim ) ) || %chn.initializing )
	{
		return;
	}
	
	%pos = vectorSub( %x SPC %y SPC %z, %chn.getPosition() );
	%px = getWord( %pos, 0 );
	%py = getWord( %pos, 1 );
	%pz = getWord( %pos, 2 );
	
	%chn.setBlock( %px, %py, %pz, %type );
}

function getBlock( %x, %y, %z, %t )
{
	%x = mFloor( %x );
	%y = mFloor( %y );
	%z = mFloor( %z );
	
	%chi = roundToChunkIndex( %x SPC %y SPC %z );
	%chx = getWord( %chi, 0 );
	%chy = getWord( %chi, 1 );
	
	if ( !isObject( %chn = chunkSO( %chx, %chy ) ) || %chn.initializing )
	{
		return "";
	}
	
	%pos = vectorSub( %x SPC %y SPC %z, %chn.getPosition() );
	%px = getWord( %pos, 0 );
	%py = getWord( %pos, 1 );
	%pz = getWord( %pos, 2 );
	
	return %chn.getBlock( %px, %py, %pz );
}

function getGroundLevel( %x, %y )
{
	%x = mFloor( %x );
	%y = mFloor( %y );
	
	%chi = roundToChunkIndex( %x SPC %y SPC 0 );
	%chx = getWord( %chi, 0 );
	%chy = getWord( %chi, 1 );
	
	if ( !isObject( %chn = chunkSO( %chx, %chy ) ) || %chn.initializing )
	{
		return 512;
	}
	
	%pos = vectorSub( %x SPC %y SPC 0, %chn.getPosition() );
	%px = getWord( %pos, 0 );
	%py = getWord( %pos, 1 );
	
	return %chn.getTerrainHeight( %px, %py );
}

function generatedPoint( %x, %y, %z )
{
	%x = mFloor( %x );
	%y = mFloor( %y );
	%z = mFloor( %z );
	
	%chi = roundToChunkIndex( %x SPC %y SPC %z );
	%chx = getWord( %chi, 0 );
	%chy = getWord( %chi, 1 );
	
	if ( !isObject( %chn = chunkSO( %chx, %chy ) ) || %chn.initializing )
	{
		return true;
	}
	
	%pos = vectorSub( %x SPC %y SPC %z, %chn.getPosition() );
	%px = getWord( %pos, 0 );
	%py = getWord( %pos, 1 );
	%pz = getWord( %pos, 2 );
	
	return ( %chn.generatedPoint[ %px, %py, %pz ] );
}

schedule(1000,0,initWorld,"world1");