Main Page | Class Hierarchy | Alphabetical List | Data Structures | Directories | File List | Data Fields | Globals

be_ai_move.h File Reference

This graph shows which files directly or indirectly include this file:

Included by dependency graph

Go to the source code of this file.

Data Structures

struct  bot_avoidspot_s
struct  bot_initmove_s
struct  bot_moveresult_s

Defines

#define AVOID_ALWAYS   1
#define AVOID_CLEAR   0
#define AVOID_DONTBLOCK   2
#define MAX_AVOIDREACH   1
#define MAX_AVOIDSPOTS   32
#define MFL_ACTIVEGRAPPLE   128
#define MFL_AGAINSTLADDER   8
#define MFL_BARRIERJUMP   1
#define MFL_GRAPPLEPULL   64
#define MFL_GRAPPLERESET   256
#define MFL_ONGROUND   2
#define MFL_SWIMMING   4
#define MFL_TELEPORTED   32
#define MFL_WALK   512
#define MFL_WATERJUMP   16
#define MOVE_BFGJUMP   32
#define MOVE_CROUCH   2
#define MOVE_GRAPPLE   8
#define MOVE_JUMP   4
#define MOVE_ROCKETJUMP   16
#define MOVE_WALK   1
#define MOVERESULT_BLOCKEDBYAVOIDSPOT   256
#define MOVERESULT_MOVEMENTVIEW   1
#define MOVERESULT_MOVEMENTVIEWSET   8
#define MOVERESULT_MOVEMENTWEAPON   16
#define MOVERESULT_ONTOPOF_ELEVATOR   128
#define MOVERESULT_ONTOPOF_FUNCBOB   64
#define MOVERESULT_ONTOPOFOBSTACLE   32
#define MOVERESULT_SWIMVIEW   2
#define MOVERESULT_WAITING   4
#define RESULTTYPE_BADGRAPPLEPATH   4
#define RESULTTYPE_ELEVATORUP   1
#define RESULTTYPE_INSOLIDAREA   8
#define RESULTTYPE_WAITFORFUNCBOBBING   2

Typedefs

typedef bot_avoidspot_s bot_avoidspot_t
typedef bot_initmove_s bot_initmove_t
typedef bot_moveresult_s bot_moveresult_t

Functions

void BotAddAvoidSpot (int movestate, vec3_t origin, float radius, int type)
int BotAllocMoveState (void)
void BotFreeMoveState (int handle)
void BotInitMoveState (int handle, bot_initmove_t *initmove)
int BotMoveInDirection (int movestate, vec3_t dir, float speed, int type)
int BotMovementViewTarget (int movestate, bot_goal_t *goal, int travelflags, float lookahead, vec3_t target)
void BotMoveToGoal (bot_moveresult_t *result, int movestate, bot_goal_t *goal, int travelflags)
int BotPredictVisiblePosition (vec3_t origin, int areanum, bot_goal_t *goal, int travelflags, vec3_t target)
int BotReachabilityArea (vec3_t origin, int client)
void BotResetAvoidReach (int movestate)
void BotResetLastAvoidReach (int movestate)
void BotResetMoveState (int movestate)
void BotSetBrushModelTypes (void)
int BotSetupMoveAI (void)
void BotShutdownMoveAI (void)


Define Documentation

#define AVOID_ALWAYS   1
 

Definition at line 66 of file be_ai_move.h.

Referenced by BotCheckForGrenades().

#define AVOID_CLEAR   0
 

Definition at line 65 of file be_ai_move.h.

Referenced by BotCheckSnapshot().

#define AVOID_DONTBLOCK   2
 

Definition at line 67 of file be_ai_move.h.

#define MAX_AVOIDREACH   1
 

Definition at line 62 of file be_ai_move.h.

Referenced by BotGetReachabilityToGoal(), BotPredictVisiblePosition(), and BotResetAvoidReach().

#define MAX_AVOIDSPOTS   32
 

Definition at line 63 of file be_ai_move.h.

#define MFL_ACTIVEGRAPPLE   128
 

Definition at line 48 of file be_ai_move.h.

#define MFL_AGAINSTLADDER   8
 

Definition at line 44 of file be_ai_move.h.

#define MFL_BARRIERJUMP   1
 

Definition at line 41 of file be_ai_move.h.

#define MFL_GRAPPLEPULL   64
 

Definition at line 47 of file be_ai_move.h.

#define MFL_GRAPPLERESET   256
 

Definition at line 49 of file be_ai_move.h.

#define MFL_ONGROUND   2
 

Definition at line 42 of file be_ai_move.h.

Referenced by BotMoveToGoal().

#define MFL_SWIMMING   4
 

Definition at line 43 of file be_ai_move.h.

Referenced by BotMoveToGoal().

#define MFL_TELEPORTED   32
 

Definition at line 46 of file be_ai_move.h.

#define MFL_WALK   512
 

Definition at line 50 of file be_ai_move.h.

#define MFL_WATERJUMP   16
 

Definition at line 45 of file be_ai_move.h.

#define MOVE_BFGJUMP   32
 

Definition at line 39 of file be_ai_move.h.

#define MOVE_CROUCH   2
 

Definition at line 35 of file be_ai_move.h.

Referenced by BotAIBlocked().

#define MOVE_GRAPPLE   8
 

Definition at line 37 of file be_ai_move.h.

#define MOVE_JUMP   4
 

Definition at line 36 of file be_ai_move.h.

#define MOVE_ROCKETJUMP   16
 

Definition at line 38 of file be_ai_move.h.

#define MOVE_WALK   1
 

Definition at line 34 of file be_ai_move.h.

Referenced by BotGetLongTermGoal(), and BotRandomMove().

#define MOVERESULT_BLOCKEDBYAVOIDSPOT   256
 

Definition at line 60 of file be_ai_move.h.

#define MOVERESULT_MOVEMENTVIEW   1
 

Definition at line 52 of file be_ai_move.h.

Referenced by AINode_Battle_Chase(), AINode_Battle_NBG(), AINode_Battle_Retreat(), AINode_Seek_ActivateEntity(), AINode_Seek_LTG(), AINode_Seek_NBG(), and BotClearPath().

#define MOVERESULT_MOVEMENTVIEWSET   8
 

Definition at line 55 of file be_ai_move.h.

Referenced by AINode_Battle_Chase(), AINode_Seek_ActivateEntity(), AINode_Seek_LTG(), and AINode_Seek_NBG().

#define MOVERESULT_MOVEMENTWEAPON   16
 

Definition at line 56 of file be_ai_move.h.

Referenced by BotClearPath().

#define MOVERESULT_ONTOPOF_ELEVATOR   128
 

Definition at line 59 of file be_ai_move.h.

#define MOVERESULT_ONTOPOF_FUNCBOB   64
 

Definition at line 58 of file be_ai_move.h.

#define MOVERESULT_ONTOPOFOBSTACLE   32
 

Definition at line 57 of file be_ai_move.h.

#define MOVERESULT_SWIMVIEW   2
 

Definition at line 53 of file be_ai_move.h.

#define MOVERESULT_WAITING   4
 

Definition at line 54 of file be_ai_move.h.

#define RESULTTYPE_BADGRAPPLEPATH   4
 

Definition at line 71 of file be_ai_move.h.

#define RESULTTYPE_ELEVATORUP   1
 

Definition at line 69 of file be_ai_move.h.

#define RESULTTYPE_INSOLIDAREA   8
 

Definition at line 72 of file be_ai_move.h.

#define RESULTTYPE_WAITFORFUNCBOBBING   2
 

Definition at line 70 of file be_ai_move.h.


Typedef Documentation

typedef struct bot_avoidspot_s bot_avoidspot_t
 

Referenced by BotAvoidSpots().

typedef struct bot_initmove_s bot_initmove_t
 

Referenced by BotInitMoveState(), and BotSetupForMovement().

typedef struct bot_moveresult_s bot_moveresult_t
 

Referenced by AINode_Battle_Chase(), AINode_Battle_Fight(), AINode_Battle_NBG(), AINode_Battle_Retreat(), AINode_Seek_ActivateEntity(), AINode_Seek_LTG(), AINode_Seek_NBG(), BotAIBlocked(), BotAttackMove(), BotCheckBlocked(), BotClearMoveResult(), BotClearPath(), BotFinishTravel_BarrierJump(), BotFinishTravel_Elevator(), BotFinishTravel_FuncBobbing(), BotFinishTravel_Jump(), BotFinishTravel_JumpPad(), BotFinishTravel_Walk(), BotFinishTravel_WalkOffLedge(), BotFinishTravel_WaterJump(), BotFinishTravel_WeaponJump(), BotMoveInGoalArea(), BotMoveToGoal(), BotRandomMove(), BotTravel_BarrierJump(), BotTravel_BFGJump(), BotTravel_Crouch(), BotTravel_Elevator(), BotTravel_FuncBobbing(), BotTravel_Grapple(), BotTravel_Jump(), BotTravel_JumpPad(), BotTravel_Ladder(), BotTravel_RocketJump(), BotTravel_Swim(), BotTravel_Teleport(), BotTravel_Walk(), BotTravel_WalkOffLedge(), and BotTravel_WaterJump().


Function Documentation

void BotAddAvoidSpot int  movestate,
vec3_t  origin,
float  radius,
int  type
 

Definition at line 719 of file be_ai_move.c.

References bot_movestate_s::avoidspots, bot_movestate_t, BotMoveStateFromHandle(), bot_movestate_s::numavoidspots, bot_movestate_s::origin, bot_avoidspot_s::radius, bot_avoidspot_s::type, type, and VectorCopy.

00720 {
00721     bot_movestate_t *ms;
00722 
00723     ms = BotMoveStateFromHandle(movestate);
00724     if (!ms) return;
00725     if (type == AVOID_CLEAR)
00726     {
00727         ms->numavoidspots = 0;
00728         return;
00729     } //end if
00730 
00731     if (ms->numavoidspots >= MAX_AVOIDSPOTS)
00732         return;
00733     VectorCopy(origin, ms->avoidspots[ms->numavoidspots].origin);
00734     ms->avoidspots[ms->numavoidspots].radius = radius;
00735     ms->avoidspots[ms->numavoidspots].type = type;
00736     ms->numavoidspots++;
00737 } //end of the function BotAddAvoidSpot

Here is the call graph for this function:

int BotAllocMoveState void   ) 
 

Definition at line 127 of file be_ai_move.c.

References bot_movestate_t, botmovestates, GetClearedMemory(), and i.

00128 {
00129     int i;
00130 
00131     for (i = 1; i <= MAX_CLIENTS; i++)
00132     {
00133         if (!botmovestates[i])
00134         {
00135             botmovestates[i] = GetClearedMemory(sizeof(bot_movestate_t));
00136             return i;
00137         } //end if
00138     } //end for
00139     return 0;
00140 } //end of the function BotAllocMoveState

Here is the call graph for this function:

void BotFreeMoveState int  handle  ) 
 

Definition at line 147 of file be_ai_move.c.

References botimport, botmovestates, FreeMemory(), and PRT_FATAL.

00148 {
00149     if (handle <= 0 || handle > MAX_CLIENTS)
00150     {
00151         botimport.Print(PRT_FATAL, "move state handle %d out of range\n", handle);
00152         return;
00153     } //end if
00154     if (!botmovestates[handle])
00155     {
00156         botimport.Print(PRT_FATAL, "invalid move state %d\n", handle);
00157         return;
00158     } //end if
00159     FreeMemory(botmovestates[handle]);
00160     botmovestates[handle] = NULL;
00161 } //end of the function BotFreeMoveState

Here is the call graph for this function:

void BotInitMoveState int  handle,
bot_initmove_t initmove
 

Definition at line 188 of file be_ai_move.c.

References bot_initmove_t, bot_movestate_t, BotMoveStateFromHandle(), bot_initmove_s::client, bot_movestate_s::client, bot_initmove_s::entitynum, bot_movestate_s::entitynum, bot_movestate_s::moveflags, bot_initmove_s::or_moveflags, bot_movestate_s::origin, bot_initmove_s::origin, bot_initmove_s::presencetype, bot_movestate_s::presencetype, bot_initmove_s::thinktime, bot_movestate_s::thinktime, VectorCopy, bot_movestate_s::velocity, bot_initmove_s::velocity, bot_movestate_s::viewangles, bot_initmove_s::viewangles, bot_movestate_s::viewoffset, and bot_initmove_s::viewoffset.

00189 {
00190     bot_movestate_t *ms;
00191 
00192     ms = BotMoveStateFromHandle(handle);
00193     if (!ms) return;
00194     VectorCopy(initmove->origin, ms->origin);
00195     VectorCopy(initmove->velocity, ms->velocity);
00196     VectorCopy(initmove->viewoffset, ms->viewoffset);
00197     ms->entitynum = initmove->entitynum;
00198     ms->client = initmove->client;
00199     ms->thinktime = initmove->thinktime;
00200     ms->presencetype = initmove->presencetype;
00201     VectorCopy(initmove->viewangles, ms->viewangles);
00202     //
00203     ms->moveflags &= ~MFL_ONGROUND;
00204     if (initmove->or_moveflags & MFL_ONGROUND) ms->moveflags |= MFL_ONGROUND;
00205     ms->moveflags &= ~MFL_TELEPORTED;   
00206     if (initmove->or_moveflags & MFL_TELEPORTED) ms->moveflags |= MFL_TELEPORTED;
00207     ms->moveflags &= ~MFL_WATERJUMP;
00208     if (initmove->or_moveflags & MFL_WATERJUMP) ms->moveflags |= MFL_WATERJUMP;
00209     ms->moveflags &= ~MFL_WALK;
00210     if (initmove->or_moveflags & MFL_WALK) ms->moveflags |= MFL_WALK;
00211     ms->moveflags &= ~MFL_GRAPPLEPULL;
00212     if (initmove->or_moveflags & MFL_GRAPPLEPULL) ms->moveflags |= MFL_GRAPPLEPULL;
00213 } //end of the function BotInitMoveState

Here is the call graph for this function:

int BotMoveInDirection int  movestate,
vec3_t  dir,
float  speed,
int  type
 

Definition at line 1231 of file be_ai_move.c.

References AAS_Swimming(), bot_movestate_t, BotMoveStateFromHandle(), BotSwimInDirection(), BotWalkInDirection(), bot_movestate_s::origin, and type.

01232 {
01233     bot_movestate_t *ms;
01234 
01235     ms = BotMoveStateFromHandle(movestate);
01236     if (!ms) return qfalse;
01237     //if swimming
01238     if (AAS_Swimming(ms->origin))
01239     {
01240         return BotSwimInDirection(ms, dir, speed, type);
01241     } //end if
01242     else
01243     {
01244         return BotWalkInDirection(ms, dir, speed, type);
01245     } //end else
01246 } //end of the function BotMoveInDirection

Here is the call graph for this function:

int BotMovementViewTarget int  movestate,
bot_goal_t goal,
int  travelflags,
float  lookahead,
vec3_t  target
 

Definition at line 843 of file be_ai_move.c.

References aas_reachability_t, AAS_ReachabilityFromNum(), bot_goal_s::areanum, aas_reachability_s::areanum, bot_movestate_s::avoidreach, bot_movestate_s::avoidreachtimes, bot_movestate_s::avoidreachtries, bot_goal_t, bot_movestate_t, BotAddToTarget(), BotGetReachabilityToGoal(), BotMoveStateFromHandle(), aas_reachability_s::end, bot_movestate_s::lastareanum, bot_movestate_s::lastgoalareanum, bot_movestate_s::lastreachnum, NULL, bot_goal_s::origin, bot_movestate_s::origin, aas_reachability_s::start, TRAVEL_ELEVATOR, TRAVEL_JUMPPAD, aas_reachability_s::traveltype, vec3_t, and VectorCopy.

00844 {
00845     aas_reachability_t reach;
00846     int reachnum, lastareanum;
00847     bot_movestate_t *ms;
00848     vec3_t end;
00849     float dist;
00850 
00851     ms = BotMoveStateFromHandle(movestate);
00852     if (!ms) return qfalse;
00853     reachnum = 0;
00854     //if the bot has no goal or no last reachability
00855     if (!ms->lastreachnum || !goal) return qfalse;
00856 
00857     reachnum = ms->lastreachnum;
00858     VectorCopy(ms->origin, end);
00859     lastareanum = ms->lastareanum;
00860     dist = 0;
00861     while(reachnum && dist < lookahead)
00862     {
00863         AAS_ReachabilityFromNum(reachnum, &reach);
00864         if (BotAddToTarget(end, reach.start, lookahead, &dist, target)) return qtrue;
00865         //never look beyond teleporters
00866         if ((reach.traveltype & TRAVELTYPE_MASK) == TRAVEL_TELEPORT) return qtrue;
00867         //never look beyond the weapon jump point
00868         if ((reach.traveltype & TRAVELTYPE_MASK) == TRAVEL_ROCKETJUMP) return qtrue;
00869         if ((reach.traveltype & TRAVELTYPE_MASK) == TRAVEL_BFGJUMP) return qtrue;
00870         //don't add jump pad distances
00871         if ((reach.traveltype & TRAVELTYPE_MASK) != TRAVEL_JUMPPAD &&
00872             (reach.traveltype & TRAVELTYPE_MASK) != TRAVEL_ELEVATOR &&
00873             (reach.traveltype & TRAVELTYPE_MASK) != TRAVEL_FUNCBOB)
00874         {
00875             if (BotAddToTarget(reach.start, reach.end, lookahead, &dist, target)) return qtrue;
00876         } //end if
00877         reachnum = BotGetReachabilityToGoal(reach.end, reach.areanum,
00878                         ms->lastgoalareanum, lastareanum,
00879                             ms->avoidreach, ms->avoidreachtimes, ms->avoidreachtries,
00880                                     goal, travelflags, travelflags, NULL, 0, NULL);
00881         VectorCopy(reach.end, end);
00882         lastareanum = reach.areanum;
00883         if (lastareanum == goal->areanum)
00884         {
00885             BotAddToTarget(reach.end, goal->origin, lookahead, &dist, target);
00886             return qtrue;
00887         } //end if
00888     } //end while
00889     //
00890     return qfalse;
00891 } //end of the function BotMovementViewTarget

Here is the call graph for this function:

void BotMoveToGoal bot_moveresult_t result,
int  movestate,
bot_goal_t goal,
int  travelflags
 

Definition at line 3055 of file be_ai_move.c.

References AAS_AgainstLadder(), AAS_AreaJumpPad(), AAS_AreaReachability(), AAS_ClearShownDebugLines(), AAS_EntityModelindex(), AAS_NextAreaReachability(), AAS_NextModelReachability(), AAS_OnGround(), AAS_PrintTravelType(), aas_reachability_t, AAS_ReachabilityFromNum(), AAS_ShowReachability(), AAS_Swimming(), AAS_Time(), AAS_TraceAreas(), AAS_TravelFlagForType(), aas_reachability_s::areanum, bot_goal_s::areanum, bot_movestate_s::areanum, bot_movestate_s::avoidreach, AVOIDREACH_TIME, bot_movestate_s::avoidreachtimes, bot_movestate_s::avoidreachtries, bot_movestate_s::avoidspots, bot_moveresult_s::blocked, bot_moveresult_s::blockentity, bot_goal_t, bot_moveresult_t, bot_movestate_t, BotAddToAvoidReach(), BotClearMoveResult(), BotFinishTravel_BarrierJump(), BotFinishTravel_Elevator(), BotFinishTravel_FuncBobbing(), BotFinishTravel_Jump(), BotFinishTravel_JumpPad(), BotFinishTravel_WalkOffLedge(), BotFinishTravel_WaterJump(), BotFinishTravel_WeaponJump(), BotFuzzyPointReachabilityArea(), BotGetReachabilityToGoal(), botimport, BotMoveInGoalArea(), BotMoveStateFromHandle(), BotOnTopOfEntity(), BotReachabilityTime(), BotResetGrapple(), BotTravel_BarrierJump(), BotTravel_BFGJump(), BotTravel_Crouch(), BotTravel_Elevator(), BotTravel_FuncBobbing(), BotTravel_Grapple(), BotTravel_Jump(), BotTravel_JumpPad(), BotTravel_Ladder(), BotTravel_RocketJump(), BotTravel_Swim(), BotTravel_Teleport(), BotTravel_Walk(), BotTravel_WalkOffLedge(), BotTravel_WaterJump(), bot_movestate_s::client, Com_Memset(), bot_movestate_s::entitynum, aas_reachability_s::facenum, bot_moveresult_s::failure, bot_moveresult_s::flags, i, bot_movestate_s::jumpreach, bot_movestate_s::lastareanum, bot_movestate_s::lastgoalareanum, bot_movestate_s::lastorigin, bot_movestate_s::lastreachnum, MFL_ONGROUND, MFL_SWIMMING, MODELTYPE_FUNC_STATIC, modeltypes, bot_movestate_s::moveflags, NULL, numareas, bot_movestate_s::numavoidspots, bot_movestate_s::origin, bot_movestate_s::presencetype, PRT_FATAL, PRT_MESSAGE, bot_movestate_s::reachability_time, bot_movestate_s::reachareanum, TFL_JUMPPAD, bot_movestate_s::thinktime, TRAVEL_BARRIERJUMP, TRAVEL_BFGJUMP, TRAVEL_CROUCH, TRAVEL_ELEVATOR, TRAVEL_FUNCBOB, TRAVEL_GRAPPLEHOOK, TRAVEL_JUMP, TRAVEL_JUMPPAD, TRAVEL_LADDER, TRAVEL_ROCKETJUMP, TRAVEL_SWIM, TRAVEL_TELEPORT, TRAVEL_WALK, TRAVEL_WALKOFFLEDGE, TRAVEL_WATERJUMP, bot_moveresult_s::traveltype, aas_reachability_s::traveltype, TRAVELTYPE_MASK, bot_moveresult_s::type, vec3_t, VectorCopy, VectorMA, and bot_movestate_s::velocity.

03056 {
03057     int reachnum, lastreachnum, foundjumppad, ent, resultflags;
03058     aas_reachability_t reach, lastreach;
03059     bot_movestate_t *ms;
03060     //vec3_t mins, maxs, up = {0, 0, 1};
03061     //bsp_trace_t trace;
03062     //static int debugline;
03063 
03064 
03065     BotClearMoveResult(result);
03066     //
03067     ms = BotMoveStateFromHandle(movestate);
03068     if (!ms) return;
03069     //reset the grapple before testing if the bot has a valid goal
03070     //because the bot could loose all it's goals when stuck to a wall
03071     BotResetGrapple(ms);
03072     //
03073     if (!goal)
03074     {
03075 #ifdef DEBUG
03076         botimport.Print(PRT_MESSAGE, "client %d: movetogoal -> no goal\n", ms->client);
03077 #endif //DEBUG
03078         result->failure = qtrue;
03079         return;
03080     } //end if
03081     //botimport.Print(PRT_MESSAGE, "numavoidreach = %d\n", ms->numavoidreach);
03082     //remove some of the move flags
03083     ms->moveflags &= ~(MFL_SWIMMING|MFL_AGAINSTLADDER);
03084     //set some of the move flags
03085     //NOTE: the MFL_ONGROUND flag is also set in the higher AI
03086     if (AAS_OnGround(ms->origin, ms->presencetype, ms->entitynum)) ms->moveflags |= MFL_ONGROUND;
03087     //
03088     if (ms->moveflags & MFL_ONGROUND)
03089     {
03090         int modeltype, modelnum;
03091 
03092         ent = BotOnTopOfEntity(ms);
03093 
03094         if (ent != -1)
03095         {
03096             modelnum = AAS_EntityModelindex(ent);
03097             if (modelnum >= 0 && modelnum < MAX_MODELS)
03098             {
03099                 modeltype = modeltypes[modelnum];
03100 
03101                 if (modeltype == MODELTYPE_FUNC_PLAT)
03102                 {
03103                     AAS_ReachabilityFromNum(ms->lastreachnum, &reach);
03104                     //if the bot is Not using the elevator
03105                     if ((reach.traveltype & TRAVELTYPE_MASK) != TRAVEL_ELEVATOR ||
03106                         //NOTE: the face number is the plat model number
03107                         (reach.facenum & 0x0000FFFF) != modelnum)
03108                     {
03109                         reachnum = AAS_NextModelReachability(0, modelnum);
03110                         if (reachnum)
03111                         {
03112                             //botimport.Print(PRT_MESSAGE, "client %d: accidentally ended up on func_plat\n", ms->client);
03113                             AAS_ReachabilityFromNum(reachnum, &reach);
03114                             ms->lastreachnum = reachnum;
03115                             ms->reachability_time = AAS_Time() + BotReachabilityTime(&reach);
03116                         } //end if
03117                         else
03118                         {
03119                             if (bot_developer)
03120                             {
03121                                 botimport.Print(PRT_MESSAGE, "client %d: on func_plat without reachability\n", ms->client);
03122                             } //end if
03123                             result->blocked = qtrue;
03124                             result->blockentity = ent;
03125                             result->flags |= MOVERESULT_ONTOPOFOBSTACLE;
03126                             return;
03127                         } //end else
03128                     } //end if
03129                     result->flags |= MOVERESULT_ONTOPOF_ELEVATOR;
03130                 } //end if
03131                 else if (modeltype == MODELTYPE_FUNC_BOB)
03132                 {
03133                     AAS_ReachabilityFromNum(ms->lastreachnum, &reach);
03134                     //if the bot is Not using the func bobbing
03135                     if ((reach.traveltype & TRAVELTYPE_MASK) != TRAVEL_FUNCBOB ||
03136                         //NOTE: the face number is the func_bobbing model number
03137                         (reach.facenum & 0x0000FFFF) != modelnum)
03138                     {
03139                         reachnum = AAS_NextModelReachability(0, modelnum);
03140                         if (reachnum)
03141                         {
03142                             //botimport.Print(PRT_MESSAGE, "client %d: accidentally ended up on func_bobbing\n", ms->client);
03143                             AAS_ReachabilityFromNum(reachnum, &reach);
03144                             ms->lastreachnum = reachnum;
03145                             ms->reachability_time = AAS_Time() + BotReachabilityTime(&reach);
03146                         } //end if
03147                         else
03148                         {
03149                             if (bot_developer)
03150                             {
03151                                 botimport.Print(PRT_MESSAGE, "client %d: on func_bobbing without reachability\n", ms->client);
03152                             } //end if
03153                             result->blocked = qtrue;
03154                             result->blockentity = ent;
03155                             result->flags |= MOVERESULT_ONTOPOFOBSTACLE;
03156                             return;
03157                         } //end else
03158                     } //end if
03159                     result->flags |= MOVERESULT_ONTOPOF_FUNCBOB;
03160                 } //end if
03161                 else if (modeltype == MODELTYPE_FUNC_STATIC || modeltype == MODELTYPE_FUNC_DOOR)
03162                 {
03163                     // check if ontop of a door bridge ?
03164                     ms->areanum = BotFuzzyPointReachabilityArea(ms->origin);
03165                     // if not in a reachability area
03166                     if (!AAS_AreaReachability(ms->areanum))
03167                     {
03168                         result->blocked = qtrue;
03169                         result->blockentity = ent;
03170                         result->flags |= MOVERESULT_ONTOPOFOBSTACLE;
03171                         return;
03172                     } //end if
03173                 } //end else if
03174                 else
03175                 {
03176                     result->blocked = qtrue;
03177                     result->blockentity = ent;
03178                     result->flags |= MOVERESULT_ONTOPOFOBSTACLE;
03179                     return;
03180                 } //end else
03181             } //end if
03182         } //end if
03183     } //end if
03184     //if swimming
03185     if (AAS_Swimming(ms->origin)) ms->moveflags |= MFL_SWIMMING;
03186     //if against a ladder
03187     if (AAS_AgainstLadder(ms->origin)) ms->moveflags |= MFL_AGAINSTLADDER;
03188     //if the bot is on the ground, swimming or against a ladder
03189     if (ms->moveflags & (MFL_ONGROUND|MFL_SWIMMING|MFL_AGAINSTLADDER))
03190     {
03191         //botimport.Print(PRT_MESSAGE, "%s: onground, swimming or against ladder\n", ClientName(ms->entitynum-1));
03192         //
03193         AAS_ReachabilityFromNum(ms->lastreachnum, &lastreach);
03194         //reachability area the bot is in
03195         //ms->areanum = BotReachabilityArea(ms->origin, ((lastreach.traveltype & TRAVELTYPE_MASK) != TRAVEL_ELEVATOR));
03196         ms->areanum = BotFuzzyPointReachabilityArea(ms->origin);
03197         //
03198         if ( !ms->areanum )
03199         {
03200             result->failure = qtrue;
03201             result->blocked = qtrue;
03202             result->blockentity = 0;
03203             result->type = RESULTTYPE_INSOLIDAREA;
03204             return;
03205         } //end if
03206         //if the bot is in the goal area
03207         if (ms->areanum == goal->areanum)
03208         {
03209             *result = BotMoveInGoalArea(ms, goal);
03210             return;
03211         } //end if
03212         //assume we can use the reachability from the last frame
03213         reachnum = ms->lastreachnum;
03214         //if there is a last reachability
03215         if (reachnum)
03216         {
03217             AAS_ReachabilityFromNum(reachnum, &reach);
03218             //check if the reachability is still valid
03219             if (!(AAS_TravelFlagForType(reach.traveltype) & travelflags))
03220             {
03221                 reachnum = 0;
03222             } //end if
03223             //special grapple hook case
03224             else if ((reach.traveltype & TRAVELTYPE_MASK) == TRAVEL_GRAPPLEHOOK)
03225             {
03226                 if (ms->reachability_time < AAS_Time() ||
03227                     (ms->moveflags & MFL_GRAPPLERESET))
03228                 {
03229                     reachnum = 0;
03230                 } //end if
03231             } //end if
03232             //special elevator case
03233             else if ((reach.traveltype & TRAVELTYPE_MASK) == TRAVEL_ELEVATOR ||
03234                 (reach.traveltype & TRAVELTYPE_MASK) == TRAVEL_FUNCBOB)
03235             {
03236                 if ((result->flags & MOVERESULT_ONTOPOF_FUNCBOB) ||
03237                     (result->flags & MOVERESULT_ONTOPOF_FUNCBOB))
03238                 {
03239                     ms->reachability_time = AAS_Time() + 5;
03240                 } //end if
03241                 //if the bot was going for an elevator and reached the reachability area
03242                 if (ms->areanum == reach.areanum ||
03243                     ms->reachability_time < AAS_Time())
03244                 {
03245                     reachnum = 0;
03246                 } //end if
03247             } //end if
03248             else
03249             {
03250 #ifdef DEBUG
03251                 if (bot_developer)
03252                 {
03253                     if (ms->reachability_time < AAS_Time())
03254                     {
03255                         botimport.Print(PRT_MESSAGE, "client %d: reachability timeout in ", ms->client);
03256                         AAS_PrintTravelType(reach.traveltype & TRAVELTYPE_MASK);
03257                         botimport.Print(PRT_MESSAGE, "\n");
03258                     } //end if
03259                     /*
03260                     if (ms->lastareanum != ms->areanum)
03261                     {
03262                         botimport.Print(PRT_MESSAGE, "changed from area %d to %d\n", ms->lastareanum, ms->areanum);
03263                     } //end if*/
03264                 } //end if
03265 #endif //DEBUG
03266                 //if the goal area changed or the reachability timed out
03267                 //or the area changed
03268                 if (ms->lastgoalareanum != goal->areanum ||
03269                         ms->reachability_time < AAS_Time() ||
03270                         ms->lastareanum != ms->areanum)
03271                 {
03272                     reachnum = 0;
03273                     //botimport.Print(PRT_MESSAGE, "area change or timeout\n");
03274                 } //end else if
03275             } //end else
03276         } //end if
03277         resultflags = 0;
03278         //if the bot needs a new reachability
03279         if (!reachnum)
03280         {
03281             //if the area has no reachability links
03282             if (!AAS_AreaReachability(ms->areanum))
03283             {
03284 #ifdef DEBUG
03285                 if (bot_developer)
03286                 {
03287                     botimport.Print(PRT_MESSAGE, "area %d no reachability\n", ms->areanum);
03288                 } //end if
03289 #endif //DEBUG
03290             } //end if
03291             //get a new reachability leading towards the goal
03292             reachnum = BotGetReachabilityToGoal(ms->origin, ms->areanum,
03293                                 ms->lastgoalareanum, ms->lastareanum,
03294                                             ms->avoidreach, ms->avoidreachtimes, ms->avoidreachtries,
03295                                                         goal, travelflags, travelflags,
03296                                                                 ms->avoidspots, ms->numavoidspots, &resultflags);
03297             //the area number the reachability starts in
03298             ms->reachareanum = ms->areanum;
03299             //reset some state variables
03300             ms->jumpreach = 0;                      //for TRAVEL_JUMP
03301             ms->moveflags &= ~MFL_GRAPPLERESET; //for TRAVEL_GRAPPLEHOOK
03302             //if there is a reachability to the goal
03303             if (reachnum)
03304             {
03305                 AAS_ReachabilityFromNum(reachnum, &reach);
03306                 //set a timeout for this reachability
03307                 ms->reachability_time = AAS_Time() + BotReachabilityTime(&reach);
03308                 //
03309 #ifdef AVOIDREACH
03310                 //add the reachability to the reachabilities to avoid for a while
03311                 BotAddToAvoidReach(ms, reachnum, AVOIDREACH_TIME);
03312 #endif //AVOIDREACH
03313             } //end if
03314 #ifdef DEBUG
03315             
03316             else if (bot_developer)
03317             {
03318                 botimport.Print(PRT_MESSAGE, "goal not reachable\n");
03319                 Com_Memset(&reach, 0, sizeof(aas_reachability_t)); //make compiler happy
03320             } //end else
03321             if (bot_developer)
03322             {
03323                 //if still going for the same goal
03324                 if (ms->lastgoalareanum == goal->areanum)
03325                 {
03326                     if (ms->lastareanum == reach.areanum)
03327                     {
03328                         botimport.Print(PRT_MESSAGE, "same goal, going back to previous area\n");
03329                     } //end if
03330                 } //end if
03331             } //end if
03332 #endif //DEBUG
03333         } //end else
03334         //
03335         ms->lastreachnum = reachnum;
03336         ms->lastgoalareanum = goal->areanum;
03337         ms->lastareanum = ms->areanum;
03338         //if the bot has a reachability
03339         if (reachnum)
03340         {
03341             //get the reachability from the number
03342             AAS_ReachabilityFromNum(reachnum, &reach);
03343             result->traveltype = reach.traveltype;
03344             //
03345 #ifdef DEBUG_AI_MOVE
03346             AAS_ClearShownDebugLines();
03347             AAS_PrintTravelType(reach.traveltype & TRAVELTYPE_MASK);
03348             AAS_ShowReachability(&reach);
03349 #endif //DEBUG_AI_MOVE
03350             //
03351 #ifdef DEBUG
03352             //botimport.Print(PRT_MESSAGE, "client %d: ", ms->client);
03353             //AAS_PrintTravelType(reach.traveltype);
03354             //botimport.Print(PRT_MESSAGE, "\n");
03355 #endif //DEBUG
03356             switch(reach.traveltype & TRAVELTYPE_MASK)
03357             {
03358                 case TRAVEL_WALK: *result = BotTravel_Walk(ms, &reach); break;
03359                 case TRAVEL_CROUCH: *result = BotTravel_Crouch(ms, &reach); break;
03360                 case TRAVEL_BARRIERJUMP: *result = BotTravel_BarrierJump(ms, &reach); break;
03361                 case TRAVEL_LADDER: *result = BotTravel_Ladder(ms, &reach); break;
03362                 case TRAVEL_WALKOFFLEDGE: *result = BotTravel_WalkOffLedge(ms, &reach); break;
03363                 case TRAVEL_JUMP: *result = BotTravel_Jump(ms, &reach); break;
03364                 case TRAVEL_SWIM: *result = BotTravel_Swim(ms, &reach); break;
03365                 case TRAVEL_WATERJUMP: *result = BotTravel_WaterJump(ms, &reach); break;
03366                 case TRAVEL_TELEPORT: *result = BotTravel_Teleport(ms, &reach); break;
03367                 case TRAVEL_ELEVATOR: *result = BotTravel_Elevator(ms, &reach); break;
03368                 case TRAVEL_GRAPPLEHOOK: *result = BotTravel_Grapple(ms, &reach); break;
03369                 case TRAVEL_ROCKETJUMP: *result = BotTravel_RocketJump(ms, &reach); break;
03370                 case TRAVEL_BFGJUMP: *result = BotTravel_BFGJump(ms, &reach); break;
03371                 case TRAVEL_JUMPPAD: *result = BotTravel_JumpPad(ms, &reach); break;
03372                 case TRAVEL_FUNCBOB: *result = BotTravel_FuncBobbing(ms, &reach); break;
03373                 default:
03374                 {
03375                     botimport.Print(PRT_FATAL,