// Primary: Destroy Block
// Secondary: Use Item/Use Block/Place Block

// Variables.
$MC::ActionRate = 500;
$MC::Destroy::Range = 6;
$MC::Destroy::Mask = $TypeMasks::fxBrickObjectType;
$MC::Destroy::TickTear = 1;
$MC::Interact::Range = 8;
$MC::Interact::Mask = $TypeMasks::fxBrickObjectType;

// Misc.
function fxDTSBrick::mcDestroy( %this )
{
	if ( $MC::Clearing )
	{
		%this.delete();
		return;
	}
	
	%db = %this.getDataBlock();
	
	if ( %this.getDataBlock().mcInvincible )
	{
		return;
	}
	
	%pos = %this.getPosition();
	%ptx = getWord( %pos, 0 );
	%pty = getWord( %pos, 1 );
	%ptz = getWord( %pos, 2 ) - $MC::GlobalBlockOffsetZ;
	%th = getGroundLevel( %ptx, %pty );
	
	if ( %ptz <= %th )
	{
		chunkSO::generateBelowTerrain( %ptx, %pty, %ptz, %th - %ptz, %th, %this );
	}
	
	if ( isObject( %chunk = %this.chunkSO ) && strLen( %id = %this.indexInChunk ) )
	{
		%pos = %chunk.blockPos[ %id ];
		%px = getWord( %pos, 0 );
		%py = getWord( %pos, 1 );
		%pz = getWord( %pos, 2 );
		
		%chunk.setBlock( %px, %py, %pz, "" );
	}
	else
	{
		%this.delete();
	}
}

function fxDTSBrick::setAdjecentBlock( %this, %type, %dir )
{
	%pos = vectorSub( %this.getPosition(), "0 0" SPC $MC::GlobalBlockOffsetZ );
	%pos = dirToPos( %dir, %pos );
	%px = getWord( %pos, 0 );
	%py = getWord( %pos, 1 );
	%pz = getWord( %pos, 2 );
	
	setBlock( %px, %py, %pz, %type );
}

function fixOffset( %off )
{
	%ox = getWord( %off, 0 );
	%oy = getWord( %off, 1 );
	%oz = getWord( %off, 2 );
	
	if ( %ox $= "-0.5" )
	{
		return "-1 0 0";
	}
	else if ( %ox $= "0.5" )
	{
		return "1 0 0";
	}
	else if ( %oy $= "-0.5" )
	{
		return "0 -1 0";
	}
	else if ( %oy $= "0.5" )
	{
		return "0 1 0";
	}
	else if ( %oz $= "-0.5" )
	{
		return "0 0 -1";
	}
	else if ( %oz $= "0.5" )
	{
		return "0 0 1";
	}
	
	return "0 0 0";
}

function offsetToDir( %off )
{
	switch$ ( %off )
	{
		case "1 0 0": return 0;
		case "0 1 0": return 1;
		case "0 0 1": return 2;
		case "-1 0 0": return 3;
		case "0 -1 0": return 4;
		case "0 0 -1": return 5;
	}
	
	return -1;
}

function dirToPos( %dir, %origin )
{
	%off = "0 0 0";
	
	switch$ ( %dir )
	{
		case 0: %off = "1 0 0";
		case 1: %off = "0 1 0";
		case 2: %off = "0 0 1";
		case 3: %off = "-1 0 0";
		case 4: %off = "0 -1 0";
		case 5: %off = "0 0 -1";
	}
	
	return vectorAdd( %origin, %dir );
}

// Action functions.
function Player::mcDestroy( %this )
{
	if ( isObject( %mnt = %this.getMountedImage( 0 ) ) )
	{
		if ( %mnt.mcHasDestroySpecial )
		{
			if ( %mnt.mcDestroySpecial( %this ) )
			{
				return;
			}
		}
	}
	
	if ( !isObject( %obj = %this.getEyeObject( $MC::Destroy::Range, $MC::Destroy::Mask ) ) )
	{
		return;
	}
	
	if ( !( %db = %obj.getDataBlock() ).isMC )
	{
		return;
	}
	
	if ( %db.mcInvincible || %db.mcHealth < 0 || strPos( %db.mcHealth * 1, "e" ) >= 0 )
	{
		return;
	}
	
	if ( isObject( %this.mcTempDestroyBlock ) && %this.mcTempDestroyBlock !$= %obj )
	{
		%this.mcTempDestroyTear = 0;
	}
	
	%this.mcTempDestroyBlock = %obj;
	
	if ( !strLen( %this.mcTempDestroyTear ) || %this.mcTempDestroyTear < 0 )
	{
		%this.mcTempDestroyTear = 0;
	}
	
	if ( isObject( %mnt ) && strLen( %spc = %mnt.mcDestroyTickTear ) )
	{
		%this.mcTempDestroyTear += %spc;
	}
	else
	{
		%this.mcTempDestroyTear += $MC::Destroy::TickTear;
	}
	
	if ( %db.mcInvincible )
	{
		%this.mcTempDestroyBlock = -1;
		%this.mcTempDestroyTear = 0;
		
		return;
	}
	
	%this.playThread( 0, "activate" );
	commandToClient( %this.client, 'centerPrint', "\c6" @ mFloatLength( ( ( %this.mcTempDestroyTear / %db.mcHealth ) * 100 ), 0 ) @ "%", 1 );
	
	%this.mcTempDestroyBlock.playSound( Minecraft_Wood_Click );
	
	if ( %this.mcTempDestroyTear >= %db.mcHealth || %this.instantDestroy )
	{
		%this.mcTempDestroyTear = 0;
		%type = %this.mcTempDestroyBlock.getDatablock().getname();
		%type = getSubStr(%type,13,strLen(%type));
		if(%this.client.mode == 0)
		{
			%this.client.amt[%type]++;
			%this.client.centerPrint("\c3You now have \c6" @ %this.client.amt[%type] SPC %type @ "\c3!");
		}
		%this.mcTempDestroyBlock.mcDestroy();
		%this.mcTempDestroyBlock = -1;
	}
}

function Player::mcDestroyCancel( %this )
{
	%this.mcTempDestroyBlock = -1;
	%this.mcTempDestroyTear = 0;
}

function Player::mcInteract( %this )
{
	if ( isObject( %mnt = %this.getMountedImage( 0 ) ) )
	{
		if ( %mnt.mcHasInteractSpecial )
		{
			if ( %mnt.mcInteractSpecial( %this ) )
			{
				return;
			}
		}
	}
	
	%ray = %this.getEyeRay( $MC::Interact::Range, $MC::Interact::Mask );
	
	if ( !isObject( %obj = firstWord( %ray ) ) )
	{
		return;
	}
	
	if ( !( %db = %obj.getDataBlock() ).isMC )
	{
		return;
	}
	
	if ( %db.mcHasInteractSpecial )
	{
		if ( call( %db.getName() @ "_mcInteractSpecial", %db, %obj, %this ) )
		{
			%this.playThread( 0, "activate" );
			return;
		}
	}
	
	if ( !isObject( %cl = %this.client ) )
	{
		return;
	}
	
	if ( !strLen( %slot = %cl.currInv ) )
	{
		return;
	}
	
	if ( !isObject( %inv = %cl.inventory[ %slot ] ) )
	{
		return;
	}
	
	if ( !%inv.isMC )
	{
		return;
	}

	%type = %inv.getName();
	%type = getSubStr( %type, 13, strLen( %type ) );
	
	if(%cl.mode == 0)
	{
		%cl.amt[%type] -= 1;
		if(%cl.amt[%type] <= 0)
		{
			%cl.amt[%type] = 0;
			%cl.centerPrint("\c3You don't have enough of this to plant!",3);
			return;
		}
		else
		{
			%cl.centerPrint("\c3You have \c6" @ %cl.amt[%type] @ "\c3 more \c6" @ %type @ "\c3.");
		}
	}
	
	%off = vectorSub( %obj.getPosition(), posFromRayCast( %ray ) );
	%off = fixOffset( %off );
	%pos = vectorSub( %obj.getPosition(), vectorSub( %off, "0 0" SPC $MC::GlobaBlockOffsetZ ) );
	
	%count = clientGroup.getCount();
	
	for ( %i = 0 ; %i < %count ; %i++ )
	{
		if ( !isObject( %pl = clientGroup.getObject( %i ).player ) )
		{
			continue;
		}
		
		if ( vectorDist( %pos, %pl.getPosition() ) < 0.5 )
		{
			return;
		}
	}
	%px = getWord( %pos, 0 );
	%py = getWord( %pos, 1 );
	%pz = getWord( %pos, 2 );
	
	setBlock( %px, %py, %pz, %type );
	%this.playThread( 0, "plant" );
}

// Detecting trigger input.
package mcInput
{
	function armor::onTrigger( %this, %obj, %slot, %val )
	{
		if ( %this.getName() !$= "playerMinecraftArmor" || ( %slot != 0 && %slot != 4 ) )
		{
			return parent::onTrigger( %this, %obj, %slot, %val );
		}
		
		%obj.setMCTrigger( ( %slot == 4 ? 1 : 0 ), %val );
	}
};

activatePackage( "mcInput" );

// Primary changing/ticking functions.
function Player::setMCTrigger( %this, %slot, %val )
{
	if ( %val )
	{
		if ( isEventPending( %this.mcTriggerTick[%slot ] ) )
		{
			return;
		}
		
		%this.mcTriggerTick( %slot );
	}
	else
	{
		if ( isEventPending( %event = %this.mcTriggerTick[ %slot ] ) )
		{
			cancel( %event );
		}
		
		if ( %slot == 0 )
		{
			%this.mcDestroyCancel();
		}
	}
}

function Player::mcTriggerTick( %this, %slot )
{
	// messageClient( %this.client, '', "Player::mcTriggerTick( " @ %slot @ " )" );
	
	cancel( %this.mcTriggerTick[ %slot ] );
	%this.mcTriggerAction( %slot );
	%this.mcTriggerTick[ %slot ] = %this.schedule( 200, "mcTriggerTick", %slot );
}

function Player::mcTriggerAction( %this, %slot )
{
	// messageClient( %this.client, '', "Player::mcTriggerAction( " @ %slot @ " )" );
	
	switch ( %slot )
	{
		case 0: %this.mcDestroy();
		case 1: %this.mcInteract();
	}
}

// Wrappers to support bots.
function AIPlayer::setMCTrigger( %this, %slot, %val )
{
	Player::setMCTrigger( %this, %slot, %val );
}

function AIPlayer::mcTriggerTick( %this, %slot )
{
	Player::mcTriggerTick( %this, %slot );
}

function AIPlayer::mcTriggerAction( %this, %slot )
{
	Player::mcTriggerAction( %this, %slot );
}

function AIPlayer::mcDestroy( %this )
{
	Player::mcDestroy( %this );
}

function AIPlayer::mcInteract( %this )
{
	Player::mcInteract( %this );
}