Game Development Community

bots and triggers

by Desmond Fletcher · in Torque Game Engine · 06/11/2002 (1:28 pm) · 7 replies

I'm trying to get a bot to trigger a sound event; my player can trigger it but not the bot.

I was using the assumption that bots derive their main characteristics from player.cc. In player.cc the findContact function is used to detect contact with a trigger. But the bot does not seem to access this function. Any ideas?

#1
06/16/2002 (5:03 am)
Desmond, I just gave it a try and put an example trigger into one of my maps, and the bots trigger it as well as my player does - so everything seems to be okay (and you are right, the bots' main characteristics are derived from the player class).
Just a wild guess: you still have this code in aiPlayer.cc:
// Copy over the trigger status
   for( int i = 0; i < MaxTriggerKeys; i++ ) {
      mMove.trigger[i] = mTriggers[i];
      //mTriggers[i] = false;
   }
If so, disable the whole for-loop and everything should be fine... I don't know why it is there or who put it there, but it simply disables any triggers for bots, which doesn't make any sense to me... this piece of code prevents bots from shooting, jumping, etc., too, by the way... so take it out and let me know if it works...
Stefan
#2
06/16/2002 (8:37 am)
Stefan,
I had already commented out that section based on one of your resources (or forum post, can't remember now).
#3
06/16/2002 (8:44 am)
Hm, I knew you would answer that... :-( Then it must be something in your specific code/scripts/mission file, cause it definitely works for me...
I make the bots follow me and run through my trigger, and the echo() commands show that they enter and leave the trigger shape...
maybe you could send me your files to check them out?
Or I could send you mine to double-check...
#4
06/16/2002 (8:50 am)
You're right! The bot was actually firing the trigger but the function was not passing it down the line (so to speak).

Here's what I have:

In server/scripts/trigger.cs-----------------------
function ScriptableTrigger::fireTrigger(%this, %trigger, %obj)
{
	%client = %obj.client;
	echo("---->client        = " @ %client);
	echo("---->triggerTarget = " @ %trigger.triggerTarget);
	switch(true)
	{
		case includedInString("command//", %trigger.triggerTarget) && 
		     includedInString("serverCmdMoveBotsToPlayer", %trigger.triggerTarget):
			//this function located in /server/scripts/commands.cs
			if (%client) {			
				serverCmdMoveBotsToPlayer(%client);
			}			
		default:
			//this function located in /client/scripts/triggerClient.cs	
			if (%client) {
				commandToClient(%client, 'fireTarget', %trigger);
			}
	} 
}

I suspect this is breaking down in the if statement above.

And in client/scripts/triggerClient.cs:
function clientCmdfireTarget(%trigger)
{
	$target = %trigger.triggerTarget; 	
	switch(true)
	{
	...Other cases.....
	    case includedInString("wav", $target):
   		//voice in /sound/voice/default
		   %strippedTarget = filebase($target); 	
			echo("---->Stripped target sound: " @ %strippedTarget);
			if(includedInString("~w", $target))
			{
				commandToServer('messageSent', %strippedTarget);
			}
			else
			{ 
				alxPlay(%strippedTarget);
			} 
		default:
			webparser_main($target);
	} 
}
#5
06/16/2002 (1:33 pm)
Desmond, I'm not really sure what's going on in your script and how you implemented your trigger, so here's what I did, maybe you can do something similar to check it out:
I got a file named soundTrigger.cs in fps/server/scripts which I execute from game.cs and which is very simple:
datablock TriggerData(SoundTestTrigger)
{
   tickPeriodMS = 100;
};

function SoundTestTrigger::onEnterTrigger(%data, %obj, %colObj)
{
   %checkname = %obj.getName();
   %client = %colObj.getControllingClient();
   echo (%client SPC ": Entered SoundTestTrigger Trigger");
}

function SoundTestTrigger::onLeaveTrigger(%data, %obj, %colObj)
{
   echo ("Left SoundTestTrigger Trigger");
}

function SoundTestTrigger::onTickTrigger(%data, %obj)
{
}

then I set up a trigger in my mission file like this:
new Trigger(soundTrigger) {
      position = "-148.559 71.6045 101.282";
      rotation = "1 0 0 0";
      scale = "2 20 20";
      dataBlock = "SoundTestTrigger";
      polyhedron = "0.0000000 0.0000000 0.0000000
 1.0000000 0.0000000 0.0000000 0.0000000 -1.0000000
 0.0000000 0.0000000 0.0000000 1.0000000";
   };
And as soon as a bot passes this trigger, the appropriate functions are called and the echos are printed to the console...

maybe you could explain a little bit more what you are trying to do with your triggers and how they (should) get activated?
#6
06/16/2002 (3:03 pm)
I have added two new fields to trigger.cc: these are triggerTarget and triggerDelay. Also, added these to objectBuilderGui.gui so they are automatically added in the editor. Now I pass the path/target info from the editor rather than creating a new trigger dataBlock each time.

The first function above is referenced by the trigger call to the scriptableTrigger datablock below:
new Trigger(st02) {
      position = "329.123 -324.858 210.57";
      rotation = "1 0 0 0";
      scale = "1 1 1";
      dataBlock = "ScriptableTrigger";
      polyhedron = "0.0000000 0.0000000 0.0000000 1.0000000 0.0000000 0.0000000 0.0000000 -1.0000000 0.0000000 0.0000000 0.0000000 1.0000000";
      triggerTarget = "Print to chathud...~wholodeck3.wav";
      triggerDelay = "0";
};
The target (in this case a voice wav) is passed as well. But the switch allows me to filter the type of target (might be another trigger, a bot, a sound, etc.) So I only need this one scriptable trigger. The switch then can either process the target directly or call a client command. The client commands are in client/scripts/triggerClient.cs

However, the switch in the fireTarget function does not seem to get activated. hmmm Just thought why that may be....its good to talk these things out. I'll let ya know if I get it fixed.
#7
06/17/2002 (8:48 am)
Figured out the problem but not the WHY. Bots are not "legitimate" clients for the commandToClient function. Once I created a serverCmdFireTarget, no problem with bots enabling triggers. Perhaps someone could explain why this is the case?

So here is the fireTrigger function in server/scripts/trigger.cs that distinguishes between ai-and human-players:
function ScriptableTrigger::fireTrigger(%this, %trigger, %obj)
{
	%client = %obj.client;
	%botornot = %client.isAIControlled();
	if(%botornot){
		error("---->client " @ %client @ " is a bot");
		[b]serverCmdFireTarget[/b](%trigger);
		//this function located in /server/scripts/commands.cs	
	}
	else
	{
		error("---->client " @ %client @ " is not a bot"); 
		switch(true)
		{
			case includedInString("command//", %trigger.triggerTarget) && 
			     includedInString("serverCmdMoveBotsToPlayer", %trigger.triggerTarget):
				//this function located in /server/scripts/commands.cs
				if (%client) {
					serverCmdMoveBotsToPlayer(%client);
				}			
			default:
				//this function located in /client/scripts/triggerClient.cs
				if (%client) {
					commandToClient(%client, 'fireTarget', %trigger);
				}
		}
	} 
}

And the serverCmdFireTarget function in server/scripts/comands.cs that responds when the trigger was fired by a bot:
function ScriptableTrigger::fireTrigger(%this, %trigger, %obj)
{
	%client = %obj.client;
	%botornot = %client.isAIControlled();
	if(%botornot){
		error("---->client " @ %client @ " is a bot");
		[b]serverCmdFireTarget[/b](%trigger);
		//this function located in /server/scripts/commands.cs	
	}
	else
	{
		error("---->client " @ %client @ " is not a bot"); 
		switch(true)
		{
			case includedInString("command//", %trigger.triggerTarget) && 
			     includedInString("serverCmdMoveBotsToPlayer", %trigger.triggerTarget):
				//this function located in /server/scripts/commands.cs
				if (%client) {
					serverCmdMoveBotsToPlayer(%client);
				}			
			default:
				//this function located in /client/scripts/triggerClient.cs
				if (%client) {
					commandToClient(%client, 'fireTarget', %trigger);
				}
		}
	} 
}