function mcTickSO()
{
	if ( !strLen( $MC::CurrWorld ) )
	{
		return -1;
	}
	
	if ( isObject( %obj = nameToID( "mcTickSO" ) ) )
	{
		return %obj;
	}
	
	%obj = new scriptObject( "mcTickSO" )
	{
		time = 0;
		timeScale = 1;
		currTimeRegion = "day";
	};
	
	%obj.tickSchedule = %obj.schedule( 50, "tick" );
	
	return %obj;
}

function mcTickSO::setTimeScale( %this, %timeScale )
{
	if ( %timeScale < 0.01 )
	{
		%timeScale = 0.01;
	}
	
	if ( %timeScale > 3.12 )
	{
		%timeScale = 3.12;
	}
	
	%this.timeScale = %timeScale;
}

function mcTickSO::tick( %this )
{
	cancel( %this.tickSchedule );
	
	if ( !strLen( $MC::CurrWorld ) )
	{
		%this.schedule( 0, "delete" );
		return;
	}
	
	%this.time %= 24000;
	
	if ( %this.time < 12000 )
	{
		if ( %this.currTimeRegion !$= "day" )
		{
			announce( "\c6It is now \c3Day\c6." );
			%this.currTimeRegion = "day";
		}
	}
	else if ( %this.time < 13800 )
	{
		if ( %this.currTimeRegion !$= "dusk" )
		{
			announce( "\c6It is now \c3Dusk\c6." );
			%this.currTimeRegion = "dusk";
		}
	}
	else if ( %this.time < 22200 )
	{
		if ( %this.currTimeRegion !$= "night" )
		{
			announce( "\c6It is now \c3Night\c6." );
			%this.currTimeRegion = "night";
		}
	}
	else if ( %this.time < 24000 )
	{
		if ( %this.currTimeRegion !$= "dawn" )
		{
			announce( "\c6It is now \c3Dawn\c6." );
			%this.currTimeRegion = "dawn";
		}
	}
	
	%this.mcGameTick();
	%this.mcBlockTick();
	
	if ( %this.time % 2 == 1 )
	{
		%this.mcRedstoneTick();
	}
	
	%this.mcMobSpawnTick( "hostile" );
	
	if ( %this.time % 400 == 0 )
	{
		%this.mcMobSpawnTick( "friendly" );
		%this.mcMobSpawnTick( "water" );
	}
	
	if ( %this.time % 20 == 0 )
	{
		%this.updateSun();
	}
	
	%this.time += %this.timeScale;
	%this.time %= 24000;
	
	%this.tickSchedule = %this.schedule( 50 / %this.timeScale, "tick" );
}

function mcTickSO::updateSun( %this )
{
	%sun = getMapSun();
	
	if ( !isObject( %sun ) )
	{
		return;
	}
	
	%elev = 90;
	%color = "0.7 0.7 0.7 1";
	%ambient = "0.3 0.3 0.3 1";
	
	if ( %this.currTimeRegion $= "day" )
	{
		%factor = %this.time / 12000;
		%value = 130 * %factor;
		if($debug)announce("factor" SPC %factor SPC "value" SPC %value);
		%elev = 25 + %value;
		%color = "0.7 0.7 1 1";
		%ambient = "0.4 0.4 0.4 1";
	}
	else if ( %this.currTimeRegion $= "dusk" )
	{
		%factor = ( %this.time - 12000 ) / 1800;
		%bright = 0.1 + 0.3 - 0.3 * %factor;
		%elev = 155 + 25 * %factor;
		%color = "0.8 0.5 0.16 1";
		%ambient = %bright SPC %bright SPC %bright SPC 1;
	}
	else if ( %this.currTimeRegion $= "night" )
	{
		%color = "0.5 0.1 0.1 1";
		%ambient = "0.1 0.1 0.1 1";
	}
	else if ( %this.currTimeRegion $= "dawn" )
	{
		%factor = ( %this.time - 22200 ) / 1800;
		%bright = 0.1 + 0.3 * %factor;
		%elev = 25 * %factor;
		%color = "0.8 0.5 0.16 1";
		%ambient = %bright SPC %bright SPC %bright SPC 1;
	}
	
	if ( %sun.elevation $= %elev && %sun.color $= %color && %sun.ambient $= %ambient )
	{
		return;
	}
	
	%sun.setName( "_tempSunCopy" );
	
	%obj = new Sun( "" : _tempSunCopy )
	{
		color = %color;
		ambient = %ambient;
		elevation = %elev;
	};
	
	%sun.setName( "" );
	missionGroup.add( %obj );
	
	if ( !isObject( %obj ) )
	{
		return;
	}
	
	%sun.delete();
}

function mcTickSO::mcGameTick( %this )
{
	// Mob AI, health, hunger
	
	return;
	%group = mobGroup();
	%count = %group.getCount();
	
	for ( %i = 0 ; %i < %count ; %i++ )
	{
		%mob = %group.getObject( %i );
		%hpn = false;
		
		initContainerRadiusSearch( %mob.getPosition(), 32, $TypeMasks::PlayerObjectType );
		
		while ( isObject( %obj = containerSearchNext() ) )
		{
			
		}
	}
}

function mcTickSO::mcBlockTick( %this )
{
	// 80 block positions at random from each chunk
	// do something to the block
}

function mcTickSO::mcRedstoneTick( %this )
{
	// Do stuff
}

function mcTickSO::mcMobSpawnTick( %this, %type )
{
	switch$ ( %type )
	{
		case "hostile": %constant = 70;
		case "friendly": %constant = 15;
		case "water": %constant = 5;
		default: return;
	}
	
	%mob_count = 0;
	%limit_count = %constant * chunkGroup().getCount() / 256;
	
	%group = mobGroup();
	%count = %group.getCount();
	
	for ( %i = 0 ; %i < %count ; %i++ )
	{
		%mob = %group.getObject( %i );
		%mob = %mob.getDataBlock();
		
		if ( %mob.mobType !$= %type )
		{
			continue;
		}
		
		if ( %mob_count++ >= %limit_count )
		{
			return;
		}
	}
	
	%group = chunkGroup();
	%count = %group.getCount();
	
	for ( %i = 0 ; %i < %count ; %i++ )
	{
		%group.getObject( %i ).spawnPackRandom( %type );
	}
}

function chunkSO::spawnPackRandom( %this, %type )
{
	%px = getRandom( 0, 15 );
	%py = getRandom( 0, 15 );
	%pz = %this.getTerrainHeight( %px, %py ) + getRandom( 0, 5 );
	
	%block = %this.getBlock( %px, %py, %pz );
	
	if ( %type $= "water" && %block !$= "water" && %block !$= "lava" && %block !$= "stationaryWater" && %block !$= "stationaryLava" )
	{
		return;
	}
	
	if ( %type !$= "water" && %block !$= "" )
	{
		return;
	}
	
	for ( %i = 0 ; %i < 12 ; %i++ )
	{
		if ( %this.attemptSpawnPack( %type, %px, %py, %pz ) )
		{
			break;
		}
	}
}

function chunkSO::attemptSpawnPack( %this, %type, %x, %y, %z )
{
	return true;
}