Game Development Community

OnReachDestination??

by Temasek Polytechnic · in Torque Game Engine · 06/29/2006 (2:14 am) · 12 replies

Ok.
I created an AIPlayer and programmed some actions to it (walk, look etc).
This is how my datablock looks like:
datablock PlayerData(AIHorse)
{
	//renderFirstPerson = false;
   emap = true;
   
   shapeFile = "~/data/shapes/horses/blue_guy.dts";
   cameraMaxDist = 4;
   computeCRC = true;
  
   canObserve = true;
   //cmdCategory = "Clients";

   cameraDefaultFov = 90.0;
   cameraMinFov = 5.0;
   cameraMaxFov = 120.0;
   
   minLookAngle = -1.4;
   maxLookAngle = 1.4;
   maxFreelookAngle = 3.0;

   mass = 10;
   drag = 0.3;
   maxdrag = 0.4;
   density = 10;

   runForce = 50;
   maxForwardSpeed = 2;

   boundingBox = "0.02 0.02 0.02";
   
   runSurfaceAngle  = 100;
   jumpSurfaceAngle = 80;

   //observeParameters = "0.5 4.5 4.5";
};
When the walk function is called, the AIPlayer(AIHorse) will walk to a destination(by setting its setMoveDestination function). It will also play the walking animation (by setting playThread).
I have a onReachDestination function that looks like this:
function AIHorse::onReachDestination(%this,%obj)
{
	//%index = getIndex(%obj);
	//%obj.playThread($ind[%index],"root");
	error("has reached destination");
	%obj.stop();
	//%aiPlayer.clearAim();
	%obj.playThread(0,"root");
}
The problem is this, the onReachDestination function is never called because the "has reached destination" is never printed out.

Can anyone figure out why?

#1
06/29/2006 (5:43 am)
Try setting the move tolerance higher, with this:

%horse.setMoveTolerance(10);

This is the number that tells your AI how close they have to be to 'there' to be there.
#2
06/29/2006 (6:34 am)
@Brian:

Unfortunatly it doesn't matter what the moveTolcerance is set to. That's just a tolerance for when the bot considers itself at target. If it's too low, the callback will still be called - just earlier.

If the bot stops, the callback will be called.. if not, it's an error in the scripts or naming hierarchy.
#3
06/29/2006 (7:07 am)
Create a second onReachDestination methode in the AIPlayer namespace to see if that one gets called:

function AIPlayer::onReachDestination(%this,%obj)
{
	error("AIPlayer::onReachDestination called...");
}

If I remember right, there were some issues with the namespace and the AIPlayer.
#4
06/29/2006 (7:18 am)
The more I think about it and the more I remember, yes, there was a problem with namespaces and it was mentioned in one of Ben Garney's blogs if I'm not totally wrong. As a workaround I copied the AIPlayer class and renamed that copy to AIMySuperCoolSecondPlayer and archieved so my second namespace to have different AI player classes. Maybe someone knows a better solution.
#5
06/29/2006 (7:48 am)
That's what I remember too.
#6
06/29/2006 (10:24 am)
In Ben Garney's own words : "Bots don't like to reach destinations". If I remember, I solved it by schedulling each bot to it's own think method and dumping AImanager.
#7
06/29/2006 (10:27 am)
This is good to know, I was having similar issues.
#8
06/29/2006 (7:33 pm)
Thank you everyone for your response.

@Martin:

I tried to add the AIPlayer::onReachDestination function, but that function was not called too.

@Brian:

I added the setMoveTolerance(10) function and i got this error message:
(64): Unknown command setMoveTolerance.
  Object (1280) AIPlayer -> Player -> ShapeBase -> GameBase -> SceneObject -> NetObject -> SimObject

Here's the code of my AIPlayer(horse) class:
exec("~/data/shapes/horses/horse.cs");

datablock PlayerData(AIHorse)
{
	//renderFirstPerson = false;
   emap = true;
   
   shapeFile = "~/data/shapes/horses/blue_guy.dts";
   cameraMaxDist = 4;
   computeCRC = true;
  
   canObserve = true;
   //cmdCategory = "Clients";

   cameraDefaultFov = 90.0;
   cameraMinFov = 5.0;
   cameraMaxFov = 120.0;
   
   minLookAngle = -1.4;
   maxLookAngle = 1.4;
   maxFreelookAngle = 3.0;

   mass = 10;
   drag = 0.3;
   maxdrag = 0.4;
   density = 10;

   runForce = 50;
   maxForwardSpeed = 2;

   boundingBox = "0.02 0.02 0.02";
   
   runSurfaceAngle  = 100;
   jumpSurfaceAngle = 80;

   //observeParameters = "0.5 4.5 4.5";
};

function AIPlayer::createHorse(%name,%point,%data)
{
	%obj = new AIPlayer()
	{
		datablock = %data;
	};
	MissionCleanup.add(%obj);
	%obj.setShapeName(%name);
	%obj.setTransform(%point);
	%obj.horseThink();
	return %obj;
}

function AIPlayer::horseThink(%this)
{
	%choice = getRandom(1,0);
	
	if(%choice == 0)
	{
		horseWalk(%this);
	}
	else if(%choice == 1)
	{
		horseLook(%this);
	}
	%this.schedule(10000,"horseThink");
}

function horseWalk(%aiPlayer)
{
	%aiPlayer.clearAim();
	//get x y coords of horse
	%x = getWord(%aiPlayer.getPosition(),0);
	%y = getWord(%aiPlayer.getPosition(),1);
	// make the horse walk in random directions
	%choice = getRandom(3,0);
	if(%choice == 0)
	{
		%x += 10;
	}
	else if(%choice == 1)
	{
		%x -= 10;
	}
	else if(%choice == 2)
	{
		%y += 10;
	}
	else
	{
		%y -= 10;
	}
	%z = getWord(%aiPlayer.getPosition(),2);//getTerrainHeight(%x SPC %y);
	%aiPlayer.playThread(0,"walks");
	%aiPlayer.setMoveDestination(%x SPC %y SPC %z);	
}

function horseLook(%aiPlayer)
{
	%aiPlayer.clearAim();
	%aiPlayer.setAimObject($playerHandle);
	%aiPlayer.playThread(0,"root");
}

function AIHorse::onCollision(%this,%obj,%col)
{
	%obj.stop();
	%obj.clearAim();
	%obj.playThread(0,"root");
}

function AIHorse::onReachDestination(%this,%obj)
{
	error("AIHorse::onReachDestination");
	%obj.stop();
	%obj.playThread(0,"root");
}

function AIPlayer::onReachDestination(%this,%obj)
{
	error("AIPlayer::onReachDestination");
}
#9
06/29/2006 (9:35 pm)
Can you post the function where your "createHorse" function is called?

Have you tried replacing the %data for a test by a static call like this?

function AIPlayer::createHorse(%name,%point,%data)
{
	%obj = new AIPlayer()
	{
		datablock = [b]AIHorse[/b];
	};
	...
}

Have you double-checked the console that there is no error somewhere?
#10
06/29/2006 (11:14 pm)
Ok, here's my function that calls it:
function serverCmdAddHorse(%client)
{
	%x = getWord(%client.camera.getTransform(),0);
	// get the y coord of the camera
	%y = getWord(%client.camera.getTransform(),1);
	// call the function that will make the flamingo appear under the marker(red circle)
	%val = getObjDist();
	// calculate the new y coord
	%y -= %val;
	%z = getTerrainHeight(%x SPC %y);
	[b]%bot = AIPlayer::createHorse("Horse",%x SPC %y SPC %z,AIHorse);[/b]
}
The only error that i have, which i don't think its related, is this:
Validation required for shape: zooIQDemo/data/shapes/horses/blue_guy.dts

I have tried using a static call, but it does not work too.
#11
07/03/2006 (12:08 am)
Anyone have any clues to help me out?
#12
07/03/2006 (9:08 am)
Test this in starter.fps.
For test purpuse only dont use the aiplayer.cs.

datablock PlayerData(AIHorse : PlayerBody)
{
   category = "Horses";
   cmdCategory = "isAiControlled";

   
};

function AIHorse::onAdd(%this,%obj)
{
   %obj.horseThink();
}


function AIPlayer::createHorse(%name,%point,%data)
{
	%obj = new AIPlayer()
	{
		datablock = %data;
	};
	MissionCleanup.add(%obj);
	%obj.setShapeName(%name);
	%obj.setTransform(%point);
	%obj.horseThink();
	//return %obj;
}

function AIPlayer::horseThink(%this,%obj)
{
	%choice = getRandom(1,0);
	
	if(%choice == 0)
	{
		%this.horseWalk(%obj);
	}
	else if(%choice == 1)
	{
		%this.horseLook(%obj);
	}
	%this.schedule(10000,"horseThink");
}

function AIPlayer::horseWalk(%obj)
{
	%obj.clearAim();
	//get x y coords of horse
	%x = getWord(%obj.getPosition(),0);
	%y = getWord(%obj.getPosition(),1);
	// make the horse walk in random directions
	%choice = getRandom(3,0);
	if(%choice == 0)
	{
		%x += 10;
	}
	else if(%choice == 1)
	{
		%x -= 10;
	}
	else if(%choice == 2)
	{
		%y += 10;
	}
	else
	{
		%y -= 10;
	}
	%z = getWord(%obj.getPosition(),2);//getTerrainHeight(%x SPC %y);
	%obj.playThread(0,"walks");
	%obj.setMoveDestination(%x SPC %y SPC %z);
                error("Object movedest = " SPC %obj SPC %obj.getMoveDestination());
	
}

function AIPlayer::horseLook(%obj)
{
      echo("HorseLook " SPC %obj);
	%obj.clearAim();
	%obj.setAimObject($playerHandle);
	%obj.setActionThread("celwave");

}

function AIHorse::onCollision(%this,%obj,%col)
{
	%obj.stop();
	%obj.clearAim();
	%obj.playThread(0,"root");
}

function AIHorse::onReachDestination(%this,%obj)
{
	echo("AIHorse::onReachDestination" SPC %obj);
	%obj.setActionThread("celwave");
}


function AIPlayer::spawn()
{
   $horsenr = $horsenr+1;
   %name = "myHorse" @ $horsenr;
   %spawnPoint = pickHorseSpawnPoint();

   // Create the demo player object
   %obj = new AiPlayer() {
      dataBlock = AIHorse;
      path="";
   };
   MissionCleanup.add(%obj);
   %obj.setShapeName(%name);
   %obj.setTransform(%spawnPoint); 
   return %obj;
}

function pickHorseSpawnPoint() 
{
   //%groupName = "MissionGroup/HorseDropPoints";
   %groupName = "MissionGroup/PlayerDropPoints";

   %group = nameToID(%groupName);

   if (%group != -1) {
      %count = %group.getCount();
      if (%count != 0) {
         %index = getRandom(%count-1);
         %spawn = %group.getObject(%index);
         return %spawn.getTransform();
      }
      else
         error("No spawn points found in " @ %groupName);
   }
   else
      error("Missing spawn points group " @ %groupName);

   // Could be no spawn points, in which case we'll stick the
   // player at the center of the world.
   return "0 0 300 1 0 0 0";
}