
function HomingMineTrap(%this, %target, %force, %strongArm)
{
%targetPos = GameBase::getPosition(%this);
%client = %target;
if (Player::getArmor(%client) == False) // If the client is dead then clean up here and quit looping.
	{
	   $HomingMine[%client] = ""; // Clean up dead entries.
	   return False;  // Bail out.
	   break;
	}
	if(%targetPos != "")
	{
	   $HomingMine[%client] = ""; // If there's new coordinates then delete the old ones.
	   $HomingMine[%client] = %targetPos; // Set the new ones.
	}
   else
   {
	if(%targetPos == "")
	{
	   %targetPos = $HomingMine[%client]; // If there's no coordinants then look in the client's table.
	}
   }
// Get client position.
		%clientPos = GameBase::getPosition(%client);
		%clientX = getWord(%clientPos,0);
		%clientY = getWord(%clientPos,1);
		%clientZ = getWord(%clientPos,2);
// Setup Speed controls.
		%speed = Item::getVelocity(%client);
		%speedX = getWord(%speed, 0);
		%speedY = getWord(%speed, 1);
		%speedZ = getWord(%speed, 2);
// Setup Impulse info
		%setPosX = getWord(%targetPos,0);
		%setPosY = getWord(%targetPos,1);
		%setPosZ = getWord(%targetPos,2);
		%mathX = Vector::neg(%clientX);
		%mathY = Vector::neg(%clientY);
		%mathZ = Vector::neg(%clientZ);
		%destPosX = %setPosX+%mathX;
		%destPosY = %setPosY+%mathY;
		%destPosZ = %setPosZ+%mathZ;
		%reverseX = Vector::neg(%destPosX);
		%reverseY = Vector::neg(%destPosY);
		%reverseZ = Vector::neg(%destPosZ);

// Set the requested force. (Atract/Repel) Default is Atract.
		if(%force == repel)
		{
			%destPosX = %reverseX;
			%destPosY = %reverseY;
			%destPosZ = %reverseZ;
		}

// Get Distance.
		%dist = Vector::getDistance(%clientPos, %targetPos);
		%Xdist = Vector::getDistance(%clientX, %setPosX);
		%Ydist = Vector::getDistance(%clientY, %setPosY);
		%Zdist = Vector::getDistance(%clientZ, %setPosZ);
// Emergency Brakes.
		%brakeX = Vector::neg(%speedX); //*0.25;
		%brakeY = Vector::neg(%speedY); //*0.25;
// Finite Vertical Navigation.
		%parachuteVal = Vector::neg(%speedZ)*0.25;
		%vertAdjust = %setPosZ-%clientZ+3;
	if(%setPosZ >= %clientZ)
	{
		if(%dist <= 25)
		{
			if(%vertAdjust <= 5)
			{
				Player::ApplyImpulse(%client, "0 0 "@%vertAdjust);
			}
			else
			{
				if(%destPosZ >= 0)
				{
					Player::ApplyImpulse(%client, "0 0 5");
				}
			}
		}
	}
 // Don't make the client go "FWING!!!" (In any direction.) :P :)
	if(%dist >= 25) // Coarse Flight.
	{
		if(%speedX <=  -10){if(%destPosX <= -1){%destPosX = -0.1;}} //%destPosX*0.010;}}
		if(%speedY <= -10){if(%destPosY <= -1){%destPosY = -0.1;}} //%destPosY*0.010;}}
		if(%speedZ <= -15){if(%destPosZ <= -1){%destPosZ = %destPosZ*0.010;}}
		if(%speedZ <= -0.000015){if(%destPosZ <= -0.000015){%destPosZ = %destPosZ+Vector::neg(%destPosZ);}}
		if(%speedX >= 10){if(%destPosX >= 1){%destPosX = %destPosX*-0.010;}} //0.1;}}
		if(%speedY >= 10){if(%destPosY >= 1){%destPosY = %destPosY*-0.010;}} //0.1;}}
		if(%speedZ >= 15){if(%destPosZ >= 1){%destPosZ = %destPosZ*-0.010;}}
		if(%speedZ >= 0.000015){if(%destPosZ >= 0.000015){%destPosZ = %destPosZ+Vector::neg(%destPosZ);}}
		if(%speedX <= -15){%destPosX = %brakeX;}
		if(%speedY <= -15){%destPosY = %brakeY;}
		if(%speedZ <= -0.1){Player::ApplyImpulse(%client, "0 0 "@%parachuteVal);}
		if(%speedX >= 15){%destPosX = %brakeX;} 
		if(%speedY >= 15){%destPosY = %brakeY;} 
		if(%speedZ >= 25){Player::ApplyImpulse(%client, "0 0 "@%vertAdjust);} //parachuteVal);} 
//		if(%speedZ <= 1){Player::ApplyImpulse(%client, "0 0 "@%vertAdjust);} //parachuteVal);} 
	}
	if(%dist <= 25) // The Alignment.
	{
//		if(%dist >= 10)
//		{
			if(%speedX <=  -10){if(%destPosX <= -5){%destPosX = %destPosX*0.010;}}
			if(%speedY <= -10){if(%destPosY <= -5){%destPosY = %destPosY*0.010;}}
			if(%speedZ <= -10){if(%destPosZ <= -5){%destPosZ = %destPosZ*0.010;}}
			if(%speedX >= 10){if(%destPosX >= 5){%destPosX = %destPosX*-0.010;}}
			if(%speedY >= 10){if(%destPosY >= 5){%destPosY = %destPosY*-0.010;}}
			if(%speedZ >= 10){if(%destPosZ >= 5){%destPosZ = %destPosZ*-0.010;}}
			if(%speedX >= 15){%destPosX = %brakeX;} 
			if(%speedX <= -15){%destPosX = %brakeX;}
			if(%speedY >= 15){%destPosY = %brakeY;} 
			if(%speedY <= -15){%destPosY = %brakeY;}
			if(%speedZ >= 15){Player::ApplyImpulse(%client, "0 0 "@%parachuteVal);} 
			if(%speedZ <= -0.1){Player::ApplyImpulse(%client, "0 0 "@%parachuteVal);}
			Player::ApplyImpulse(%client, "0 0 "@%vertAdjust);
//		}
	}
//	if(%dist <= 10) // The Landing.
//	{
//		if(%force != repel)
//		{
//			if(%speedX <=  -5){if(%destPosX <= -1){%destPosX = %destPosX*0.10;}}
//			if(%speedY <= -5){if(%destPosY <= -1){%destPosY = %destPosY*0.10;}}
//			if(%speedZ <= -5){if(%destPosZ <= -1){%destPosZ = %destPosZ*0.10;}}
//			if(%speedX >= 5){if(%destPosX >= 1){%destPosX = %destPosX*-0.10;}}
//			if(%speedY >= 5){if(%destPosY >= 1){%destPosY = %destPosY*-0.10;}}
//			if(%speedZ >= 5){if(%destPosZ >= 0.11){%destPosZ = %destPosZ*-0.20;}}
//			if(%speedX >= 7){%destPosX = %brakeX;} 
//			if(%speedX <= -7){%destPosX = %brakeX;}
//			if(%speedY >= 7){%destPosY = %brakeY;} 
//			if(%speedY <= -7){%destPosY = %brakeY;}
//			if(%speedZ >= 15){%destPosZ = %parachuteVal;} 
//			if(%speedZ <= -15){%destPosZ = %parachuteVal;}
//			Item::setVelocity(%target,"0 0 0.5");
//		}
//		else
//		{
//			if(%speedX <=  -5){if(%destPosX <= -1){%destPosX = %destPosX*1000;}}
//			if(%speedY <= -5){if(%destPosY <= -1){%destPosY = %destPosY*1000;}}
//			if(%speedZ <= -5){if(%destPosZ <= -1){%destPosZ = %destPosZ*1000;}}
//			if(%speedX >= 5){if(%destPosX >= 1){%destPosX = %destPosX*-1000;}}
//			if(%speedY >= 5){if(%destPosY >= 1){%destPosY = %destPosY*-1000;}}
//			if(%speedZ >= 5){if(%destPosZ >= 0.11){%destPosZ = %destPosZ*-2000;}}
//			if(%speedX >= 3){%destPosX = %brakeX;} 
//			if(%speedX <= -3){%destPosX = %brakeX;}
//			if(%speedY >= 3){%destPosY = %brakeY;} 
//			if(%speedY <= -3){%destPosY = %brakeY;}
//			if(%speedZ >= 15){%destPosZ = %parachuteVal;} 
//			if(%speedZ <= -0.1){%destPosZ = %parachuteVal;}
//			Item::setVelocity(%target,"0 0 2");
//		}
//	}

	// Finite Horizontal Navigation.
	if(%Xdist <= 15)
	{
		if(%Zdist >= 0) // Here we tell HomingMine to hold X&Y until Z is in the clear.
		{
			if(%Zdist <= 1)
			{
				if(%Xdist <= 20){if(%speedX <= 3){%lockX = false;}}
			}
			if(%dist <= 0)
			{
				if(%Xdist >= -20){if(%speedX >= -3){%lockX = false;}}
			}
			if(%Zdist >= 1)
			{
//			   if(%Xdist <= 20){%lockX = true;}
//			   if(%Xdist >= -20){%lockX = true;}
			   if(%speedZ >= 3){Player::ApplyImpulse(%client, "0 0 "@%parachuteVal);} 
			   if(%speedZ <= -0.1){Player::ApplyImpulse(%client, "0 0 "@%parachuteVal);}
			   %destPos = ""@%destPosX@" "@%destPosY@" "@%destPosZ@"";
			   Player::ApplyImpulse(%client, %destPos);
			}
		}
	}
	if(%Ydist <= 15)
	{
		if(%Zdist >= 0) // Here we tell HomingMine to hold X&Y until Z is in the clear.
		{
			   if(%Zdist <= 1)
			   {
				if(%Ydist <= 20){if(%speedY <= 3){%lockY = false;}}
			   }
			   if(%dist <= 0)
			   {
				if(%Ydist >= -20){if(%speedY >= -3){%lockY = false;}}
			   }
				if(%Zdist >= 1)
				{
//				   if(%Ydist <= 20){%lockY = true;}
//				   if(%Ydist >= -20){%lockY = true;}
				}
				if(%speedZ >= 3){Player::ApplyImpulse(%client, "0 0 "@%parachuteVal);} 
				if(%speedZ <= -0.1){Player::ApplyImpulse(%client, "0 0 "@%parachuteVal);}
				%destPos = ""@%destPosX@" "@%destPosY@" "@%destPosZ@"";
				Player::ApplyImpulse(%client, %destPos);
		}
	}
if(%lockX == true)
	{
//		%destPosX = %brakeX;
	}
	if(%lockY == true)
	{
//		%destPosY = %brakeY;
	}
// Are we stuck? Hmm, lets try to fix it. (For field obsticals.)
	if(%dist >= 10)
	{
		if(%speedY <= 0.1){if(%speedY >= 0){if(%lockX != true){%destPosX = %reverseX*0.001; %stuck = true; %freeUp = "+Y axis. Reversing X to "@%reverseX;}}}
		if(%speedY >= -0.1){if(%speedY <= 0){if(%lockX != true){%destPosX = %reverseX*0.001; %stuck = true; %freeUp = "-Y axis. Reversing X to "@%reverseX;}}}
		if(%speedX <= 0.1){if(%speedX >= 0){if(%lockY != true){%destPosY = %reverseY*0.001; %stuck = true; %freeUp = "+X axis. Reversing Y to "@%reverseY;}}}
		if(%speedX >= -0.1){if(%speedX <= 0){if(%lockY != true){%destPosY = %reverseY*0.001; %stuck = true; %freeUp = "-X axis. Reversing Y to "@%reverseY;}}}
		if(%speedZ <= 0.1){if(%speedZ >= 0){%destPosZ = %reverseZ; %stuck = true; %freeUp = "+Z axis. Reversing "@%reverseZ;Player::ApplyImpulse(%client,"0 0 100");}}
		if(%speedZ >= -0.1){if(%speedZ <= 0){%destPosZ = %reverseZ; %stuck = true; %freeUp = "-Z axis. Reversing "@%reverseZ;}}
	}
	if(%dist >=25)
	{
		%destPos = ""@%destPosX@" "@%destPosY@" "@%destPosZ@""; //0";
	}
	else
	{
		%destPos = ""@%destPosX@" "@%destPosY@" "@%destPosZ@"";
	}
	if(%dist <= 2.5)
	{
		GameBase::setPosition(%client,%clientPos);
	}

// Apply the results.	
//	if(%dist >= 1) // A higher value for faster/sloppier destinations. // In this case turret decides when to stop.
//	{
		if($HomingMine != "break") // Override input. (Just in case.)
		{
			if(%destPos != "")
			{
				if(%strongArm == "")
				{
					Player::ApplyImpulse(%client, %destPos); // More true to how it should act.
				}
				else
				{
					Item::setVelocity(%client, %destPos); // Stronger but less forgiving.
				}
//				schedule("HomingMineTrap("@%client@");",0.01); // Comment out this line if if your gonna call the function from elsewhere.
// Turret will handle the resheduling in this instance.

				// Note: You'll need your external function call to HomingMineTrap repeatedly untill goal is met.
				return %dist; // Tie-in for externals. (For use if external function decides when it should quit.)
			}
		}
//	}
	else
	{
		$HomingMine[%client] = ""; // Where all done so its time to clean up.
	}
}

MineData HomingMine
{
	className = "Mine";
   description = "Magnetic Mine";
   shapeFile = "sensor_small"; //"mine";
   shadowDetailMask = 4;
   explosionId = mineExp;
	explosionRadius = 10.0;
	damageValue = 0.65;
	damageType = $MineDamageType;
	kickBackStrength = 150;
	triggerRadius = 25;
	maxDamage = 0.5;
	shadowDetailMask = 0;
	destroyDamage = 1.0;
	damageLevel = {1.0, 1.0};
};

function HomingMine::onAdd(%this)
{
	%this.damage = 0;
	HomingMine::deployCheck(%this);
}

function HomingMine::onCollision(%this,%object)
{
	%type = getObjectType(%object);
	%dist = Vector::getDistance(%this,%object);
	%data = GameBase::getDataName(%this);
	if(%dist <= 25)
	{
		HomingMineTrap(%this, %target);
	}
	if(%dist <= 2.5)
	{
		if ((%type == "Player" || %data == HomingMine || %data == Vehicle || %type == "Moveable") && GameBase::isActive(%this)) 
		GameBase::setDamageLevel(%this, %data.maxDamage);
	}
}

function HomingMine::deployCheck(%this)
{
	if (GameBase::isAtRest(%this)) {
		GameBase::playSequence(%this,1,"deploy");
	 	GameBase::setActive(%this,true);
		%set = newObject("set",SimSet);
		if(1 != containerBoxFillSet(%set,$MineObjectType,GameBase::getPosition(%this),1,1,1,0)) {
			%data = GameBase::getDataName(%this);
			GameBase::setDamageLevel(%this, %data.maxDamage);
		}
		deleteObject(%set);
	}
	else 
		schedule("HomingMine::deployCheck(" @ %this @ ");", 3, %this);
}	

function HomingMine::onDestroyed(%this)
{
	$TeamItemCount[GameBase::getTeam(%this) @ "mineammo"]--;
}

function HomingMine::onDamage(%this,%type,%value,%pos,%vec,%mom,%object)
{
   if (%type == $MineDamageType)
      %value = %value * 0.25;

	%data = GameBase::getDataName(%this);
	if((%data.maxDamage/1.5) < %this.damage+%value) 
		GameBase::setDamageLevel(%this, %data.maxDamage);
	else 
		%this.damage += %value;
}

//----------------------------------------------------------------------------


function HomingMine::onDamage(%this,%type,%value,%pos,%vec,%mom,%object)
{
   if (%type == $MineDamageType)
      %value = %value * 0.25;

	%damageLevel = GameBase::getDamageLevel(%this);
	GameBase::setDamageLevel(%this,%damageLevel + %value);
}

function HomingMine::Detonate(%this)
{
	%data = GameBase::getDataName(%this);
	GameBase::setDamageLevel(%this, %data.maxDamage);
}

