#include "gAIBase.h"
#include "gArena.h"
#include "eGrid.h"
#include "ePath.h"
#include "eGameObject.h"
#include "gWall.h"
#include "gSensor.h"
#include "gCycle.h"
#include "tConsole.h"
#include "rFont.h"
#include "rScreen.h"
#include "eFloor.h"
#include "eDebugLine.h"
#include "gAICharacter.h"
#include "tReferenceHolder.h"
#include "tRandom.h"
#include "tRecorder.h"
#include <stdlib.h>
#include <cstdlib>
#include <memory>
Go to the source code of this file.
Classes | |
class | gRandomController |
class | gCycleTouchEvent |
class | gCycleMemoryEntry |
class | gLoopData |
class | gHitData |
class | gAISensor |
class | gAILogEntry |
class | gAILog |
Defines | |
#define | AI_REACTION 0 |
#define | AI_EMERGENCY 1 |
#define | AI_RANGE 2 |
#define | AI_STATE_TRACE 3 |
#define | AI_STATE_CLOSECOMBAT 4 |
#define | AI_STATE_PATH 5 |
#define | AI_LOOP 6 |
#define | AI_ENEMY 7 |
#define | AI_TUNNEL 8 |
#define | AI_DETECTTRACE 9 |
#define | AI_STARTSTATE 10 |
#define | AI_STARTSTRAIGHT 11 |
#define | AI_STATECHANGE 12 |
#define | TOL 4 |
#define | MAXAI_COLOR 13 |
#define | REACTION .2 |
#define | DANGERLEVELS 4 |
#define | LOOPLEVEL 0 |
#define | SPACELEVEL 1 |
#define | TRAPLEVEL 2 |
#define | COLIDELEVEL 2 |
#define | TEAMLEVEL 3 |
#define | ENTRIES 10 |
Functions | |
static | tCONTROLLED_PTR (gAITeam) sg_AITeam |
static gAITeam * | AITeam () |
static void | ClearAITeam () |
REAL | Random () |
static REAL | Delay () |
static gAICharacter * | BestIQ (int iq) |
static bool | CheckLoop (const gCycle *a, const gCycle *b, REAL bDist, int bSide, int dir, tArray< const gCycle * > &closedIn, int &winding, REAL aEndDist=0, int aEndSides=3, int aEndDir=1) |
static bool | IsTrapped (const gCycle *trapped, const gCycle *other) |
static void | CycleBlocksWayHelper (const gCycle *a, const gCycle *b, int aDir, int bDir, REAL aDist, REAL bDist, int winding) |
static gAISensor * | sg_GetSensor (int currentDirectionNumber, gCycle const &object, int turn, REAL side, REAL range, REAL corridor, REAL &mindist) |
std::ostream & | operator<< (std::ostream &s, gAIPlayer::ThinkDataBase const &data) |
std::istream & | operator>> (std::istream &s, gAIPlayer::ThinkDataBase &data) |
Variables | |
static tReferenceHolder < gAIPlayer > | sg_AIReferences |
static nNOInitialisator< gAITeam > | gAITeam_init (331,"gAITeam") |
static int | current_ai |
static REAL | rgb_ai [MAXAI_COLOR][3] |
static nNOInitialisator < gAIPlayer > | gAIPlayer_init (330,"gAIPlayer") |
static char const * | section = "AI" |
const REAL | relax = 25 |
#define AI_DETECTTRACE 9 |
#define AI_EMERGENCY 1 |
Definition at line 50 of file gAIBase.cpp.
Referenced by gAIPlayer::EmergencySurvive(), and gAIPlayer::RightBeforeDeath().
#define AI_ENEMY 7 |
#define AI_LOOP 6 |
Definition at line 55 of file gAIBase.cpp.
Referenced by gAIPlayer::EmergencySurvive(), and gAISensor::gAISensor().
#define AI_RANGE 2 |
#define AI_REACTION 0 |
#define AI_STARTSTATE 10 |
#define AI_STARTSTRAIGHT 11 |
#define AI_STATE_CLOSECOMBAT 4 |
#define AI_STATE_PATH 5 |
#define AI_STATE_TRACE 3 |
#define AI_STATECHANGE 12 |
#define AI_TUNNEL 8 |
#define COLIDELEVEL 2 |
#define DANGERLEVELS 4 |
Definition at line 1946 of file gAIBase.cpp.
Referenced by gAIPlayer::EmergencySurvive(), and gAILog::Print().
#define ENTRIES 10 |
#define LOOPLEVEL 0 |
#define MAXAI_COLOR 13 |
#define REACTION .2 |
Referenced by gAIPlayer::ThinkCloseCombat().
#define SPACELEVEL 1 |
#define TEAMLEVEL 3 |
#define TOL 4 |
Definition at line 371 of file gAIBase.cpp.
Referenced by CheckLoop(), and gAIPlayer::EmergencySurvive().
#define TRAPLEVEL 2 |
static gAITeam* AITeam | ( | ) | [static] |
Definition at line 98 of file gAIBase.cpp.
References tNEW.
Referenced by gAIPlayer::ClearAll(), and gAIPlayer::SetNumberOfAIs().
00099 { 00100 if ( !sg_AITeam ) 00101 { 00102 sg_AITeam = tNEW( gAITeam ); 00103 } 00104 00105 return sg_AITeam; 00106 }
static gAICharacter* BestIQ | ( | int | iq | ) | [static] |
Definition at line 162 of file gAIBase.cpp.
References ai, gAIPlayer::Character(), gAICharacter::iq, GrowingArrayBase::Len(), tListItemBase::Len(), gAICharacter::s_Characters, and se_PlayerNetIDs.
Referenced by gAITeam::BalanceWithAIs(), and gAIPlayer::SetNumberOfAIs().
00163 { 00164 int i; 00165 00166 static tArray<bool> inGame(gAICharacter::s_Characters.Len()); 00167 for (i = gAICharacter::s_Characters.Len()-1; i>=0; i--) 00168 inGame(i) = false; 00169 00170 for (i = se_PlayerNetIDs.Len()-1; i>=0; i--) 00171 { 00172 // count the active AIs 00173 ePlayerNetID *p = se_PlayerNetIDs(i); 00174 gAIPlayer *ai = dynamic_cast<gAIPlayer*>(p); 00175 if (ai && ai->Character() ) 00176 { 00177 int index = ai->Character() - &(gAICharacter::s_Characters(0)); 00178 inGame(index) = true; 00179 } 00180 } 00181 00182 // find the best fitting IQ that could be inserted: 00183 gAICharacter* bestIQ = 0; 00184 for (i = gAICharacter::s_Characters.Len()-1; i>=0; i--) 00185 if (!inGame(i)) 00186 if (!bestIQ || fabs(bestIQ->iq - iq) > fabs(gAICharacter::s_Characters(i).iq - iq)) 00187 bestIQ = &gAICharacter::s_Characters(i); 00188 00189 return bestIQ; 00190 }
static bool CheckLoop | ( | const gCycle * | a, | |
const gCycle * | b, | |||
REAL | bDist, | |||
int | bSide, | |||
int | dir, | |||
tArray< const gCycle * > & | closedIn, | |||
int & | winding, | |||
REAL | aEndDist = 0 , |
|||
int | aEndSides = 3 , |
|||
int | aEndDir = 1 | |||
) | [static] |
Definition at line 384 of file gAIBase.cpp.
References gCycleMemoryEntry::cycle, gCycleTouchEvent::dist, gCycleMemory::Earliest(), gCycleMovement::GetDistance(), eGameObject::Grid(), gCycleMemory::Latest(), GrowingArrayBase::Len(), gCycleMemoryEntry::max, gCycle::memory, gCycleMemoryEntry::min, gCycleTouchEvent::otherDist, gCycleTouchEvent::otherSide, REAL, tASSERT, TOL, gCycleTouchEvent::winding, and eGrid::WindingNumber().
Referenced by gAISensor::DetectLoop(), gAIPlayer::EmergencySurvive(), and IsTrapped().
00388 { 00389 tASSERT(0<= bSide && 1 >= bSide); 00390 tASSERT(0<= dir && 1 >= dir); 00391 00392 int tries = 10; // so long until we give up 00393 int ends = 0; 00394 00395 bool bClosedIn = false; 00396 00397 const gCycle *run = b; // we run along this cycle's wall 00398 int end = dir; // and move towards this end its wall wall 00399 int side = bSide; // we are on this side of the cycle 00400 REAL dist = bDist; // and are at this distance. 00401 winding = 0; // the winding number we collected 00402 00403 int turn = a->Grid()->WindingNumber(); 00404 int halfTurn = turn >> 1; 00405 00406 00407 #ifdef DEBUG 00408 // con << "\n"; 00409 #endif 00410 00411 while(tries-- > 0 && run && 00412 !(run == a && 00413 end == aEndDir && 00414 aEndSides & (1 << side) && 00415 (end > 0 ? dist >= aEndDist : dist <= aEndDist ) ) ) 00416 { 00417 #ifdef DEBUG 00418 // con << "end = " << end << ", side = " << side << ", dist = " << dist 00419 // << ", winding = " << winding << "\n"; 00420 #endif 00421 if (end > 0) 00422 { 00423 00424 // find the last connection 00425 gCycleMemoryEntry* last = run->memory.Latest(side); 00426 if (!last || last->max[side].dist <= dist + TOL) 00427 { 00428 // no interference. We can move directly around the cylce 00429 // and close it in. 00430 #ifdef DEBUG 00431 // con << "Turning around...\n"; 00432 #endif 00433 00434 winding += halfTurn * 00435 ( side > 0 ? -1 : 1); 00436 00437 end = 0; 00438 side = 1-side; 00439 closedIn[closedIn.Len()] = run; 00440 dist = run->GetDistance(); 00441 00442 // detect early loop 00443 if (run == b) 00444 if (bClosedIn) 00445 { 00446 winding = 0; 00447 return false; 00448 } 00449 else 00450 bClosedIn = true; 00451 } 00452 else 00453 { 00454 #ifdef DEBUG 00455 // con << "Crossing...\n"; 00456 #endif 00457 00458 // find the first connection 00459 gCycleMemoryEntry* first = run->memory.Earliest(side); 00460 if (first && first->min[side].dist >= dist + TOL) 00461 { 00462 // we cross the connection: 00463 winding += first->min[side].winding; 00464 run = first->cycle; 00465 end = (side == first->min[side].otherSide) ? 1 : 0; 00466 00467 // if (end == 0) 00468 // we need to turn around to follow 00469 winding += halfTurn * (side > 0 ? 1 : -1); 00470 00471 dist = first->min[side].otherDist; 00472 side = first->min[side].otherSide; 00473 } 00474 else 00475 { 00476 winding = 0; 00477 return false; 00478 } 00479 } 00480 } 00481 else // dir = -1, we move towards the end 00482 { 00483 // find the first connection 00484 gCycleMemoryEntry* first = run->memory.Earliest(side); 00485 if (!first || first->min[side].dist >= dist - TOL) 00486 { 00487 #ifdef DEBUG 00488 // con << "Turning around...\n"; 00489 #endif 00490 00491 00492 // no interference. We can move directly around the cylce's end. 00493 winding += halfTurn * ( side > 0 ? 1 : -1); 00494 00495 end = 1; 00496 side = 1-side; 00497 ends++; 00498 dist = -2 * TOL; 00499 } 00500 else 00501 { 00502 #ifdef DEBUG 00503 // con << "Crossing...\n"; 00504 #endif 00505 00506 00507 // find the latest connection 00508 gCycleMemoryEntry* last = run->memory.Latest(side); 00509 if (last && last->max[side].dist <= dist - TOL) 00510 { 00511 // we cross the connection: 00512 winding += last->max[side].winding; 00513 00514 // we need to turn around to start: 00515 winding += halfTurn * (side > 0 ? -1 : 1); 00516 00517 run = last->cycle; 00518 end = (side == last->max[side].otherSide) ? 0 : 1; 00519 00520 // if (end == 1) 00521 // we need to turn around to follow 00522 // winding -= halfTurn * (side > 0 ? 1 : -1); 00523 00524 dist = last->max[side].otherDist; 00525 side = last->max[side].otherSide; 00526 } 00527 else 00528 // uh oh. we are already closed in. No chance... 00529 { 00530 winding = 0; 00531 return false; 00532 } 00533 } 00534 } 00535 } 00536 00537 #ifdef DEBUG 00538 // con << "end = " << end << ", side = " << side << ", dist = " << dist 00539 // << ", winding = " << winding << "\n\n"; 00540 #endif 00541 00542 if (tries >= 0) 00543 { 00544 return true; 00545 } 00546 else 00547 { 00548 winding = 0; 00549 return false; 00550 } 00551 }
static void ClearAITeam | ( | ) | [static] |
Definition at line 108 of file gAIBase.cpp.
References NULL.
Referenced by gAIPlayer::ClearAll(), and gAIPlayer::SetNumberOfAIs().
00109 { 00110 sg_AITeam = NULL; 00111 }
static void CycleBlocksWayHelper | ( | const gCycle * | a, | |
const gCycle * | b, | |||
int | aDir, | |||
int | bDir, | |||
REAL | aDist, | |||
REAL | bDist, | |||
int | winding | |||
) | [static] |
Definition at line 951 of file gAIBase.cpp.
References gCycleTouchEvent::dist, gCycleMemoryEntry::max, gCycle::memory, gCycleMemoryEntry::min, gCycleTouchEvent::otherDist, gCycleTouchEvent::otherSide, and gCycleTouchEvent::winding.
Referenced by gAIPlayer::CycleBlocksWay().
00953 { 00954 gCycleMemoryEntry* aEntry = (const_cast<gCycleMemory&>(a->memory)).Remember(b); 00955 00956 if (aDist > aEntry->max[aDir].dist) 00957 { 00958 aEntry->max[aDir].dist = aDist; 00959 aEntry->max[aDir].otherSide = bDir; 00960 aEntry->max[aDir].otherDist = bDist; 00961 aEntry->max[aDir].winding = winding; 00962 } 00963 00964 if (aDist < aEntry->min[aDir].dist) 00965 { 00966 aEntry->min[aDir].dist = aDist; 00967 aEntry->min[aDir].otherSide = bDir; 00968 aEntry->min[aDir].otherDist = bDist; 00969 aEntry->min[aDir].winding = winding; 00970 } 00971 }
static REAL Delay | ( | ) | [static] |
Definition at line 149 of file gAIBase.cpp.
References fd, REAL, se_AverageFrameTime(), and sg_delayCycle.
Referenced by gAIPlayer::EmergencySurvive(), gAIPlayer::RightBeforeDeath(), sg_GetSensor(), gAIPlayer::Think(), and gAIPlayer::ThinkTrace().
00150 { 00151 REAL delay = sg_delayCycle * .9f; 00152 00153 REAL fd = se_AverageFrameTime()*1.5f; 00154 if ( fd > delay) 00155 delay = fd; 00156 00157 return delay; 00158 }
Definition at line 555 of file gAIBase.cpp.
References CheckLoop(), gCycleMovement::GetDistance(), and GrowingArrayBase::Len().
Referenced by gAIPlayer::EmergencySurvive(), gAIPlayer::ThinkCloseCombat(), gAIPlayer::ThinkPath(), gAIPlayer::ThinkSurvive(), and gAIPlayer::ThinkTrace().
00556 { 00557 tArray<const gCycle*> closedIn; 00558 int winding = 0; 00559 if (CheckLoop(trapped, trapped, trapped->GetDistance(), 1, 0, closedIn, winding, trapped->GetDistance() - 1)) 00560 { 00561 if (winding + 2 < 0) 00562 { 00563 // see if the other cylce is trapped with him 00564 for (int i = closedIn.Len()-1; i>=0; i--) 00565 if (other == closedIn(i)) 00566 return false; // we can get him! 00567 00568 // no. trapped is trapped allone. 00569 return true; 00570 } 00571 } 00572 00573 return false; 00574 }
std::ostream& operator<< | ( | std::ostream & | s, | |
gAIPlayer::ThinkDataBase const & | data | |||
) |
Definition at line 2874 of file gAIBase.cpp.
References gAIPlayer::ThinkDataBase::thinkAgain, and gAIPlayer::ThinkDataBase::turn.
std::istream& operator>> | ( | std::istream & | s, | |
gAIPlayer::ThinkDataBase & | data | |||
) |
Definition at line 2881 of file gAIBase.cpp.
References gAIPlayer::ThinkDataBase::thinkAgain, and gAIPlayer::ThinkDataBase::turn.
02882 { 02883 s >> data.turn >> data.thinkAgain; 02884 02885 return s; 02886 }
REAL Random | ( | ) |
Definition at line 135 of file gAIBase.cpp.
References tRandomizer::Get(), tRandomizer::GetInstance(), and gRandomController::randomizer_.
Referenced by gAISensor::gAISensor(), gAIPlayer::RightBeforeDeath(), gAIPlayer::SwitchToState(), gAIPlayer::ThinkCloseCombat(), and gAIPlayer::ThinkSurvive().
00136 { 00137 if ( gRandomController::random_ ) 00138 { 00139 tRandomizer & randomizer = gRandomController::random_->randomizer_; 00140 return randomizer.Get(); 00141 } 00142 else 00143 { 00144 tRandomizer & randomizer = tRandomizer::GetInstance(); 00145 return randomizer.Get(); 00146 } 00147 }
static gAISensor* sg_GetSensor | ( | int | currentDirectionNumber, | |
gCycle const & | object, | |||
int | turn, | |||
REAL | side, | |||
REAL | range, | |||
REAL | corridor, | |||
REAL & | mindist | |||
) | [static] |
Definition at line 2677 of file gAIBase.cpp.
References Delay(), gAISensor::distance, eCoord, eGrid::GetDirection(), eGameObject::Position(), REAL, tNEW, and eGrid::Turn().
Referenced by gAIPlayer::Think().
02678 { 02679 // determine the current direction 02680 eGrid & grid = *object.Grid(); 02681 eCoord origDir = grid.GetDirection( currentDirectionNumber ); 02682 02683 // determine sensors 02684 gAISensor * ret = 0; 02685 02686 // turn direction 02687 int direction = currentDirectionNumber; 02688 int turns = 1; 02689 grid.Turn( direction, turn ); 02690 eCoord dir = grid.GetDirection( direction ); 02691 while ( !ret || ( turn * ( origDir * dir ) > .01 && currentDirectionNumber != direction ) ) 02692 { 02693 // cast rays 02694 gAISensor * sensor = tNEW(gAISensor)(&object,object.Position(),dir, side, range, corridor*.5f, turn ); 02695 if ( !ret || sensor->distance > ret->distance ) 02696 { 02697 if ( ret ) 02698 { 02699 // calculate effective distance required to turn around in time 02700 REAL dist = ret->distance - 1.2 * object.Speed() * Delay() * turns; 02701 if ( mindist > dist ) 02702 mindist = dist; 02703 } 02704 02705 delete ret; 02706 ret = sensor; 02707 } 02708 else 02709 { 02710 delete sensor; 02711 } 02712 02713 // go on turning 02714 grid.Turn( direction, turn ); 02715 dir = grid.GetDirection( direction ); 02716 ++turns; 02717 } 02718 02719 return ret; 02720 }
static tCONTROLLED_PTR | ( | gAITeam | ) | [static] |
int current_ai [static] |
Definition at line 1062 of file gAIBase.cpp.
nNOInitialisator<gAIPlayer> gAIPlayer_init(330,"gAIPlayer") [static] |
Referenced by gAIPlayer::CreatorDescriptor().
nNOInitialisator<gAITeam> gAITeam_init(331,"gAITeam") [static] |
Referenced by gAITeam::CreatorDescriptor().
Initial value:
{ {1,.2,.2}, {.2,1,.2}, {.2,.2,1}, {1,1,.2}, {1,.2,1}, {.2,1,1}, {1,.6,.2}, {1,.2,.6}, {.6,.2,1}, {.2,.6,1}, {1,1,1}, {.2,.2,.2}, {.5,.5,.5} }
Definition at line 1063 of file gAIBase.cpp.
char const* section = "AI" [static] |
Definition at line 2888 of file gAIBase.cpp.
Referenced by ANET_Error(), ANET_GetHostList(), nAddress::GetHostname(), eTimer::IsSynced(), nServerInfo::Load(), login_accept_handler(), PasswordCallback(), se_SmoothTime(), nBasicNetworkSystem::Select(), nAddress::SetHostname(), sg_ArchiveCoord(), sg_ArchiveReal(), and nSocket::Write().
tReferenceHolder< gAIPlayer > sg_AIReferences [static] |
Definition at line 63 of file gAIBase.cpp.