Slightly advanced bot scripting
by Stefan Beffy Moises · 04/08/2002 (12:03 pm) · 54 comments
So you got bots in your game running around randomly and maybe to specific locations?
Cool! (If not, make sure you've read my previous tutorial on adding bots to a game ;-) ...)
But wouldn't it be cooler to make them hunt you? Move along waypoints?
Or search the next nearest player and hunt
him? Well, you are pretty close... read on!
Credits go to Jared Hoberock and Ryan Mette for providing some cool additional functions in the forums! Thanks, guys! :-)
First of all, I took the test mission and added some waypoints in the world editor creator (F11 - F4)
and put them in a seperate SimGroup to access them from script later on:
For the next part we need to add a little snipit to the engine code to clear the bots aim through script.
The function itself is already in aiPlayer.cc, it simply sets the aim location to the
current destination point of the AI, like this:
It just wasn't exposed to the scripting engine, so I did it:
Then, in aiPlayer.cs, I got a handy little function following any waypoints in this SimGroup and/or chasing the
player if finished:
This next function bascially tests if the player's position is in view and
if it is, the AI aims and shoots at him (if a weapon and some ammo are available -
NOTE: hasInventory() is defined in inventory.cs.
I'm using Spock's Inventory Manager, though -
I will show you two versions of the function, hold on...).
so here are the functions I added in inventory.cs to check for available weapons,
the first one is for the "traditional" inventory system,
the second one is for Spock's inventory manager:
The next function checks if the target is in view. First it sets the sight range of the
AI, you might want to adjust this...
The next piece of code searches for the closest human player.
It simply iterates through the ClientGroup and checks the distance to
the available clients.
Now some little helper functions: the first returns the number of available bot waypoints,
the second returns the distance to the next waypoint.
Yep, that should be it...
If I missed something, please let me know ;-)
Of course this isn't really Artificial Intelligent behaviour, but at least it's fun :-)
All the *real* AI stuff like pathfinding/planning will hopefully be implemented soon - I'm really curious to see Phil's results of including the U.N.Bot (see AI-Depot for details...)
But for now, have fun!
Cool! (If not, make sure you've read my previous tutorial on adding bots to a game ;-) ...)
But wouldn't it be cooler to make them hunt you? Move along waypoints?
Or search the next nearest player and hunt
him? Well, you are pretty close... read on!
Credits go to Jared Hoberock and Ryan Mette for providing some cool additional functions in the forums! Thanks, guys! :-)
First of all, I took the test mission and added some waypoints in the world editor creator (F11 - F4)
and put them in a seperate SimGroup to access them from script later on:
new SimGroup(BotMarkers) {
new WayPoint() {
position = "84.7609 -329.467 181.154";
rotation = "1 0 0 0";
scale = "1 1 1";
dataBlock = "WayPointMarker";
name = "1";
team = "0";
};
new WayPoint() {
position = "91.9828 -332.776 184.206";
rotation = "1 0 0 0";
scale = "1 1 1";
dataBlock = "WayPointMarker";
name = "2";
team = "0";
};
new WayPoint() {
position = "98.164 -330.142 187.618";
rotation = "1 0 0 0";
scale = "1 1 1";
dataBlock = "WayPointMarker";
name = "3";
team = "0";
};
new WayPoint() {
position = "119.626 -343.224 208.346";
rotation = "1 0 0 0";
scale = "1 1 1";
dataBlock = "WayPointMarker";
name = "4";
team = "0";
};
new WayPoint() {
position = "138.997 -327.711 225.599";
rotation = "1 0 0 0";
scale = "1 1 1";
dataBlock = "WayPointMarker";
name = "5";
team = "0";
};
};For the next part we need to add a little snipit to the engine code to clear the bots aim through script.
The function itself is already in aiPlayer.cc, it simply sets the aim location to the
current destination point of the AI, like this:
/**
* Clears the aim location and sets it to the bot's
* current destination so he looks where he's going
*/
void AIPlayer::clearAim() {
mAimLocation = Point3F( 0.0f, 0.0f, 0.0f );
mAimToDestination = true;
}It just wasn't exposed to the scripting engine, so I did it:
/**
* Clears the point the AI is aiming at
*/
ConsoleMethod( AIConnection, clearAim, void, 2, 2, "ai.clearAim();" ) {
AIPlayer *ai = static_cast<AIPlayer*>( object );
ai->clearAim();
}Then, in aiPlayer.cs, I got a handy little function following any waypoints in this SimGroup and/or chasing the
player if finished:
function AIPlayer::handleWaypointsAndChase(%this)
{
// look for next "available" human player... :-)
%nextClient = ClientGroup.getObject(AIPlayer::getClosestHuman(%this));
$daPlaya = %nextClient.player;
if(!isObject($daPlaya) || !isObject(%this))
{
return;
}
// get his position:
%playPos = $daPlaya.getPosition();
// but first look for some waypoints...
// if there are some waypoints to follow
if(isObject(BotMarkers))
{
%num = getNumberBotMarkers();
// %this.countMyMoves tracks the number of waypoints already passed by this AI
if(%this.countMyMoves $= "")
{
//echo number of waypoint once
echo(%num @ " BotMarkers found!");
}
// output player posititon
error("Player Position: " @ %playPos);
// as long as this bot hasn't completed the waypoint path:
if(%this.countMyMoves < BotMarkers.getCount())
{
%dest = BotMarkers.getObject(%this.countMyMoves).position;
echo("Next destination: " @ %dest);
echo("The distance is: " @ getMarkerDistance(%this.countMyMoves, %this));
echo("myMoves along the waypoint path:" SPC %this.countMyMoves);
%this.setMoveDestination(%dest);
%this.move();
%this.countMyMoves++;
}
// okay, finished path, time for hunting the player...
else
{
AIPlayer::shootHimIfYouSeeHim(%this, %playPos);
}
}
// else: No waypoints, so chase the player!
else
{
AIPlayer::shootHimIfYouSeeHim(%this, %playPos);
}
}This next function bascially tests if the player's position is in view and
if it is, the AI aims and shoots at him (if a weapon and some ammo are available -
NOTE: hasInventory() is defined in inventory.cs.
I'm using Spock's Inventory Manager, though -
I will show you two versions of the function, hold on...).
function AIPlayer::shootHimIfYouSeeHim(%this, %playPos)
{
%this.setTargetObject($daPlaya);
%iSeeHim = aiPlayer::isObjectInView(%this, $daPlaya);
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.player.hasInventory("Crossbow") && %this.player.hasInventory("CrossbowAmmo"))
|| (%this.player.hasInventory("Rifle") && %this.player.hasInventory("RifleAmmo")) )
{
// shoooooot
%this.setTrigger(0,true);
}
else
{
error(%this.player SPC "has no weapon/ammo!");
}
%this.setMoveDestination(%playPos);
%this.move();
}
// 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.setAimLocation($daPlaya.getWorldBoxCenter());
%this.move();
}
}so here are the functions I added in inventory.cs to check for available weapons,
the first one is for the "traditional" inventory system,
the second one is for Spock's inventory manager:
// "traditional"
function ShapeBase::hasInventory(%this, %data) {
return %this.inv[%data];
}
// "Spock's way" ;-)
function ShapeBase::hasInventory(%this, %data) {
return %this.getInvItem(%data, "amount");
}The next function checks if the target is in view. First it sets the sight range of the
AI, you might want to adjust this...
// this one's provided by Ryan Mette
function aiPlayer::isObjectInView(%this, %object)
{
%player = %this.player;
// default sight range of AI:
%this.sightRange = 70.0;
if (!(isObject(%player) && isObject(%object))) return;
%objPos = %object.getWorldBoxCenter();
%eyePoint = %player.getWorldBoxCenter();
%distance = VectorDist(%objPos, %eyePoint);
error("DISTANCE:" SPC %distance);
if (%distance <= %this.sightRange)
{
// if the object is within 1.5 meters sometimes it can
// fall out of the field of view due to the eye height
if (%distance > 2)
{
%eyeTransform = %player.getEyeTransform();
%eyePoint = firstWord(%eyeTransform)
SPC getWord(%eyeTransform, 1)
SPC getWord(%eyeTransform, 2);
}
%eyeVector = VectorNormalize(%player.getEyeVector());
//make sure we're not looking through walls...
%mask = $TypeMasks::TerrainObjectType |
$TypeMasks::InteriorObjectType |
$TypeMasks::StaticShapeObjectType;
%losResult = containerRayCast(%objPos, %eyePoint, %mask);
%losObject = GetWord(%losResult, 0);
if (!isObject(%losObject))
{
//create the vector from this client to the client
%objVector = VectorNormalize(VectorSub(%objPos, %eyePoint));
// dot product to determine field of view
%dot = VectorDot(%objVector, %eyeVector);
// within field of view
return (%dot > 0.6);
}
}
return false;
}The next piece of code searches for the closest human player.
It simply iterates through the ClientGroup and checks the distance to
the available clients.
// provided by Jared Hoberock
// I changed it to use ClientGroup instead of its own array like Jared did...
function AIPlayer::getClosestHuman(%this) {
%botPos = %this.getLocation();
%count = ClientGroup.getCount();
for(%i = 0; %i < %count; %i++)
{
%client = ClientGroup.getObject(%i);
%playPos = %client.player.getPosition();
%tempDist = VectorDist(%playPos, %botPos);
if(%i == 0) {
%dist = %tempDist;
%index = %i;
}
else {
if(%dist > %tempDist) {
%dist = %tempDist;
%index = %i;
}
}
}
return %index;
}Now some little helper functions: the first returns the number of available bot waypoints,
the second returns the distance to the next waypoint.
function getNumberBotMarkers()
{
%count = BotMarkers.getCount();
return %count;
}
function getMarkerDistance(%markernumber, %bot)
{
%botPosition = %bot.getLocation();
%markerObject = BotMarkers.getObject(%markernumber);
%dist = vectorDist( %botPosition, %markerObject.position );
return %dist;
}Yep, that should be it...
If I missed something, please let me know ;-)
Of course this isn't really Artificial Intelligent behaviour, but at least it's fun :-)
All the *real* AI stuff like pathfinding/planning will hopefully be implemented soon - I'm really curious to see Phil's results of including the U.N.Bot (see AI-Depot for details...)
But for now, have fun!
#2
04/10/2002 (8:40 am)
Well, here's a little add-on to my code, sounds like it could be useful for you, too, Bradley... it checks the health of the AI, and if the damage level is >= 60, it searches for the next available HealthPatch, runs over it until the damage is below 60 again and then continues to chase the next nearest human player... here it goes:// a little addon to "shootHimIfYouSeeHim"
//(love that function name, hehe...)
function AIPlayer::shootHimIfYouSeeHim(%this, %playPos)
{
%botDamage = %this.getControlObject().getDamageLevel();
error("AI DamageLevel:" SPC %botDamage);
if(%botDamage >= 60)
{
// scan for HEALTH objects
%nextHealthObjPos = findNearestItem(%this.player.getPosition(), "HealthPatch");
if(%nextHealthObjPos $= "")
{
echo("AI: no HealthPatch found!");
%dest = getRandom(550) SPC getRandom(550) SPC getRandom(550);
}
else
{
error("AI: Next HealthPatch position:" SPC %nextHealthObjPos);
%dest = %nextHealthObjPos;
}
%this.clearAim();
%this.setMoveDestination(%dest);
%this.move();
return;
}
... //snip
}
// and here a utitlity function doing the "dirty" work:
//(btw, thanks to Joel Baxter for the "%obj.getDatablock().getName()" tip...)
function findNearestItem(%myPos, %name)
{
%dataGroup = "MissionGroup";
for(%i = 0; %i < %dataGroup.getCount(); %i++)
{
%obj = %dataGroup.getObject(%i);
if(%obj.getClassName() !$= "Item")
{
continue;
}
if(%obj.getDatablock().getName() $= %name && isObject(%obj))
{
%objPos = %obj.position;
echo("Found object: Datablock:" SPC %obj.getDatablock().getName() SPC "ClassName:" SPC %obj.getClassName());
%tempDist = VectorDist(%objPos, %myPos);
if(%shortestDist > %tempDist || %shortestDist $= "")
{
%shortestDist = %tempDist;
%finalPos = %objPos;
}
echo("shortestDist:" SPC %shortestDist);
}
}
return %finalPos;
}"findNearestItem" is pretty handy, you can give it a position and a datablock name to search for, and it returns the next nearest Items' position... Pretty cool to watch the bots run away from you if damaged and come back if they are "healed" ... check it out! :-)
#3
I'm sure we should get some really interesting behaviour from the new AI when we get it in place.
Phil.
04/10/2002 (11:44 am)
Nice to see you having fun guys :)) most bots kind of start out like this. But this sort of hard coding usually ends up pretty messy :))I'm sure we should get some really interesting behaviour from the new AI when we get it in place.
Phil.
#4
But, as you said, it's fun and I'm doing it mainly to get some overview of the scripting side of things...
And, as I mentioned earlier, everyone is desperately waiting for the *real* AI to come in, especially this Neural Network Bot you "promised" ;-)
By the way, what's the status on that - are you already working on it or is Alex still organizing his code?
I really would LOVE to see some serious AI in TGE - once that happens, I promise to stop with these "AI scripts"... ;-))
04/10/2002 (12:33 pm)
Yep, I know, Phil... that surely isn't anything someone would seriously call "AI" ;-)But, as you said, it's fun and I'm doing it mainly to get some overview of the scripting side of things...
And, as I mentioned earlier, everyone is desperately waiting for the *real* AI to come in, especially this Neural Network Bot you "promised" ;-)
By the way, what's the status on that - are you already working on it or is Alex still organizing his code?
I really would LOVE to see some serious AI in TGE - once that happens, I promise to stop with these "AI scripts"... ;-))
#5
04/10/2002 (6:28 pm)
Ok, why do we need to use waypoints and paths. I really think it's possible to do it another way but i'll try it first and then tell. whenever i get the time.
#6
Say for instance you have a Q3 deathmatch map, you might put 35-40 waypoints in it all around the place with different paths leading amongst them in a graph layout. You would have nodes at all the weapon and ppowerup pickups with paths leading through the armour shards, etc.
Now you come to creating bots, you could right the AAA-player bot that knows the map back to front and how to get to all the pickups, so you might define it's node-path as
1->2->5->10->35->7->1
and it would then look through the path graph to find the most efficient path to thos waypoints.
Then you add the newbie bot that just sort of runs around all over the place and it's node-path might be
4->3->7->22->23->40->2->7->50->1->20->10->33
to represent the new player.
This is the sort of methodology I'll be looking to implement for bots in multiplayer, since it would allow the same sort of function as Q3 did, where people can define bots by a text file though in this case you'd have to know where your waypoints are to do so so it will limit the modability for endusers to an extent.
Now if you are talking about single-player games, then waypoints and paths will allow you to script semi-convincing pathing routines for guards, animals or whatever which I don't think really needs to be expanded upon.
Now as for a technical explination of why waypoints and paths...no collision checking and certainty :).
If you just give a location for a bot to go to, then you have to worry about checking for collision with walls, crates, whatever else you have in the way and you are never certain of the path it will take or how long it will take to get there.
If you have paths and waypoints and a list for each bot to follow, you know exactly where it's going to go, exactly what's in it's way and how long it should take to get there.
04/10/2002 (6:59 pm)
The main reason I see for setting waypoints and paths is that it allows you to either specify the cleanest way for a bot to go around a zone.Say for instance you have a Q3 deathmatch map, you might put 35-40 waypoints in it all around the place with different paths leading amongst them in a graph layout. You would have nodes at all the weapon and ppowerup pickups with paths leading through the armour shards, etc.
Now you come to creating bots, you could right the AAA-player bot that knows the map back to front and how to get to all the pickups, so you might define it's node-path as
1->2->5->10->35->7->1
and it would then look through the path graph to find the most efficient path to thos waypoints.
Then you add the newbie bot that just sort of runs around all over the place and it's node-path might be
4->3->7->22->23->40->2->7->50->1->20->10->33
to represent the new player.
This is the sort of methodology I'll be looking to implement for bots in multiplayer, since it would allow the same sort of function as Q3 did, where people can define bots by a text file though in this case you'd have to know where your waypoints are to do so so it will limit the modability for endusers to an extent.
Now if you are talking about single-player games, then waypoints and paths will allow you to script semi-convincing pathing routines for guards, animals or whatever which I don't think really needs to be expanded upon.
Now as for a technical explination of why waypoints and paths...no collision checking and certainty :).
If you just give a location for a bot to go to, then you have to worry about checking for collision with walls, crates, whatever else you have in the way and you are never certain of the path it will take or how long it will take to get there.
If you have paths and waypoints and a list for each bot to follow, you know exactly where it's going to go, exactly what's in it's way and how long it should take to get there.
#7
04/10/2002 (7:27 pm)
i've tried to implement damagelevel functions but in the console, it says that those functions are not found. what gives?
#8
04/10/2002 (8:16 pm)
Have you had any luck with creating AI piloted or controlled vehicles? I have made AI Vehicles (players) but they do not follow an "go to location" commands :/
#9
Basically, this is about how advanced the AI was in the Thief series -- in terms of how they're controlled I mean; they had more advanced stimuli defined (auditory; player visibility was determined on more than straight distance/LOS means), but these are the tools that let us build more advanced AI.
Of course the Thief AI used pathfinding, but the method they used was to trace pathing points around every obstacle, edge, crevice and feature in the world and compile it. Needless to say, this only works well for relatively small areas.
04/10/2002 (9:37 pm)
This is cool. It provides the necessary functions and tools necessary for people to make more advanced guards and so on, using scripting.Basically, this is about how advanced the AI was in the Thief series -- in terms of how they're controlled I mean; they had more advanced stimuli defined (auditory; player visibility was determined on more than straight distance/LOS means), but these are the tools that let us build more advanced AI.
Of course the Thief AI used pathfinding, but the method they used was to trace pathing points around every obstacle, edge, crevice and feature in the world and compile it. Needless to say, this only works well for relatively small areas.
#10
%this.getControlObject().getDamageLevel();
doesn't work for you?? That's strange... which Torque version are you using? Did you try it in aiPlayer.cs? Did you inlude
engine\game\aiPlayer.h
\engine\game\aiPlayer.cc
in your project and recompile the engine (see my first tutorial)?
Oh, and you don't *need* the waypoints ... if Phil puts this UNBot in, it will be able to "learn" the levels and find every path you want him to find... without any waypoints or manual path editing... Waypoints are just the only way to do it at the moment, without having to write your own pathfinding routines (which wouldn't make sense because the stuff Phil is going to put in will be much better anyways...). So while waiting for these new possibilities I simply tried to play around with what is currently available... but you don't *have* to use it, if you don't like it...
04/10/2002 (10:25 pm)
Alexander, so %this.getControlObject().getDamageLevel();
doesn't work for you?? That's strange... which Torque version are you using? Did you try it in aiPlayer.cs? Did you inlude
engine\game\aiPlayer.h
\engine\game\aiPlayer.cc
in your project and recompile the engine (see my first tutorial)?
Oh, and you don't *need* the waypoints ... if Phil puts this UNBot in, it will be able to "learn" the levels and find every path you want him to find... without any waypoints or manual path editing... Waypoints are just the only way to do it at the moment, without having to write your own pathfinding routines (which wouldn't make sense because the stuff Phil is going to put in will be much better anyways...). So while waiting for these new possibilities I simply tried to play around with what is currently available... but you don't *have* to use it, if you don't like it...
#11
change ondeath to:
This depends on putting the proper classname= in the datablock ItemData and that the ammo is namedammo ..
keep in mind that untill any pathfinding is added that the bots will get stuck ( they allways end up under the arch in waterworld )
Add the following functions:
want to create an army? ( and bring your fps down fast )
change onAdd to:
$bot=aiAddPlayer("bot the bot");
followed by
$bot.lotsobots(NUMBER);
and change the number to whatever .. BTW .. high numbers start to bog down the engine ... ALOT
ya i know this doesnt have to have the $bot.lotsobots thing .. i just have no idea how to call it from the console ...
04/22/2002 (2:08 pm)
so what good is a dead bot?change ondeath to:
function AIPlayer::ondeath(%this) {
echo( "You got me!" );
%this.spawnplayer();
}I found that bots without wepons do a bad job of killing ... so this tells him to go get a weapon and the ammo for it alsoThis depends on putting the proper classname= in the datablock ItemData and that the ammo is named
keep in mind that untill any pathfinding is added that the bots will get stuck ( they allways end up under the arch in waterworld )
Add the following functions:
function AIPlayer::getstuff(%this,%InvName)
{
%mypos=%this.player.getPosition();
%dataGroup = "MissionGroup";
for(%i = 0; %i < %dataGroup.getCount(); %i++)
{
%Name = %dataGroup.getObject(%i);
//is it an Item and not somthing like the sky?
if(%Name.getClassName() !$= "Item")
{
continue;
}
%txtname=%Name.getDataBlock().getName();
//is it what we are looking for?
if(%txtname $= %InvName)
{
%objPos = %Name.getposition();
%tempDist = VectorDist(%objPos, %myPos);
%foundit = 1;
if(%shortestDist > %tempDist || %shortestDist $= "")
{
%shortestDist = %tempDist;
%finalPos = %objPos;
}
}
}
//if you havent found it run somewhere else go get it
if(%foundit == 0)
{
%finalPos = getRandom(50) SPC getRandom(50) SPC getRandom(50);
}
echo("Found:" SPC %txtname SPC "at" SPC %objPos);
%this.clearAim();
%this.setMoveDestination(%finalPos);
%this.move();
return %foundit;
}
function AIPlayer::findweapon(%this)
{
%foundit = 0;
%mypos=%this.player.getPosition();
%dataGroup = "MissionGroup";
for(%i = 0; %i < %dataGroup.getCount(); %i++)
{
%Name = %dataGroup.getObject(%i);
// is it an Item and not somthing like the sky?
// note - everything dropable is an item
if(%Name.getClassName() !$= "Item")
{
continue;
}
// is it a weapon? ( does it have className = "Weapon";
// in the datablock ItemData )
// Note - it seems you can make up classnames when creating
// items.
%txtname=%Name.getDataBlock().classname;
if(%txtname $= Weapon)
{
%objPos = %Name.getposition();
%englishname=%Name.getDataBlock().getname();
//echo("Found weapon:" SPC %englishname);
%tempDist = VectorDist(%objPos, %myPos);
%foundit = 1;
if(%shortestDist > %tempDist || %shortestDist $= "")
{
%shortestDist = %tempDist;
%finalPos = %objPos;
%ammo=%englishname@"ammo";
}
}
}
echo("Found:" SPC %englishname SPC "at" SPC %objPos);
$weaponammo=%ammo;
%this.clearAim();
%this.setMoveDestination(%finalPos);
%this.move();
}then change onReachDestination to:function AIPlayer::onReachDestination(%this) {
echo( "onReachDestination" );
if(%this.player.hasInventory($weaponammo) == 0)
{
%this.getstuff($weaponammo);
}
}and change onAdd to:function AIPlayer::onAdd(%this) {
echo( "I've been added.." );
AIPlayer::findweapon(%this);
}want to create an army? ( and bring your fps down fast )
change onAdd to:
function AIPlayer::onAdd(%this) {
echo( "I've been added.." );
AIPlayer::wander(%this);
} and onReachDestination to:function AIPlayer::onReachDestination(%this) {
echo( "onReachDestination" );
AIPlayer::wander(%this);
}then add the functionsfunction AIPlayer::wander(%this){
%dest = getRandom(150) SPC getRandom(150) SPC getRandom(150);
%this.setMoveDestination(%dest);
%this.move();
}
function AIPlayer::lotsobots(%this, %number){
for(%botcount=0;%botcount<%number;%botcount++){
MissionGroup.add(aiAddPlayer(%botcount));
}
}then at the console type $bot=aiAddPlayer("bot the bot");
followed by
$bot.lotsobots(NUMBER);
and change the number to whatever .. BTW .. high numbers start to bog down the engine ... ALOT
ya i know this doesnt have to have the $bot.lotsobots thing .. i just have no idea how to call it from the console ...
#12
So it shouldn't be able to find Weapons and the like... or am I missing something?
04/23/2002 (6:49 am)
This still only searches for Items, doesn't it?So it shouldn't be able to find Weapons and the like... or am I missing something?
#13
04/26/2002 (11:35 pm)
delete-me
#14
so it seems that the only way to tell between a box on the ground and a rocket is in the datablocks of the script ( i could be way off on this so correct me if i'm wrong )
04/27/2002 (12:07 am)
um ... i just went through the code .. i dont seem to see a "Weapon" class per-say ( just about everything else has it's own class ) so i dont know of an easy way to sort out what is a weapon and what is just an item ( of course if you throw a health kit at another player hard enuf it could be concidered a weapon )..so it seems that the only way to tell between a box on the ground and a rocket is in the datablocks of the script ( i could be way off on this so correct me if i'm wrong )
#15
04/27/2002 (2:34 pm)
delete this please
#16
04/27/2002 (2:55 pm)
Chris, do you have a file aiPlayer.cs.dso in \example\fps\server\scripts? And is your function named AIPlayer::handleWaypointsAndChase()?
#17
04/27/2002 (3:11 pm)
Yes that file is present in the same folder as aiPlayer.cs \example\fps\server\scripts and My function is named the above. When i remove the .dso file from the directory the findWaypointsAndChase() function works but the others in aiPlayer.cs do not hmmm? Any help appreciatted as always
#18
edit: seems i cant posting anything without at least 1 typo
04/27/2002 (5:46 pm)
hit ~ in game and scroll up .. you should see an error while compileing aiplayer.cs ... their will be ## ## NEER the erroredit: seems i cant posting anything without at least 1 typo
#19
04/27/2002 (7:40 pm)
Great that worked for me. All of the above AI code works great and gives me a great idea of how to work on it. Can anyone answer these questions though? Why dont my bots fire? I have debug lines output to console so i know that the trigger for the object is being set to true but they dont discharge thier guns if they have them and ammo.
#20
i'm also hopeing that the work the GG guys are doing on the AI will make this scripting unessary (aggression states?).
04/27/2002 (9:22 pm)
i think bots dont truly have inventory so they have nothing to fire ( if that makes sense ) , but i could be wrong ... my bots dont fire either :-) ... also the function AIPlayer::getClosestHuman(%this) has pulled up the bots id# on more than one occasion ... of course i'm just making some guess basied on some things i've been able to work out ... what i do know is that trigger 0 is the fire trigger ( in the enm scetion of aiplayer.cc ) ... i do whonder what trigger 1 is condidering it's missing.i'm also hopeing that the work the GG guys are doing on the AI will make this scripting unessary (aggression states?).
Torque 3D Owner Bradley Crawford
For example the first application I cansee for this would be for the ingame cut-scene idea I am working on.
The second implication would be to implement roaming guards following set paths that will attack the player if they see them. Add in some code that gives them a chance to "hear" the player and turn to face them if the player moves too quickly, gets too close, etc and you have a pretty good early implementation of RtCW guards.
If you can name waypoints then you might make a "retreat" waypoint for each guard where if they get to 50% health and player > 60% health then the bot runs back to the retreat waypoint, which would be beind a wall or something that provides cover, and you then have a semblance of intelligent behaviour.
If you then add the previous listening code to all the bots, the one that hits retreat waypoint might start yelling for help, which would then bring his friends running to join him at his waypoint and then the entire group could go back to chasing the player.
A lot of possibilities exist for this code and since it was what I was going to start on this week, thank you for saving me time and for sharing Stefan. If I get the features I want working, I'll post them as a follow-up
Brad "Knytestorme" Crawford