aiPlayer "AI" extensions
by Stefan Beffy Moises · 01/16/2003 (2:21 pm) · 65 comments
Download Code File
NOTE: you should be able to just copy the files over your fresh HEAD of Torque, compile and simply add a bot (which will attack you by default) with CTRL-B...
This line in commands.cs determines what the bot will initially do (in this case, hunt down the player):
just add this to aiPlayer.h and aiPlayer.cc:
Then, these go into aiPlayer.h:
If you haven't done so already, add aiPlayer.* to your project and compile...
Then, add this to "server/scripts/commands.cs":
and this to "client/scripts/default.bind.cs":
Hm, and that should be it... if you have any questions/problems, post them here or on our website at tork.zenkel.com
If the above download doesn't work, you can grab the files here
NOTE: you should be able to just copy the files over your fresh HEAD of Torque, compile and simply add a bot (which will attack you by default) with CTRL-B...
This line in commands.cs determines what the bot will initially do (in this case, hunt down the player):
$bots[$botCounter].setAttackTargetObject(%client.player);other possible commands are:
$bots[$botCounter].setFollowTargetObject(%client.player); // follows the player or $bots[$botCounter].setScanningPlayers(true); // if a player comes into sight, he is hunted down... :DOk, first of all, I have added a processTick function to the AIPlayer, so that you don't have to rely on callback functions, instead the bots get constantly updated now...
just add this to aiPlayer.h and aiPlayer.cc:
// updating - beffy void processTick(const Move* move);
// beffy - added to have constant updates
void AIPlayer::processTick(const Move* move)
{
doActivities();
if (getAttackTargetObject())
attackTarget();
if (getFollowTargetObject())
followTarget();
Parent::processTick(move);
}Then, these go into aiPlayer.h:
// ---Scanning // Jimomighty
bool mScanningPlayers;
F32 mScanningPlayersDistance;
void scanningPlayers();
void setScanningPlayers(bool enable);
void setScanningPlayersDistance( const F32 distance );
// ---Following // Jimomighty
bool mFollowTargetInLOS;
SimObjectPtr<ShapeBase> mFollowTargetObject;
void setFollowTargetObject( ShapeBase *followtargetObject );
S32 getFollowTargetObject() const;
void followTarget();
F32 getFollowTargetLOS() const { return mFollowTargetInLOS; }
// ---Attacking // Jimomighty
bool mAttackTargetInLOS;
SimObjectPtr<ShapeBase> mAttackTargetObject;
void setAttackTargetObject( ShapeBase *attacktargetObject );
S32 getAttackTargetObject() const;
void attackTarget();
F32 getAttackTargetLOS() const { return mAttackTargetInLOS; }
bool mModeFire;
bool mModeJump;
// ---Target Control // Jimomighty
void clearAllTargets();
void clearActionTargets();
void clearAttackTarget();
void clearFollowTarget();
// ---Misc // Jimomighty
void doActivities();
S32 getTargetDistance() const;
void checkTargetLOS();
void fireWeapon(bool enable);
void doJump(bool enable);
void doJump();
bool mJump;I don't want to paste all the complete functions here, just look into the .cc file to read them... :)If you haven't done so already, add aiPlayer.* to your project and compile...
Then, add this to "server/scripts/commands.cs":
$botCounter = 0;
function serverCmdAddBot(%client) {
MissionCleanup.add($bots);
%npcName = "Bot" @ $botCounter;
$bots[$botCounter] = AIPlayer::spawnPlayer(%npcName);
MissionCleanup.add($bots[$botCounter]);
$bots[$botCounter].setAttackTargetObject(%client.player);
$botCounter++;
}and this to "client/scripts/default.bind.cs":function addBot(%val)
{
if(%val)
{
commandToServer('AddBot');
}
}
moveMap.bind(keyboard, "ctrl b", addBot);and last but not least this line to "client/config.cs" also:and this to "client/scripts/default.bind.cs":
moveMap.bind(keyboard, "ctrl b", addBot);
Hm, and that should be it... if you have any questions/problems, post them here or on our website at tork.zenkel.com
If the above download doesn't work, you can grab the files here
#2
01/14/2003 (10:40 pm)
What do you mean with "re-load"? Respawn? Track the player again if he respawns?
#3
01/17/2003 (3:34 am)
Way to go Stefan (and Jimomighty)! AI is one area that has been lacking. I was going to start looking at some bot stuff again this weekend and this should help.
#4
01/17/2003 (9:31 am)
Thanks for finishing that up, guys. Always felt like I dropped the ball on the AI.
#5
-Sabrecyd
01/17/2003 (2:02 pm)
Stefan, I added the small amount of code needed to set the "scanningsite" value if you'd like to use it. This way differnt bots can have a value other then 100. I'll be out drinking tonight, but I can send you the changed aiplayer files tomorrow. Just let me know :)-Sabrecyd
#6
01/17/2003 (3:36 pm)
I meant so he will reload his weapon as i don't have automatic reloading.
#7
@Pat: you were the one to get the ball rolling with your original AIPlayer class - so thank you!
@Edward: hm, there is some resource for weapon reloading in the resources... just put that in and instead of mapping the reload to a key, trigger it automatically as soon as the bot runs out of ammo (or simply do a "incInventory(RifleAmmo,500)" or something like that...) Shouldn't be too hard to implement... maybe I'll look into it if I find the time...
01/18/2003 (4:07 am)
@Sabrecyd: sure, go ahead! If anybody else is extending this, feel free to post your improvements here :)@Pat: you were the one to get the ball rolling with your original AIPlayer class - so thank you!
@Edward: hm, there is some resource for weapon reloading in the resources... just put that in and instead of mapping the reload to a key, trigger it automatically as soon as the bot runs out of ammo (or simply do a "incInventory(RifleAmmo,500)" or something like that...) Shouldn't be too hard to implement... maybe I'll look into it if I find the time...
#8
This is to have the ability to set the bots scanning value from script. For example: Add this line to the spawn bot script in aiplayer.cs:
%player.setSite(20);
I put it just below the line:
%player.setEnergyLevel(60);
Here's the c-code changes needed. Line numbers should be close, but I have a couple other changes made.
In aiplayer.h
Around line 30,
below this:
F32 mMoveSpeed; add:
F32 mSite; // Sabrecyd
Around line 60,
below this:
void setMoveSpeed( const F32 speed );
F32 getMoveSpeed() const { return mMoveSpeed; } add:
void setSite( const F32 site ); // Sabrecyd
F32 getSite() const { return mSite; }
In aiplayer.cc
Around line 62,
below this:
void AIPlayer::setMoveSpeed( F32 speed )
{
mMoveSpeed = getMax(0.0f, getMin( 1.0f, speed ));
} add:
void AIPlayer::setSite( F32 site ) // Sabrecyd
{
mScanningPlayersDistance = site;
}
Around line 363,
below this:
ConsoleMethod( AIPlayer, setMoveSpeed, void, 3, 3, "ai.setMoveSpeed( float );" )
{
AIPlayer *ai = static_cast( object );
ai->setMoveSpeed( dAtof( argv[2] ) );
} add:
ConsoleMethod( AIPlayer, setSite, void, 3, 3, "ai.setSite( float );" ) // Sabrecyd
{
AIPlayer *ai = static_cast( object );
ai->setSite( dAtof( argv[2] ) );
}
I think that
01/20/2003 (7:25 am)
Ok, finally got around to it. Friday was rough ;)This is to have the ability to set the bots scanning value from script. For example: Add this line to the spawn bot script in aiplayer.cs:
%player.setSite(20);
I put it just below the line:
%player.setEnergyLevel(60);
Here's the c-code changes needed. Line numbers should be close, but I have a couple other changes made.
In aiplayer.h
Around line 30,
below this:
F32 mMoveSpeed; add:
F32 mSite; // Sabrecyd
Around line 60,
below this:
void setMoveSpeed( const F32 speed );
F32 getMoveSpeed() const { return mMoveSpeed; } add:
void setSite( const F32 site ); // Sabrecyd
F32 getSite() const { return mSite; }
In aiplayer.cc
Around line 62,
below this:
void AIPlayer::setMoveSpeed( F32 speed )
{
mMoveSpeed = getMax(0.0f, getMin( 1.0f, speed ));
} add:
void AIPlayer::setSite( F32 site ) // Sabrecyd
{
mScanningPlayersDistance = site;
}
Around line 363,
below this:
ConsoleMethod( AIPlayer, setMoveSpeed, void, 3, 3, "ai.setMoveSpeed( float );" )
{
AIPlayer *ai = static_cast
ai->setMoveSpeed( dAtof( argv[2] ) );
} add:
ConsoleMethod( AIPlayer, setSite, void, 3, 3, "ai.setSite( float );" ) // Sabrecyd
{
AIPlayer *ai = static_cast
ai->setSite( dAtof( argv[2] ) );
}
I think that
#9
I used an older version of aiPlayer tutor. which calls the function "setTrigger". and as that function seems to be no longer exist in the Head version. the aiplayer don't really SHOOT.
Then I try this tutor. But I found that the function "DoJump()" and "DoShoot" is called. But the aiPlayer don't really Shoot, nor Jump.
It is some part missing?
01/26/2003 (3:53 am)
Thanks for this tutor.I used an older version of aiPlayer tutor. which calls the function "setTrigger". and as that function seems to be no longer exist in the Head version. the aiplayer don't really SHOOT.
Then I try this tutor. But I found that the function "DoJump()" and "DoShoot" is called. But the aiPlayer don't really Shoot, nor Jump.
It is some part missing?
#10
I applied all suggested changes and found two issues:
1. on bot creation I got message:
Mapping string: Bot0 to index: 13
Set::add: Object "" doesn't exist <-- why?!
2. AIPlayers don't do anything, neither move nor shoot :-(
Also I found in parent's Player::processTick() method:
if( mControlObject ) <-- this is ALWAYS FALSE
{
// this block is NEVER executed!
if( !move )
{
mControlObject->processTick(0);
}
else
{
pMove = NullMove;
cMove = *move;
...
}
...
mControlObject->processTick((mDamageState == Enabled)? &cMove: &NullMove); // It's responsible for actual moving, right?
}
Did I miss anything?
01/27/2003 (5:55 am)
Great article, but...I applied all suggested changes and found two issues:
1. on bot creation I got message:
Mapping string: Bot0 to index: 13
Set::add: Object "" doesn't exist <-- why?!
2. AIPlayers don't do anything, neither move nor shoot :-(
Also I found in parent's Player::processTick() method:
if( mControlObject ) <-- this is ALWAYS FALSE
{
// this block is NEVER executed!
if( !move )
{
mControlObject->processTick(0);
}
else
{
pMove = NullMove;
cMove = *move;
...
}
...
mControlObject->processTick((mDamageState == Enabled)? &cMove: &NullMove); // It's responsible for actual moving, right?
}
Did I miss anything?
#11
I create a aiBot (by script) this way:
function createanewbot(){
%newbot = AIPlayer::spawnPlayer();
%newbot.setShapeName( "Bill gate No." @ (%x + 1));
// every player starts with a rifle for now...
%weapon = new Item(){
dataBlock = Rifle;
};
%ammo = new Item(){
dataBlock = RifleAmmo;
};
MissionCleanup.add(%weapon);
MissionCleanup.add(%ammo);
%newbot.pickup(%weapon, 1);
%newbot.pickup(%ammo, 2);
%newbot.use(Rifle);
MissionCleanup.add(%newbot);
$MyBot[%botnumber] = %newbot;
}
An I use the default aiPlayer console functions to drive the bots like this:
$MyBot[%botnumber].setMoveDestinat(ClientGroup.getObject(0).player.getPosition());
You can drive the bots by inputting command interactivily in the console,
or schedule the ai Logic like this:
$MyBot[0].Schedule(5000, 0, "MyAiRoutine");
Try search a privious version of aiPlayer tutor, which is also by Stefan too.
and look for the 'schedule' related resourse for more details.
Hope the infomation may help you :)
01/28/2003 (8:05 am)
Hi Roman,I create a aiBot (by script) this way:
function createanewbot(){
%newbot = AIPlayer::spawnPlayer();
%newbot.setShapeName( "Bill gate No." @ (%x + 1));
// every player starts with a rifle for now...
%weapon = new Item(){
dataBlock = Rifle;
};
%ammo = new Item(){
dataBlock = RifleAmmo;
};
MissionCleanup.add(%weapon);
MissionCleanup.add(%ammo);
%newbot.pickup(%weapon, 1);
%newbot.pickup(%ammo, 2);
%newbot.use(Rifle);
MissionCleanup.add(%newbot);
$MyBot[%botnumber] = %newbot;
}
An I use the default aiPlayer console functions to drive the bots like this:
$MyBot[%botnumber].setMoveDestinat(ClientGroup.getObject(0).player.getPosition());
You can drive the bots by inputting command interactivily in the console,
or schedule the ai Logic like this:
$MyBot[0].Schedule(5000, 0, "MyAiRoutine");
Try search a privious version of aiPlayer tutor, which is also by Stefan too.
and look for the 'schedule' related resourse for more details.
Hope the infomation may help you :)
#12
I feel stucked :-(
My bot does not react to any command! I got neither error message nor response from aiPlayer...
Whatever I change, it seems not to work: mControlObject is ALWAYS Null, so moving function doesn't work. But it's also Null for my player and it works (or problem is somewhere else).
I've also found aiConnection class but it is not used in this tutorial, isn't it?
Anyway I didn't manage to make this aiPlayer working yet :-(
My questions may seem quite stupid but I'm completely newbie to Torque...
01/28/2003 (10:45 pm)
Thanks Yui,I feel stucked :-(
My bot does not react to any command! I got neither error message nor response from aiPlayer...
Whatever I change, it seems not to work: mControlObject is ALWAYS Null, so moving function doesn't work. But it's also Null for my player and it works (or problem is somewhere else).
I've also found aiConnection class but it is not used in this tutorial, isn't it?
Anyway I didn't manage to make this aiPlayer working yet :-(
My questions may seem quite stupid but I'm completely newbie to Torque...
#13
The aiConnection class is no longer used. Just forget it.
Have you tried the older version of Stefan's tutor? try seeach the resourse with the keyword "aiplayer".
Before working on the c++ files. I think you can try to insert and control with pure script first. The clean HEAD version without any update is enough to do so.
As long as you have put an aiplayer into the stage. the aiplayer should have a id. Use 'echo' command to print the id of it. and you can use the id to call the class function in the console like this: "id.command();". e.g. if the id of the aiplayer is 1234. then type "1234.setAimObject();" to make it alway looking at you.
I am a "little bit advanced newbie" too. Hope this message could help.
01/30/2003 (12:50 am)
Hi Roman,The aiConnection class is no longer used. Just forget it.
Have you tried the older version of Stefan's tutor? try seeach the resourse with the keyword "aiplayer".
Before working on the c++ files. I think you can try to insert and control with pure script first. The clean HEAD version without any update is enough to do so.
As long as you have put an aiplayer into the stage. the aiplayer should have a id. Use 'echo' command to print the id of it. and you can use the id to call the class function in the console like this: "id.command();". e.g. if the id of the aiplayer is 1234. then type "1234.setAimObject();" to make it alway looking at you.
I am a "little bit advanced newbie" too. Hope this message could help.
#14
I dont really want to use HEAD as getting the updates is a pain in the neck to say the least (because of my school, not because it's CVS), so I woud like to know if it's worth the effort.
03/07/2003 (8:12 am)
Mmmh, I am reading all I can on AI, and I was wondering if any of you guys could tell me what are the big changes between 1.1.2 and HEAD ? I dont really want to use HEAD as getting the updates is a pain in the neck to say the least (because of my school, not because it's CVS), so I woud like to know if it's worth the effort.
#15
If you want to add this to the 1.1.2 version, download beffy's zip and follow the instructions. The only change you'll need to make will be in Player.cc at the top of the processTick() function.
Make it look like this:
[code]
void Player::processTick(const Move* move)
{
PROFILE_START(Player_ProcessTick);
// If we are not being controlled by a client, let the
// AI sub-module get a chance at producing a move.
Move aiMove;
if (!move && getAIMove(&aiMove))
move = &aiMove;
03/13/2003 (12:33 pm)
Philippe,If you want to add this to the 1.1.2 version, download beffy's zip and follow the instructions. The only change you'll need to make will be in Player.cc at the top of the processTick() function.
Make it look like this:
[code]
void Player::processTick(const Move* move)
{
PROFILE_START(Player_ProcessTick);
// If we are not being controlled by a client, let the
// AI sub-module get a chance at producing a move.
Move aiMove;
if (!move && getAIMove(&aiMove))
move = &aiMove;
#16
04/13/2003 (8:07 am)
I'm a new game Developers.I had bought the Torque Game Engine SDK.I want to add other player in my DEMO,so i want add aiPlayer.I had look this paper.but i don't know how to add aiplayer in my demo.I want you help.thank you .
#17
Thanks,
-Nick
P.S.: This is an awesome resource.
04/24/2003 (9:48 am)
I noticed a strange effect when using this AI addition. A bot is spawned properly, detects the player's presence correctly, and hunts him. However, it (the bot) keeps circling around and about the player and ONLY shoots when the player is in the air (e.g. during a jump or a fall). Any idea why this might be happening and how to fix it?Thanks,
-Nick
P.S.: This is an awesome resource.
#18
this is an awesome resource. I did exactly you have specified but the bots dont move. I downloaded the head version and added your aiplayer.cc. It compiles and bot shows up but doesnt move. Can you please help. where can the problem lie? thanks in advance.
07/01/2003 (12:23 pm)
hi beffy,this is an awesome resource. I did exactly you have specified but the bots dont move. I downloaded the head version and added your aiplayer.cc. It compiles and bot shows up but doesnt move. Can you please help. where can the problem lie? thanks in advance.
#19
not sure... do you add it with "CTRL B" like explained above?
Do you get any errors in the console?
07/01/2003 (2:05 pm)
Hi,not sure... do you add it with "CTRL B" like explained above?
Do you get any errors in the console?
#20
thanks for ur quick reply. It worked. My mistake. But I still have some problems. I tried your code with the stable version (not the head). It didnt quite work. I made changes to player.cc and added the code in processTick() as explained in one of the threads above, but the bots dont move. Plus do I have to delete the bots once I leave the mission or they get taken care of by the endgame? I guess I will have to atleast reset the botnumber count coz they keep on increasing.
thanks a ton.
07/01/2003 (3:20 pm)
hi beffy,thanks for ur quick reply. It worked. My mistake. But I still have some problems. I tried your code with the stable version (not the head). It didnt quite work. I made changes to player.cc and added the code in processTick() as explained in one of the threads above, but the bots dont move. Plus do I have to delete the bots once I leave the mission or they get taken care of by the endgame? I guess I will have to atleast reset the botnumber count coz they keep on increasing.
thanks a ton.
Torque Owner Edward Smith
Silencersoft