It's impossible to be "dead accurate," unless you equip the bots with raycasting weapons. You can take a guess what their position will be at a future point in time, but if they change directions, jump, crouch, or stop after the projectile is fired it will go to the position you predict, not the position they're at.
"Homing" projectiles are one way around this, but they're very poorly implemented in Blockland. Essentially, every 100ms or so you delete the projectile and spawn a new one at the correct angle to hit the player.
This is untested, but it should predict the target's location based on their current velocity. Tested, works. This includes Z velocity, mind you, so if the player jumps gravity will forget it up.
function AIPlayer::predictiveAim(%this, %target, %player)
{
if(%player)
%targetPosition = %target.getEyePoint();
else
%targetPosition = %target.getPosition();
if(!isObject(%weapon = %this.getMountedImage(0)))
{
%this.setAimLocation(%targetPosition);
return %targetPosition;
}
%projectileSpeed = %weapon.projectile.muzzleVelocity;
%toTarget = vectorSub(%targetPosition, %this.getMuzzlePoint(0));
%dist = vectorDist(%this.getMuzzlePoint(0), %targetPosition);
%delta = %dist / %projectileSpeed;
%aimSpot = vectorAdd(%targetPosition, vectorScale(%target.getVelocity(), %delta));
%this.setAimLocation(vectorAdd(%aimSpot, vectorSub(%this.getEyePoint(), %this.getMuzzlePoint(0))));
return %aimSpot;
}