Questions to Stefans advanced bot scripting ....
by Michael Schaumburg · in Torque Game Engine · 12/03/2002 (5:09 am) · 23 replies
I got it working this great source "Adding NPC support". Now I try to to get Stefans source "Advanced bot scripting" at www.garagegames.com/index.php?sec=mg&mod=resource&page=view&qid=2505 to work for the NPC's. When I try to acces from a NPC to the code, I get some errors in the console. First how I create the NPC:
I was running through the scripts but I can't find this missing functions. In the console I get the following:
fps/server/scripts/aiPlayer.cs (275): Unknown command getLocation
fps/server/scripts/aiPlayer.cs (155): Unknown command setTargetObject
fps/server/scripts/aiPlayer.cs (174): Unknown command move
Why is the function unable to find the object ?
fps/server/scripts/aiPlayer.cs (163): Unable to find object: '' attempting to call function 'hasInventory'
fps/server/scripts/aiPlayer.cs (163): Unable to find object: '' attempting to call function 'hasInventory
Any idea ??
Also I changed my create function to start the NPC with a weapon, but he still has no weapon:
function NPC::create(%datablock)
{
// Create the player object
%obj= new AIPlayer()
{
dataBlock= %datablock;
};
%obj.setMoveSpeed(0.2);
%obj.handleWaypointsAndChase(%this);
return %obj;
}I was running through the scripts but I can't find this missing functions. In the console I get the following:
fps/server/scripts/aiPlayer.cs (275): Unknown command getLocation
fps/server/scripts/aiPlayer.cs (155): Unknown command setTargetObject
fps/server/scripts/aiPlayer.cs (174): Unknown command move
Why is the function unable to find the object ?
fps/server/scripts/aiPlayer.cs (163): Unable to find object: '' attempting to call function 'hasInventory'
fps/server/scripts/aiPlayer.cs (163): Unable to find object: '' attempting to call function 'hasInventory
Any idea ??
Also I changed my create function to start the NPC with a weapon, but he still has no weapon:
// start with a weapon
%weapon = new Item(){
dataBlock = Rifle;
};
%ammo = new Item(){
dataBlock = RifleAmmo;
};
MissionCleanup.add(%weapon);
MissionCleanup.add(%ammo);
%obj.pickup(%weapon,1);
%obj.pickup(%ammo,2);
#2
The dump listing says that my NPC has a rifle and ammo. But I can't see a weapon on the NPS ??
12/03/2002 (6:56 am)
Hmm, a great list. Anyway, is this source from Stefan no longer working for the latest changes (HEAD)??The dump listing says that my NPC has a rifle and ammo. But I can't see a weapon on the NPS ??
#3
12/03/2002 (7:30 am)
That reference is for the old bot types. I think Stefan has a new reference that works in the HEAD version. take a look at his website: tork.zenkel.com/
#4
12/03/2002 (8:33 am)
Michael - one problem ya' do have there is that you've given the bot a weapon and some ammo. However, ya' gotta tell the bot to use it. Ie, %obj.use(Rifle); Then you should see your bot have the rifle.
#5
Anyway, there are some functions in the source I can't understand where to find them and what they should do:
Does the AI code change that much??
12/03/2002 (9:09 am)
Also when I say to use the weapon they don't have it. Maybe I made a great mistake. I think there is no difference between a NPC I put into the mission through the editor or when I'm spawning a new AIplayer, or I'm wrong ??Anyway, there are some functions in the source I can't understand where to find them and what they should do:
%this.setTargetObject($daPlaya); %botPos = %this.getLocation();
Does the AI code change that much??
#6
%obj = new (AIplayer)(){ .............. }
Are you missing some parenthesis?
For example, my projectile spells are as follows:
%p = new (projectile)() {
dataBlock = %dataBlockName;
initialVelocity = %scaledVel;
initialPosition = %playerPos;
client = %client;
};
12/03/2002 (1:50 pm)
Should it not be:%obj = new (AIplayer)(){ .............. }
Are you missing some parenthesis?
For example, my projectile spells are as follows:
%p = new (projectile)() {
dataBlock = %dataBlockName;
initialVelocity = %scaledVel;
initialPosition = %playerPos;
client = %client;
};
#7
%botPos = %this.getLocation();
you should use
%botPos = %this.getPosition();
12/03/2002 (2:30 pm)
Also, instead of%botPos = %this.getLocation();
you should use
%botPos = %this.getPosition();
#8
I think the new trigger command is setImageTrigger(0,true); I know there was the same question like this a month before and it wasn't answered. So I think there is no way to have a bot shooting from script. Maybe this function is broken. Or is there someone with a shooting bot in the HEAD version ??
What I also noticed is, when the bot reached his destination, he makes some stupid dancing animation instead of standing still.
12/03/2002 (11:25 pm)
What I have got to work, is to start the bot with a weapon.In latest the HEAD you must create him like this:// start with a weapon %obj.setEnergyLevel(60); %obj.incInventory(Crossbow,1); %obj.incInventory(CrossbowAmmo,CrossbowAmmo.maxInventory); %obj.use(Crossbow);Now the bot has a weapon and he is running to my position. The problem is, that he don't want to shoot!
I think the new trigger command is setImageTrigger(0,true); I know there was the same question like this a month before and it wasn't answered. So I think there is no way to have a bot shooting from script. Maybe this function is broken. Or is there someone with a shooting bot in the HEAD version ??
What I also noticed is, when the bot reached his destination, he makes some stupid dancing animation instead of standing still.
#9
If not, I don't have to try longer where I make a mistake.
Michael
12/04/2002 (7:52 am)
Anybody who knows if the function setImageTrigger is working that a bot is shooting ?????If not, I don't have to try longer where I make a mistake.
Michael
#10
12/04/2002 (8:14 am)
I had no luck getting the trigger running - but I also didn't try very hard. Because of the particular application of bots I had in mind, I just said heck with it, and did a little custom scripting for the UFO's in Trajectory Zone - but, I'm not sure that it would be very beneficial in your case :-/
#11
yeh it's sad to try and try with no succes, even I'm happy to get it work to set a NPC from the mission editor. Anyway I'm interesting in your code to see how you get around it. Also why we didn't get an official answer to that problem in case we are not alone ???
12/04/2002 (8:43 am)
Hi Davis,yeh it's sad to try and try with no succes, even I'm happy to get it work to set a NPC from the mission editor. Anyway I'm interesting in your code to see how you get around it. Also why we didn't get an official answer to that problem in case we are not alone ???
#12
We can't get an answer, probably because no one knows about it. Jeff & Co. don't spend all day crusing the forums - they've also got game development and Torque develpment to do :-) If you think it's a bug (and dig deep in the C++ files before saying that - it may not be, it may be just a change in how things work now :-) Also check the .dump() of the object, and see if there's another way to fire, and what AI methods are available.), then be sure to file it on the bug board for Torque. I didn't bother since for my purposes, I really didn't care about things like weapon mounts - it's a UFO, it could fire from any angle ;-) So, I changed things a bit, and did this:
That just picked the UFO's location, and created a little offset there so that the projectile didn't instance inside of it. Then, I gave it a random direction and velocity to fire from. Not the BEST solution in the world, but, it was quick and dirty, and did what I needed it to do ;-)
Hope that helps...
12/04/2002 (10:34 am)
Quote:yeh it's sad to try and try with no succes, even I'm happy to get it work to set a NPC from the mission editor. Anyway I'm interesting in your code to see how you get around it. Also why we didn't get an official answer to that problem in case we are not alone ???
We can't get an answer, probably because no one knows about it. Jeff & Co. don't spend all day crusing the forums - they've also got game development and Torque develpment to do :-) If you think it's a bug (and dig deep in the C++ files before saying that - it may not be, it may be just a change in how things work now :-) Also check the .dump() of the object, and see if there's another way to fire, and what AI methods are available.), then be sure to file it on the bug board for Torque. I didn't bother since for my purposes, I really didn't care about things like weapon mounts - it's a UFO, it could fire from any angle ;-) So, I changed things a bit, and did this:
%launchPosition = %alien.player.position;
%launchPosition = setword(%launchposition, 2, getword(%launchposition, 2) + 2);
%muzzleVector = (getrandom(-90, 90)/100) SPC (getrandom(-90, 90)/100) SPC (getrandom(0,90)/100);
%muzzleVelocity = VectorAdd(
VectorScale(%muzzleVector, getRandom(15, 90)),
VectorScale(0, 0));
%p = new (Projectile)() {
dataBlock = %projectile;
initialVelocity = %muzzleVelocity;
initialPosition = %launchPosition;
sourceObject = %alien.player;
sourceSlot = 0;
client = %alien;
};
MissionCleanup.add(%p);That just picked the UFO's location, and created a little offset there so that the projectile didn't instance inside of it. Then, I gave it a random direction and velocity to fire from. Not the BEST solution in the world, but, it was quick and dirty, and did what I needed it to do ;-)
Hope that helps...
#13
and
does work just fine, for me from a HEAD in late October.
12/04/2002 (10:53 am)
Michael, the functions you don't understand are explained at the top of AIPlayer.cs// The AIPlayer C++ class implements the following methods. // // AIPlayer::stopMove(); // Stop the player where he is. // // AIPlayer::clearAim(); // Clear any current aim location or aim object. The player will // maintain his current orientation, or face towards his destination // if moving. // // AIPlayer::setMoveSpeed( float ); // Set the speed (0-1) at which the player moves. // // AIPlayer::setMoveDestination( "x y z" ); // Set the destination point to move towards. The Z location is ignored // though the player will face upwards (or downards) towards the destination // if no other aim target is set. // // AIPlayer::getMoveDestination(); // Returns the current destination point. // // AIPlayer::setAimLocation( \"x y z\" ); // Set a point to look at. The player maintains his orientation towards // this point even while moving towards a destination point. // // AIPlayer::setAimObject( obj ); // Set an object to look at. The player maintains his orientation towards // this object, even while moving towards a destination point. The aim // object can also be moving. // // AIPlayer::getAimLocation(); // Returns the current point the player is looking at. If the player has // an aimObject set, this would be the current position of the target // object. // // AIPlayer::getAimObject(); // Returns the current target object, if there is one.
and
%obj.setImageTrigger(0,true);
does work just fine, for me from a HEAD in late October.
#14
12/04/2002 (10:54 am)
Hmm, that looks interesting, maybe the only way that a bot will shoot. You are right, maybe someone knows how it works now. Yesterday I was reading the dump list again and again but there is only one trigger function.
#15
12/04/2002 (11:45 am)
Hi Ken, I have no problems to understand these functions above but my bot still doesn't shoot. So sorry I will post my shooting code here. It's a bit different from Stefans, maybe someone can figure out what is wrong ( I can see the message "NPC is shooting...") , so here is the code :function AIPlayer::shootHimIfYouSeeHim(%this, %playPos)
{
%myrange = 500;
%iSeeHim = AIPlayer::isObjectInView(%this, $daPlaya, %myrange);
error(%this.player SPC "isObjectInView:" SPC %iSeeHim);
if(%iSeeHim)
{
error(%this.player @ ": I see him!!!");
%this.setAimLocation($daPlaya.getWorldBoxCenter());
// do we have a weapon?
if ( (%this.hasInventory("Crossbow") && %this.hasInventory("CrossbowAmmo"))
|| (%this.hasInventory("Rifle") && %this.hasInventory("RifleAmmo")) )
{
%this.setAimObject($daPlaya);
%this.setAimLocation($daPlaya.getWorldBoxCenter());
// shoooooot
error("NPC is shooting..." SPC %this);
%this.setImageTrigger(0,true);
}
else
{
error(%this.player SPC "has no weapon/ammo!");
}
%this.setMoveDestination(%playPos);
}
// no player in sight?
else
{
// clear aim
%this.clearAim();
// check for next nearest player
%nextClient = ClientGroup.getObject(AIPlayer::getClosestHuman(%this));
$daPlaya = %nextClient.player;
if(!isObject($daPlaya))
{
return;
}
%playPos = $daPlaya.getPosition();
%this.setMoveDestination(%playPos);
%this.setAimObject(%client.player);
%this.setAimLocation($daPlaya.getWorldBoxCenter());
}
}
#16
And this to the public section of aiPlayer.h:
and call it with
%player.fireWeapon(true);
to start firing
or
%player.fireWeapon(false);
(or whatever variable holds your AIPlayer object... %obj, $bots[0], etc....)
e.g. in my bot adding function:
12/04/2002 (11:48 am)
ok, add this to aiPlayer.cc:// add this to the constructor:
mModeFire = false;
// and this anywhere in the class...
/**
* Tells the AI to fire.
*/
void AIPlayer::fireWeapon(bool enable) {
// Fire the seclected weapon.
if(enable)
{
mModeFire = true;
throwCallback( "onShoot" );
}
else
{
mModeFire = false;
throwCallback( "onUnshoot" );
}
}
ConsoleMethod( AIPlayer, fireWeapon, void, 3, 3, "ai.fireWeapon(bool)")
{
AIPlayer *ai = static_cast<AIPlayer *>( object );
ai->fireWeapon(dAtob(argv[2]));
}
// add this in
// bool AIPlayer::getAIMove(Move *movePtr)
// right after
// movePtr->pitch = newPitch - headRotation.x;
// shoot
if (mModeFire) {
const char *WeaponSlot = Con::getVariable("$WeaponSlot");
S32 slot = dAtoi(WeaponSlot);
if (slot >= 0 && slot < ShapeBase::MaxMountedImages) {
if (getMountedImage(slot)) {
if (!movePtr->trigger[slot]) {
// shoot trigger
movePtr->trigger[slot] = true;
}
}
}
}
...And this to the public section of aiPlayer.h:
bool mModeFire;
and call it with
%player.fireWeapon(true);
to start firing
or
%player.fireWeapon(false);
(or whatever variable holds your AIPlayer object... %obj, $bots[0], etc....)
e.g. in my bot adding function:
function serverCmdAddBot(%client) {
MissionCleanup.add($bots);
%npcName = "Bot" @ $botCounter;
$bots[$botCounter] = AIPlayer::spawnPlayer(%npcName);
MissionCleanup.add($bots[$botCounter]);
serverCmdMoveBotToPlayer(%client,$bots[$botCounter]);
$bots[$botCounter].fireWeapon(true);
$botCounter++;
}
function serverCmdMoveBotToPlayer(%client,%bot)
{
if (isObject(%client.player) && isObject(%bot))
{
%bot.setAimLocation( %client.player.getPosition() );
%bot.setMoveDestination( %client.player.getPosition() );
echo("Moving to current position of the player!");
}
}
#17
Actually your problem is simple: you should avoid using setAimLocation() after you do a setAimObject(). Otherwise, the aim object gets cleared! When you setAimObject(), the aim location is automatically set to this object.
12/04/2002 (12:20 pm)
Michael,Actually your problem is simple: you should avoid using setAimLocation() after you do a setAimObject(). Otherwise, the aim object gets cleared! When you setAimObject(), the aim location is automatically set to this object.
#18
12/04/2002 (12:39 pm)
oops, forgot some stuff to go into the public section of the aiPlayer.h file... :Pbool mModeFire; void fireWeapon(bool enable);hope that's all ...
#19
Thank you Stefan
12/04/2002 (1:07 pm)
Stefan, all I can say is thank you very much. Between 10 minutes my bot was shooting at me, and I have no chance against him. For all, who have problems with setImageTrigger, this is the working code.Thank you Stefan
#20
12/05/2002 (2:18 pm)
You don't need stephan's code to have Bots fire when command with getImageTrigger.
Torque Owner Davis Ray Sickmon, Jr
Default Studio Name
in your NPC::Create, just after you've created your new bot, slap in:
echo("NEW BOT:" SPC %obj);That will dump the number fer your brand new bot into the console window. take the number, and type (whatever the number is).dump();That gives you a listing of all the methods, etc. for an object. From there, you can also tell if for some reason it's not generating it at all (there won't be a value in %obj).
IIRC, semi-recently the AI code changed a bunch - look at the dump and see what is available to work from now, and go from there.