Immersive AI Engine by Gavin Bunney discussion
by Fyodor -bank- Osokin · in Torque Game Engine · 02/27/2007 (4:46 am) · 191 replies
Let's discuss the iAI engine here, not spamming the .blog is good :)
The first question - is it based on standard AIPlayer.cc from SDK?
May be it's written in documents, but I haven't read all of them yet..
The first question - is it based on standard AIPlayer.cc from SDK?
May be it's written in documents, but I haven't read all of them yet..
About the author
Game developer.
Recent Threads
#62
Thank you I actually noticed my mistake, but forgot to update it in the post. Sorry. Anyways I actually modified the get random point stuff a bit more. I also added a separate function for spawning that checks to make sure there's space before spawning.
06/27/2007 (2:25 am)
@aaronThank you I actually noticed my mistake, but forgot to update it in the post. Sorry. Anyways I actually modified the get random point stuff a bit more. I also added a separate function for spawning that checks to make sure there's space before spawning.
function getRandomPoint(%pos,%rad,%height)
//adding %this to parameters messed up %pos WTH
{
%x = getWord(%pos, 0) + mFloor(getRandom(%rad * 2) - %rad);
%y = getWord(%pos, 1) + mFloor(getRandom(%rad * 2) - %rad);
%z = getWord(%pos, 2) + mFloor(getRandom(%rad * 2) - %rad);
%start = %x @ " " @ %y @ " 5000";
%end = %x @ " " @ %y @ " -1000";
%ground = containerRayCast(%start, %end, $TypeMasks::TerrainObjectType, 0);
%z = getWord(%ground, 3) + %height;
%position = %x @ " " @ %y @ " " @ %z;
}
function getSpawnLocation(%pos,%rad,%height)
{
while(%retries < 20)
{
%x = getWord(%pos, 0) + mFloor(getRandom(%rad * 2) - %rad);
%y = getWord(%pos, 1) + mFloor(getRandom(%rad * 2) - %rad);
%z = getWord(%pos, 2) + mFloor(getRandom(%rad * 2) - %rad);
%start = %x @ " " @ %y @ " 5000";
%end = %x @ " " @ %y @ " -1000";
%ground = containerRayCast(%start, %end, $TypeMasks::TerrainObjectType, 0);
%z = getWord(%ground, 3) + %height;
//echo ("Spawn Position : " @ %x SPC %y);
//echo ("Ground Level : " @ %z);
%position = %x @ " " @ %y @ " " @ %z;
%mask = ($TypeMasks::VehicleObjectType |
$TypeMasks::MoveableObjectType |
$TypeMasks::StaticShapeObjectType |
$TypeMasks::ForceFieldObjectType |
$TypeMasks::InteriorObjectType |
$TypeMasks::ItemObjectType);
if (ContainerBoxEmpty(%mask,%position,2.0))
{
//echo ("Spawn Position Is Good");
return %position;
}
else
%retries++;
}
error("Gave up finding space to spawn.");
return %pos; //give up!!
}
#63
06/28/2007 (11:42 pm)
Finally, I got it working. It now does what it is supposed to do. Although, it still needs a little tinkering. On the test run it spawned 2 entertainers but all they did was run around, at least it worked that far. Now all I need is about 2 weeks to go through all the code and see how it works. Then, another 2 weeks to intergrate it into my project and I should be good to go.
#64
Its referring to iAIPath::initPersistFields, specifically this:
Everything else compiles fine. Any ideas?
06/30/2007 (2:48 am)
I'm also having a little problem when I try to compile. For some reason, I'm getting this error:..\engine\immersiveAI\seek\path\iAIPath.cc(333) : error C2065: 'TypeBool' : undeclared identifier ..\engine\immersiveAI\seek\path\iAIPath.cc(335) : error C2065: 'TypeColorI' : undeclared identifier
Its referring to iAIPath::initPersistFields, specifically this:
addGroup("Misc");
addField("showPath", TypeBool, Offset(mShow, iAIPath), "Display the path on rendering.");
addField("renderSpline", TypeBool, Offset(mRenderSpline, iAIPath), "Render the path as a spline. If set to false, will render as linear.");
addField("pathColour", TypeColorI, Offset(mPathColour, iAIPath), "The colour of the rendered path.");
addField("pathNodeColour", TypeColorI, Offset(mPathNodeColour, iAIPath), "The colour of the nodes on the rendered path.");
endGroup("Misc");Everything else compiles fine. Any ideas?
#65
That sounds like a problem with your includes.
at the top of my .cc file I have the following
#include "console/consoleTypes.h"
06/30/2007 (7:19 pm)
@RyanThat sounds like a problem with your includes.
at the top of my .cc file I have the following
#include "sceneGraph/sceneGraph.h" #include "game/cameraSpline.h" #include "dgl/dgl.h" #include "iAIPath.h" #include "iAIPathMap.h" #include "iAIPathFind.h" #include "iAIPathGlobal.h"if you have all of those I would try adding
#include "console/consoleTypes.h"
#66
06/30/2007 (9:19 pm)
It worked after I added #include "console/consoleTypes.h". Thanks!
#67
07/08/2007 (1:15 pm)
I am having an issue setting spawn points from the World Editor. When try to insert an iAIAgent_Soldier, for example, I am getting an error "PlayerData:: create not found". Am I missing something?
#68
07/11/2007 (1:44 am)
Check if it is looking for playerbody and replace it with demoplayer.
#69
Another question. I currently have 30 different NPC's looking to port into this. Some of the NPCs have the same job, there are 3 shopkeepers, for example. Would I expand the predefined types and add a shopkeeper type to for all three shopkeepers, or would each NPC become their own type?
Hopefully I explained this well enough.
07/11/2007 (1:22 pm)
It was a self-inflicted issue. Thanks for the suggestion.Another question. I currently have 30 different NPC's looking to port into this. Some of the NPCs have the same job, there are 3 shopkeepers, for example. Would I expand the predefined types and add a shopkeeper type to for all three shopkeepers, or would each NPC become their own type?
Hopefully I explained this well enough.
#70
07/11/2007 (9:30 pm)
The pathfinding engine is causing occasional lockups for me it seems. Try running in debug mode and you'll see what I mean. Make sure you use my fix to "void findRouter" above though or it will throw a fatal exception almost immediately when you run in debug mode. Anyways I'm going to start hunting down these errors, but it would be great if someone else would help, or at least be able to confirm the pathfinding is causing some lockups for them too.
#71
#define IAIPATHGLOBAL_GRID_BUFFER_INTERIOR Point3F(10.0, 10.0, 0)
isnt actually referenced anywhere in the code. Im using TGEA, and the ai keep getting stuck on our
keep corners as they path around it. The paths draw fine around it, but their hitboxes wont let the actual Ai through.
I might see if i can solve this this week.
07/15/2007 (3:52 am)
Hi guys, i noticed that the #define IAIPATHGLOBAL_GRID_BUFFER_INTERIOR Point3F(10.0, 10.0, 0)
isnt actually referenced anywhere in the code. Im using TGEA, and the ai keep getting stuck on our
keep corners as they path around it. The paths draw fine around it, but their hitboxes wont let the actual Ai through.
I might see if i can solve this this week.
#72
About your question as to your shopkeepers. I have created new Agent types for my current NPC's. I only have one complete so far. What you would do is create a new agent type, just copy the supplied code and make the changes for your NPC's. If you have 3 shopkeepers, create a shopkeeper agent type. All 3 agents can use the same script because of there unique ID. All of the agent managing is done in script so it is fairly easy to manage. I have created a new goal listing just for my merchant agents. They mind the store untill a customer tries t talk to them. If their boredom gets to high they wander around a little, similar to the explore goal. I found it quite easy, although there is a lot of trial and error you may have to endure.
07/17/2007 (12:03 am)
@ Dave DAbout your question as to your shopkeepers. I have created new Agent types for my current NPC's. I only have one complete so far. What you would do is create a new agent type, just copy the supplied code and make the changes for your NPC's. If you have 3 shopkeepers, create a shopkeeper agent type. All 3 agents can use the same script because of there unique ID. All of the agent managing is done in script so it is fairly easy to manage. I have created a new goal listing just for my merchant agents. They mind the store untill a customer tries t talk to them. If their boredom gets to high they wander around a little, similar to the explore goal. I found it quite easy, although there is a lot of trial and error you may have to endure.
#73
09/10/2007 (12:06 pm)
Anyone made any further progress with this that they want to share?
#74
to Gavin,
Wow, thank you for sharing this knowledge ! Its going a long way to helping me with my bachelors in Computer Science mastering in AI. For me its always easier to work practically and think theoretically.
Secondly
to bank, Stephen, Aaron
Thank you very much for working through the natural integrations, woulda taken a myself a tge novice more than a long time to do what you guys done for me in less than an hour.
____________________________________________
I have put this in tge_5_1_2_afx_1_0_2 and tgea_1_0_3.
Works great except for one severity I encountered so far. I was even brave enough to add a few afx_rpg thoughts to the bots, quite funny to watch them light the camp fire.
The severity is that which I think Stephen is encountering, it especially hits me when the "seek" fails(with quite a few bots on hand).
Stephen, I will try and help as best I can, I am working and studying for my degree part time, but am really keen on making this work, so it will be a priority !!
Till the next ...
09/16/2007 (9:02 am)
Firstly to Gavin,
Wow, thank you for sharing this knowledge ! Its going a long way to helping me with my bachelors in Computer Science mastering in AI. For me its always easier to work practically and think theoretically.
Secondly
to bank, Stephen, Aaron
Thank you very much for working through the natural integrations, woulda taken a myself a tge novice more than a long time to do what you guys done for me in less than an hour.
____________________________________________
I have put this in tge_5_1_2_afx_1_0_2 and tgea_1_0_3.
Works great except for one severity I encountered so far. I was even brave enough to add a few afx_rpg thoughts to the bots, quite funny to watch them light the camp fire.
The severity is that which I think Stephen is encountering, it especially hits me when the "seek" fails(with quite a few bots on hand).
Stephen, I will try and help as best I can, I am working and studying for my degree part time, but am really keen on making this work, so it will be a priority !!
Till the next ...
#75
I have abandoned working in tge now. Focusing only on tgea. I still have not upgraded the render from dgl to using GFX, except for console output. Just means I can't see the graph visually, but I don't have a need for that.
I have almost completed porting all the script code to the engine. I have exposed all ported code to the console for later experiments when using script again.
The reason for doing this is that my intention for this is purely research. I want to create a 500 member strong community and watch them interact. With the script code as is in tgea, I can only implement 20 standard immersive agents before lagging kicks in and not too much later i get an access violation which i cant explain. It almost seems random, it occurs usually in the network part of tgea or the audio part.
My machine spec is :
2Ghz cpu
2GB ram
I have only ported roughly 30%( all members are now bound to the agent class for now, no more dynamic script members ) of the code to the engine and am already seeing vast improvements. I can now add 65 agents, two agents are additional, up and above that of the standard immersive ones. There is slightly less lag with 65 agents vs even that of the scripted 20 agents and access violations occur far less too.
The lag only kicks in when the agents do their pathing, as soon as I have ported all the code to engine and achieved my goal of 500 agents, I will see if I can add my 2cents worth to the pathing. I already have a slope algorithym which i want to apply to the path creation which takes in to account the "runSurfaceAngle" so that no grid is created on unwalkable slopes.
btw, for those interested in interior navigation and are not too worried about bot count, I highly recommend a look at the F.E.A.R engine @ aigamedev.com. I ported the standard part of it to tge and it works really well, and is extremely well architected. I have put it on hold as I can only squeeze out 60 or so of its simple collision detection bots before lag creeps in.
I will keep up the posts, please help with suggestions, mods, upgrades, other findings ... it usually speeds up the process. (where to upload sources to ?)
Till the next ...
09/19/2007 (3:11 am)
Stephen, can you explain in a little more detail what you mean by lockups ...I have abandoned working in tge now. Focusing only on tgea. I still have not upgraded the render from dgl to using GFX, except for console output. Just means I can't see the graph visually, but I don't have a need for that.
I have almost completed porting all the script code to the engine. I have exposed all ported code to the console for later experiments when using script again.
The reason for doing this is that my intention for this is purely research. I want to create a 500 member strong community and watch them interact. With the script code as is in tgea, I can only implement 20 standard immersive agents before lagging kicks in and not too much later i get an access violation which i cant explain. It almost seems random, it occurs usually in the network part of tgea or the audio part.
My machine spec is :
2Ghz cpu
2GB ram
I have only ported roughly 30%( all members are now bound to the agent class for now, no more dynamic script members ) of the code to the engine and am already seeing vast improvements. I can now add 65 agents, two agents are additional, up and above that of the standard immersive ones. There is slightly less lag with 65 agents vs even that of the scripted 20 agents and access violations occur far less too.
The lag only kicks in when the agents do their pathing, as soon as I have ported all the code to engine and achieved my goal of 500 agents, I will see if I can add my 2cents worth to the pathing. I already have a slope algorithym which i want to apply to the path creation which takes in to account the "runSurfaceAngle" so that no grid is created on unwalkable slopes.
btw, for those interested in interior navigation and are not too worried about bot count, I highly recommend a look at the F.E.A.R engine @ aigamedev.com. I ported the standard part of it to tge and it works really well, and is extremely well architected. I have put it on hold as I can only squeeze out 60 or so of its simple collision detection bots before lag creeps in.
I will keep up the posts, please help with suggestions, mods, upgrades, other findings ... it usually speeds up the process. (where to upload sources to ?)
Till the next ...
#76
I also wonder about the removal of the pathgrid from slopes that are unwalkable, do you think that if you had any flying agents that this would be an issue? Or would you simply remove the pathfinding from flying agents and just use LOS to help them move?
09/19/2007 (4:51 pm)
Hmm that's interesting that putting all of the scripts into c++ will give that much of a boost. I think I'll have to try that because I too get crashes and lag after the agent count gets too high, having 500 agents would be fantastic, if you ever hit that goal please share how you did it with us.I also wonder about the removal of the pathgrid from slopes that are unwalkable, do you think that if you had any flying agents that this would be an issue? Or would you simply remove the pathfinding from flying agents and just use LOS to help them move?
#77
Then, after learning more about immersiveAI it became apparent that a hacked version of Gavin's c++ GM with less of his intended architecture was produced. Not been the main focal point it is left to cleanup, that is if it proves to be useful.
Not much left to port. Just the agent specific files (ie. bandit, soldier, exploreArea, ...). It was expected to see an incredible boost in performance once goal formulating and management was ported. This was not the case. The benchmark of 500 agents using this architecture now seems ambitious. How do the blizzard likes get so many bots going !! It can only be thought that they use few controllers, none individual. The target now is 100 agents. Then onto path optimization. One thing though, the porting has really minimized the crashes.
@Ben
Wow, flying and pathing, now thats opening a can of worms. Terrain pathing would be uselful, especially if most optimal and accurate provided there are no atmospheric obstacles, but then adding an infrequent LOS check up and above the terrain pathing would help overcome that anyways. To answer your question on the pathgrid. Ground objects require the detail of the grid, but not on all areas of the terrain, hence the exctractions of the irrelevant nodes, with air however, the detail level for the path grid need not be as high. So basically have a separate pathgrid for flying and ground, and use a LOD algorithym when creating airpathgrid and don't remove any parts of the grid, unless necessary.
After some clean up, the GoalManagerCore will be posted. The rest of the resources will take up space, where is the best place to upload ?
It would be nice to see items tweaked so that the functionality remains and number of agents increase. Any thoughts on a type of AI Interpolation maybe ?
Till the next ...
09/22/2007 (3:05 pm)
More code now in c++. The script GoalManager is ported and named GoalManagerCore. Reason for the separate name is through the porting and testing, the script GM shared processing with the ported GM, so they had to co-exist for a while.Then, after learning more about immersiveAI it became apparent that a hacked version of Gavin's c++ GM with less of his intended architecture was produced. Not been the main focal point it is left to cleanup, that is if it proves to be useful.
Not much left to port. Just the agent specific files (ie. bandit, soldier, exploreArea, ...). It was expected to see an incredible boost in performance once goal formulating and management was ported. This was not the case. The benchmark of 500 agents using this architecture now seems ambitious. How do the blizzard likes get so many bots going !! It can only be thought that they use few controllers, none individual. The target now is 100 agents. Then onto path optimization. One thing though, the porting has really minimized the crashes.
@Ben
Wow, flying and pathing, now thats opening a can of worms. Terrain pathing would be uselful, especially if most optimal and accurate provided there are no atmospheric obstacles, but then adding an infrequent LOS check up and above the terrain pathing would help overcome that anyways. To answer your question on the pathgrid. Ground objects require the detail of the grid, but not on all areas of the terrain, hence the exctractions of the irrelevant nodes, with air however, the detail level for the path grid need not be as high. So basically have a separate pathgrid for flying and ground, and use a LOD algorithym when creating airpathgrid and don't remove any parts of the grid, unless necessary.
After some clean up, the GoalManagerCore will be posted. The rest of the resources will take up space, where is the best place to upload ?
It would be nice to see items tweaked so that the functionality remains and number of agents increase. Any thoughts on a type of AI Interpolation maybe ?
Till the next ...
#78
A thought about the 500 agents, maybe it's because they are so bloated from shapebase all the way down. Perhaps instead of Gamebase->Shapebase->Player->AiPlayer->iAiAgent something that was more Gamebase->iAiAgent would be a more lightweight solution that might help. (not that it wouldnt be a huge task to program). Or like you said, have fewer controllers or brains, maybe one master control brain that powers all of the agents and the agents are like limbs of the main brain which makes it's decision for what each one would do, like fingers on a hand or something.
09/24/2007 (10:28 am)
@Greg: I've emailed you with details of where you can upload.A thought about the 500 agents, maybe it's because they are so bloated from shapebase all the way down. Perhaps instead of Gamebase->Shapebase->Player->AiPlayer->iAiAgent something that was more Gamebase->iAiAgent would be a more lightweight solution that might help. (not that it wouldnt be a huge task to program). Or like you said, have fewer controllers or brains, maybe one master control brain that powers all of the agents and the agents are like limbs of the main brain which makes it's decision for what each one would do, like fingers on a hand or something.
#79
Here is an early adopter for the c++ GoalManager ie. GoalManagerCore. To help with corrections and omitions. The code is from a strong java base still learning c++ in's and out's. The comments from .cs files remain from the original author.
GoalManagerCore.h
and GoalManagerCore.cpp part 1 max post 8192
09/24/2007 (1:53 pm)
@Ben: Thanks a stack for the upload location. Once all sources are ported I will post them there and add link here. Thanks too for the suggestions' on optimizations. As mentioned before, the objective is to get the AI count up as high as possible leaving room for playability and natural experience. The single brain, seems most likely. One scheduled think for a list of agents vs 100's of scheduled thinks should ease the load on the engine. Paying more attention to agents with higher priority. To your analogy, the index finger and thumb get more thought.Here is an early adopter for the c++ GoalManager ie. GoalManagerCore. To help with corrections and omitions. The code is from a strong java base still learning c++ in's and out's. The comments from .cs files remain from the original author.
GoalManagerCore.h
#ifndef _IAIGOALMANAGERCORE_H_
#define _IAIGOALMANAGERCORE_H_
#include "immersiveAI/agent/iAIAgent.h"
#include "platform/platformThread.h"
#include "console/simBase.h"
#include "immersiveAI/iAIGoalLibrary.h"
//-------------------------------------------------------------------
/// @def IAIGOALMANAGER_EVALUATION_FORMAT
/// @brief Format of the evaluation functions. %s is the goal or
/// solution name.
//-------------------------------------------------------------------
#define IAIGOALMANAGERCORE_EVALUATION_FORMAT "%s_evaluate"
//-------------------------------------------------------------------
/// @def IAIGOALMANAGER_SOLUTION_FUNCTION_FORMAT
/// @brief Format of the solution function to execute. %s is the
/// solution name.
//-------------------------------------------------------------------
#define IAIGOALMANAGERCORE_SOLUTION_FUNCTION_FORMAT "%s_onEnter"
class iAIGoalManagerCore : public SimObject {
typedef SimObject Parent;
public:
DECLARE_CONOBJECT(iAIGoalManagerCore);
iAIGoalManagerCore();
~iAIGoalManagerCore();
//-------------------------------------------------------------------
/// @fn bool onAdd()
/// @brief Called on adding to Sim.
///
/// @return Add success.
//-------------------------------------------------------------------
bool onAdd();
//-------------------------------------------------------------------
/// @fn bool onRemove()
/// @brief Called on removal from Sim.
//-------------------------------------------------------------------
void onRemove();
void iAIGoalManagerCore::initialize();
const bool iAIGoalManagerCore::assignGoal(iAIAgent* agent, const char * goal, const char * solution);
const char * iAIGoalManagerCore::evaluateGoalList(iAIAgent* agent, Vector<iAIGoal*> wordList, const char * avoidWord);
const char * iAIGoalManagerCore::evaluateSolutionList(iAIAgent* agent, Vector<iAIGoalSolution*> wordList, const char * avoidWord);
const bool iAIGoalManagerCore::requestNewGoal(iAIAgent* agent, const bool avoidCurrentGoal = false, const bool avoidCurrentSolution = false);
const bool iAIGoalManagerCore::requestNewSolution(iAIAgent* agent, const char * avoidCurrentSolution);
const bool iAIGoalManagerCore::resumePreviousSolution(iAIAgent* agent);
const bool iAIGoalManagerCore::completedSolution(iAIAgent* agent);
protected:
iAIGoalLibrary* goalLibrary;
};
#endifand GoalManagerCore.cpp part 1 max post 8192
#include "iAIGoalManagerCore.h"
#include "util/safeDelete.h"
#include "console/consoleTypes.h"
#include "immersiveAI/seek/path/iAIPath.h"
IMPLEMENT_CONOBJECT(iAIGoalManagerCore);
iAIGoalManagerCore::iAIGoalManagerCore(){
}
iAIGoalManagerCore::~iAIGoalManagerCore(){
//nothing
}
static const char* itoa(S32 i)
{
static char buf[32];
dSprintf(buf, sizeof(buf), "%d", i);
return buf;
}
bool iAIGoalManagerCore::onAdd()
{
if (!Parent::onAdd())
return false;
// get the goal library
this->goalLibrary = dynamic_cast<iAIGoalLibrary*>(Sim::findObject(Con::getVariable("$iAIGoalLibrary")));
// throw error if goal library not found
if (!this->goalLibrary)
{
Con::errorf("Immersive AI :: GoalManager Core :: Unable to locate the goal library!");
return false;
}
return true;
}
void iAIGoalManagerCore::onRemove()
{
Parent::onRemove();
}
void iAIGoalManagerCore::initialize(){
}
const bool iAIGoalManagerCore::assignGoal(iAIAgent* agent, const char * goal, const char * solution)
{
// check valid parameters
if (((!agent) || (agent->getStateName() == "Dead")) ||
((dStrlen(goal) == 0) || (dStrlen(solution) == 0)))
return false;
//%agent.setActionThread("look");//should reset their animations
// check for a goal interrupt
if (agent->isGoalInterrupt() == true)
{
agent->setGoalInterrupt( false );
agent->setResumePrevious( true );
} else
{
if (agent->isResumePrevious() == true)
{
agent->setResumePrevious( false );
// resume previous only if previous is a differnt goal/solution!
if (!((agent->getPreviousGoal() != agent->getCurrentGoal()) &&
(agent->getPreviousSolution() != agent->getCurrentSolution())))
{
return this->resumePreviousSolution(agent);
}
}
}
// check if agent has a current goal
if (dStrlen(agent->getCurrentGoal()) != 0)
{
// set the previous goal/solution to the current ones
agent->setPreviousGoal( agent->getCurrentGoal() );
agent->setPreviousSolution( agent->getCurrentSolution() );
}
// set the new goal & solution
agent->setCurrentGoal( goal );
agent->setCurrentSolution( solution );
char command[100] = {};
// build the solution function and execute
dSprintf(command, sizeof(command), IAIGOALMANAGERCORE_SOLUTION_FUNCTION_FORMAT, solution);
//char * current = eval(%solution @ "_onEnter(\"" @ %agent @ "\");");
// execute the solution
Con::executef(2, command, itoa( agent->getId() ));
//Con::evaluate( command, false, NULL);
return true;
}
const bool iAIGoalManagerCore::resumePreviousSolution(iAIAgent * agent)
{
// check valid parameters
if ((!agent) || (agent->getStateName() == "Dead"))
return false;
// check if agent has previous
if ((dStrlen(agent->getPreviousGoal()) != 0) && (dStrlen(agent->getPreviousSolution()) != 0))
{
// assign the previous goal/solution
return (this->assignGoal(agent, agent->getPreviousGoal(), agent->getPreviousSolution()));
} else
{
// didn't have a previous goal/solution
return false;
}
}
const bool iAIGoalManagerCore::completedSolution(iAIAgent* agent)
{
// check valid parameters
if ((!(agent)) || (agent->getStateName() == "Dead"))
return false;
// some cleanup..
agent->setActionThread("look", false, true, true);
if (agent->getCurrentPath())
agent->setCurrentPath( NULL );
// check if over think tick limit
if (agent->getLastTick_ticks() > agent->getThinkTickLimit())
{
// request a different goal and solution
this->requestNewGoal(agent, true, true);
} else
{
// request a new goal and solution
this->requestNewGoal(agent);
}
return true;
}
#80
09/24/2007 (1:56 pm)
.... GoalManagerCore.cpp part 2 max post 8192const bool iAIGoalManagerCore::requestNewGoal(iAIAgent * agent, const bool avoidCurrentGoal, const bool avoidCurrentSolution )
{
// check valid parameters
if ((!(agent)) || (agent->getStateName() == "Dead")){
Con::iAIMessagef(itoa(agent->getId())," was not alive or valid while choosing a new goal.");
return false;
}
// check if wanting to avoid the current goal
const char * avoidWord = "";
if (avoidCurrentGoal == true)
avoidWord = agent->getCurrentGoal();
// evaluate the agents goals
Vector<iAIGoal*> goalList;
agent->getGoalList( goalList );
char * goal;
goal = const_cast<char*>(this->evaluateGoalList(agent, goalList, avoidWord));
// check goal found
if (dStrlen(goal) == 0){
Con::iAIMessagef("iAIGoalManagerCore::requestNewGoal - no new goal was found.");
return false;
}
// get a list of solutions for the goal
Vector<iAIGoalSolution*> solutionList = this->goalLibrary->getSolutionList(const_cast<char*>(agent->getAgentType()), goal);
// check solution list found
if (solutionList.size() == 0){
Con::iAIMessagef(itoa(agent->getId())," solution LIST for ai type ",agent->getAgentType()," not found while choosing the new goal: ", goal);
return false;
}
// check if wanting to avoid the current solution
avoidWord = "";
if (avoidCurrentSolution == true)
avoidWord = agent->getCurrentSolution();
// evaluate the solutions
const char * solution = "";
solution = this->evaluateSolutionList(agent, solutionList, avoidWord);
// check solution found
if (dStrlen(solution) == 0){
Con::iAIMessagef(itoa(agent->getId())," solution not found in solution list: ", solutionList);
return false;
}
// assign and execute the goal and solution to the agent
bool success = this->assignGoal(agent, goal, solution);
if(success)
Con::iAIMessagef("Successfully chose the new goal ",goal," via solution ",solution,"to the agent ",itoa(agent->getId()));
else
Con::iAIMessagef("Failed to assign the new goal ",goal," or the solution ",solution,"to the agent ",itoa(agent->getId()));
return (success);
}
const char * iAIGoalManagerCore::evaluateGoalList(iAIAgent* agent, Vector<iAIGoal*> wordList, const char * avoidWord)
{
// get number of words in the wordList
S32 wordCount = wordList.size();
// hold the max value & max string found
S32 maxValue = -1;
char * maxName = "";
iAIGoal* currentWord;
const char * current = "";
S32 currentVal;
// iterate over all goals
for (S32 i = 0; i < wordCount; i++)
{
// get the current goal name from the goalList
currentWord = wordList[i];
// check if to avoid the current word
if ( currentWord->mName == avoidWord )
continue;
// execute the goal evaluate method
char command[100] = {};
// build the solution function and execute
dSprintf(command, sizeof(command), IAIGOALMANAGERCORE_EVALUATION_FORMAT, currentWord->mName);
current = Con::executef( 2, command, itoa( agent->getId() ) );
currentVal = dAtoi( current );
//current = eval(%currentWord @ "_evaluate(\"" @ %agent @ "\");");
// check for less than 0, as not allowed into this goal
if (currentVal < 0)
continue;
// check if best goal found
if (currentVal > maxValue)
{
// set best goal values
maxValue = currentVal;
maxName = currentWord->mName;
}
}
if ( maxName )
Con::iAIMessagef( maxName );
return maxName ? maxName : "";
}
const char * iAIGoalManagerCore::evaluateSolutionList(iAIAgent* agent, Vector<iAIGoalSolution*> wordList, const char * avoidWord)
{
// get number of words in the wordList
S32 wordCount = wordList.size();
// hold the max value & max string found
S32 maxValue = -1;
char * maxName = "";
iAIGoalSolution* currentWord;
const char * current = "";
S32 currentVal;
// iterate over all goals
for (S32 i = 0; i < wordCount; i++)
{
// get the current goal name from the goalList
currentWord = wordList[i];
// check if to avoid the current word
if ( currentWord->mName == avoidWord )
continue;
// execute the goal evaluate method
char command[100] = {};
// build the solution function and execute
dSprintf(command, sizeof(command), IAIGOALMANAGERCORE_EVALUATION_FORMAT, currentWord->mName);
current = Con::executef( 2, command, itoa( agent->getId() ) );
currentVal = dAtoi( current );
//current = eval(%currentWord @ "_evaluate(\"" @ %agent @ "\");");
// check for less than 0, as not allowed into this goal
if (currentVal < 0)
continue;
// check if best goal found
if (currentVal > maxValue)
{
// set best goal values
maxValue = currentVal;
maxName = currentWord->mName;
}
}
if ( maxName )
Con::iAIMessagef( maxName );
return maxName ? maxName : "";
}
ConsoleMethodGroupBegin(iAIGoalManagerCore, ScriptFunctions, "iAIGoalManager Script Functions");
ConsoleMethod( iAIGoalManagerCore, assignGoal, bool, 5, 5,
"void iAIGoalManagerCore.assignGoal( agent )")
{
argc;
if (dStrlen(argv[2]) != 0)
{
// get the parsed agent & ensure valid
iAIAgent *agent = dynamic_cast<iAIAgent*>(Sim::findObject(argv[2]));
if (agent)
{
// request a solution for the agent
object->assignGoal(agent, argv[3], argv[4]);
return true;
} else
{
Con::errorf("Immersive AI :: GoalManager :: Unable to locate parsed agent!");
return false;
}
} else
{
Con::errorf("Immersive AI :: GoalManager :: No Agent parsed to add!");
return false;
}
}
ConsoleMethod( iAIGoalManagerCore, resumePreviousSolution, bool, 3, 3,
"void iAIGoalManager.resumePreviousSolution( agent )")
{
if (dStrlen(argv[2]) != 0)
{
// get the parsed agent & ensure valid
iAIAgent *agent = dynamic_cast<iAIAgent*>(Sim::findObject(argv[2]));
if (agent)
{
// request a solution for the agent
object->resumePreviousSolution(agent);
return true;
} else
{
Con::errorf("Immersive AI :: GoalManager :: Unable to locate parsed agent!");
return false;
}
} else
{
Con::errorf("Immersive AI :: GoalManager :: No Agent parsed to add!");
return false;
}
}
ConsoleMethod( iAIGoalManagerCore, completedSolution, bool, 3, 3,
"void iAIGoalManager.completedSolution( agent )")
{
if (dStrlen(argv[2]) != 0)
{
// get the parsed agent & ensure valid
iAIAgent *agent = dynamic_cast<iAIAgent*>(Sim::findObject(argv[2]));
if (agent)
{
// request a solution for the agent
object->completedSolution(agent);
return true;
} else
{
Con::errorf("Immersive AI :: GoalManager :: Unable to locate parsed agent!");
return false;
}
} else
{
Con::errorf("Immersive AI :: GoalManager :: No Agent parsed to add!");
return false;
}
}
ConsoleMethod( iAIGoalManagerCore, initialize, void, 2, 2,
"void iAIGoalManagerCore.initialize( ) .")
{
object->initialize();
}
Ryan Edmar
Default Studio Name
Also, currently I am using 1.4.2 because I can't afford to upgrade right now. So far I've just implemented it into a stock build of the starter.fps for testing purposes. I've made alot of customizations to the engine and script file in the current project I'm working on and didn't want to do my testing there.
As for the 5 seconds I mentioned. I wasn't saying it paused for 5 seconds, that's about how long the game ran before the error forced it to close. I ran it without calling iAIAgentManager.initilize() and it ran fine, but as soon as I try to spawn a bot it crashes. Unfortunately do to my problems with my laptop I can't do any testing when I normally do it. So when I get some more time I make some more changes and see what comes of it. Thanks for your help.