📄 be_ai_move.c
字号:
} //end if
} //end if
//FIXME: do air control to avoid hazards
return qtrue;
} //end else
} //end of the function BotWalkInDirection
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
int BotMoveInDirection(int movestate, vec3_t dir, float speed, int type)
{
bot_movestate_t *ms;
ms = BotMoveStateFromHandle(movestate);
if (!ms) return qfalse;
//if swimming
if (AAS_Swimming(ms->origin))
{
return BotSwimInDirection(ms, dir, speed, type);
} //end if
else
{
return BotWalkInDirection(ms, dir, speed, type);
} //end else
} //end of the function BotMoveInDirection
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
int Intersection(vec2_t p1, vec2_t p2, vec2_t p3, vec2_t p4, vec2_t out)
{
float x1, dx1, dy1, x2, dx2, dy2, d;
dx1 = p2[0] - p1[0];
dy1 = p2[1] - p1[1];
dx2 = p4[0] - p3[0];
dy2 = p4[1] - p3[1];
d = dy1 * dx2 - dx1 * dy2;
if (d != 0)
{
x1 = p1[1] * dx1 - p1[0] * dy1;
x2 = p3[1] * dx2 - p3[0] * dy2;
out[0] = (int) ((dx1 * x2 - dx2 * x1) / d);
out[1] = (int) ((dy1 * x2 - dy2 * x1) / d);
return qtrue;
} //end if
else
{
return qfalse;
} //end else
} //end of the function Intersection
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
void BotCheckBlocked(bot_movestate_t *ms, vec3_t dir, int checkbottom, bot_moveresult_t *result)
{
vec3_t mins, maxs, end, up = {0, 0, 1};
bsp_trace_t trace;
//test for entities obstructing the bot's path
AAS_PresenceTypeBoundingBox(ms->presencetype, mins, maxs);
//
if (fabs(DotProduct(dir, up)) < 0.7)
{
mins[2] += sv_maxstep->value; //if the bot can step on
maxs[2] -= 10; //a little lower to avoid low ceiling
} //end if
VectorMA(ms->origin, 3, dir, end);
trace = AAS_Trace(ms->origin, mins, maxs, end, ms->entitynum, CONTENTS_SOLID|CONTENTS_PLAYERCLIP|CONTENTS_BODY);
//if not started in solid and not hitting the world entity
if (!trace.startsolid && (trace.ent != ENTITYNUM_WORLD && trace.ent != ENTITYNUM_NONE) )
{
result->blocked = qtrue;
result->blockentity = trace.ent;
#ifdef DEBUG
//botimport.Print(PRT_MESSAGE, "%d: BotCheckBlocked: I'm blocked\n", ms->client);
#endif //DEBUG
} //end if
//if not in an area with reachability
else if (checkbottom && !AAS_AreaReachability(ms->areanum))
{
//check if the bot is standing on something
AAS_PresenceTypeBoundingBox(ms->presencetype, mins, maxs);
VectorMA(ms->origin, -3, up, end);
trace = AAS_Trace(ms->origin, mins, maxs, end, ms->entitynum, CONTENTS_SOLID|CONTENTS_PLAYERCLIP);
if (!trace.startsolid && (trace.ent != ENTITYNUM_WORLD && trace.ent != ENTITYNUM_NONE) )
{
result->blocked = qtrue;
result->blockentity = trace.ent;
result->flags |= MOVERESULT_ONTOPOFOBSTACLE;
#ifdef DEBUG
//botimport.Print(PRT_MESSAGE, "%d: BotCheckBlocked: I'm blocked\n", ms->client);
#endif //DEBUG
} //end if
} //end else
} //end of the function BotCheckBlocked
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
void BotClearMoveResult(bot_moveresult_t *moveresult)
{
moveresult->failure = qfalse;
moveresult->type = 0;
moveresult->blocked = qfalse;
moveresult->blockentity = 0;
moveresult->traveltype = 0;
moveresult->flags = 0;
} //end of the function BotClearMoveResult
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
bot_moveresult_t BotTravel_Walk(bot_movestate_t *ms, aas_reachability_t *reach)
{
float dist, speed;
vec3_t hordir;
bot_moveresult_t result;
BotClearMoveResult(&result);
//first walk straight to the reachability start
hordir[0] = reach->start[0] - ms->origin[0];
hordir[1] = reach->start[1] - ms->origin[1];
hordir[2] = 0;
dist = VectorNormalize(hordir);
//
BotCheckBlocked(ms, hordir, qtrue, &result);
//
if (dist < 10)
{
//walk straight to the reachability end
hordir[0] = reach->end[0] - ms->origin[0];
hordir[1] = reach->end[1] - ms->origin[1];
hordir[2] = 0;
dist = VectorNormalize(hordir);
} //end if
//if going towards a crouch area
if (!(AAS_AreaPresenceType(reach->areanum) & PRESENCE_NORMAL))
{
//if pretty close to the reachable area
if (dist < 20) EA_Crouch(ms->client);
} //end if
//
dist = BotGapDistance(ms->origin, hordir, ms->entitynum);
//
if (ms->moveflags & MFL_WALK)
{
if (dist > 0) speed = 200 - (180 - 1 * dist);
else speed = 200;
EA_Walk(ms->client);
} //end if
else
{
if (dist > 0) speed = 400 - (360 - 2 * dist);
else speed = 400;
} //end else
//elemantary action move in direction
EA_Move(ms->client, hordir, speed);
VectorCopy(hordir, result.movedir);
//
return result;
} //end of the function BotTravel_Walk
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
bot_moveresult_t BotFinishTravel_Walk(bot_movestate_t *ms, aas_reachability_t *reach)
{
vec3_t hordir;
float dist, speed;
bot_moveresult_t result;
BotClearMoveResult(&result);
//if not on the ground and changed areas... don't walk back!!
//(doesn't seem to help)
/*
ms->areanum = BotFuzzyPointReachabilityArea(ms->origin);
if (ms->areanum == reach->areanum)
{
#ifdef DEBUG
botimport.Print(PRT_MESSAGE, "BotFinishTravel_Walk: already in reach area\n");
#endif //DEBUG
return result;
} //end if*/
//go straight to the reachability end
hordir[0] = reach->end[0] - ms->origin[0];
hordir[1] = reach->end[1] - ms->origin[1];
hordir[2] = 0;
dist = VectorNormalize(hordir);
//
if (dist > 100) dist = 100;
speed = 400 - (400 - 3 * dist);
//
EA_Move(ms->client, hordir, speed);
VectorCopy(hordir, result.movedir);
//
return result;
} //end of the function BotFinishTravel_Walk
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
bot_moveresult_t BotTravel_Crouch(bot_movestate_t *ms, aas_reachability_t *reach)
{
float speed;
vec3_t hordir;
bot_moveresult_t result;
BotClearMoveResult(&result);
//
speed = 400;
//walk straight to reachability end
hordir[0] = reach->end[0] - ms->origin[0];
hordir[1] = reach->end[1] - ms->origin[1];
hordir[2] = 0;
VectorNormalize(hordir);
//
BotCheckBlocked(ms, hordir, qtrue, &result);
//elemantary actions
EA_Crouch(ms->client);
EA_Move(ms->client, hordir, speed);
//
VectorCopy(hordir, result.movedir);
//
return result;
} //end of the function BotTravel_Crouch
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
bot_moveresult_t BotTravel_BarrierJump(bot_movestate_t *ms, aas_reachability_t *reach)
{
float dist, speed;
vec3_t hordir;
bot_moveresult_t result;
BotClearMoveResult(&result);
//walk straight to reachability start
hordir[0] = reach->start[0] - ms->origin[0];
hordir[1] = reach->start[1] - ms->origin[1];
hordir[2] = 0;
dist = VectorNormalize(hordir);
//
BotCheckBlocked(ms, hordir, qtrue, &result);
//if pretty close to the barrier
if (dist < 9)
{
EA_Jump(ms->client);
} //end if
else
{
if (dist > 60) dist = 60;
speed = 360 - (360 - 6 * dist);
EA_Move(ms->client, hordir, speed);
} //end else
VectorCopy(hordir, result.movedir);
//
return result;
} //end of the function BotTravel_BarrierJump
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
bot_moveresult_t BotFinishTravel_BarrierJump(bot_movestate_t *ms, aas_reachability_t *reach)
{
float dist;
vec3_t hordir;
bot_moveresult_t result;
BotClearMoveResult(&result);
//if near the top or going down
if (ms->velocity[2] < 250)
{
hordir[0] = reach->end[0] - ms->origin[0];
hordir[1] = reach->end[1] - ms->origin[1];
hordir[2] = 0;
dist = VectorNormalize(hordir);
//
BotCheckBlocked(ms, hordir, qtrue, &result);
//
EA_Move(ms->client, hordir, 400);
VectorCopy(hordir, result.movedir);
} //end if
//
return result;
} //end of the function BotFinishTravel_BarrierJump
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
bot_moveresult_t BotTravel_Swim(bot_movestate_t *ms, aas_reachability_t *reach)
{
vec3_t dir;
bot_moveresult_t result;
BotClearMoveResult(&result);
//swim straight to reachability end
VectorSubtract(reach->start, ms->origin, dir);
VectorNormalize(dir);
//
BotCheckBlocked(ms, dir, qtrue, &result);
//elemantary actions
EA_Move(ms->client, dir, 400);
//
VectorCopy(dir, result.movedir);
Vector2Angles(dir, result.ideal_viewangles);
result.flags |= MOVERESULT_SWIMVIEW;
//
return result;
} //end of the function BotTravel_Swim
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
bot_moveresult_t BotTravel_WaterJump(bot_movestate_t *ms, aas_reachability_t *reach)
{
vec3_t dir, hordir;
float dist;
bot_moveresult_t result;
BotClearMoveResult(&result);
//swim straight to reachability end
VectorSubtract(reach->end, ms->origin, dir);
VectorCopy(dir, hordir);
hordir[2] = 0;
dir[2] += 15 + crandom() * 40;
//botimport.Print(PRT_MESSAGE, "BotTravel_WaterJump: dir[2] = %f\n", dir[2]);
VectorNormalize(dir);
dist = VectorNormalize(hordir);
//elemantary actions
//EA_Move(ms->client, dir, 400);
EA_MoveForward(ms->client);
//move up if close to the actual out of water jump spot
if (dist < 40) EA_MoveUp(ms->client);
//set the ideal view angles
Vector2Angles(dir, result.ideal_viewangles);
result.flags |= MOVERESULT_MOVEMENTVIEW;
//
VectorCopy(dir, result.movedir);
//
return result;
} //end of the function BotTravel_WaterJump
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
bot_moveresult_t BotFinishTravel_WaterJump(bot_movestate_t *ms, aas_reachability_t *reach)
{
vec3_t dir, pnt;
float dist;
bot_moveresult_t result;
//botimport.Print(PRT_MESSAGE, "BotFinishTravel_WaterJump\n");
BotClearMoveResult(&result);
//if waterjumping there's nothing to do
if (ms->moveflags & MFL_WATERJUMP) return result;
//if not touching any water anymore don't do anything
//otherwise the bot sometimes keeps jumping?
VectorCopy(ms->origin, pnt);
pnt[2] -= 32; //extra for q2dm4 near red armor/mega health
if (!(AAS_PointContents(pnt) & (CONTENTS_LAVA|CONTENTS_SLIME|CONTENTS_WATER))) return result;
//swim straight to reachability end
VectorSubtract(reach->end, ms->origin, dir);
dir[0] += crandom() * 10;
dir[1] += crandom() * 10;
dir[2] += 70 + crandom() * 10;
dist = VectorNormalize(dir);
//elemantary actions
EA_Move(ms->client, dir, 400);
//set the ideal view angles
Vector2Angles(dir, result.ideal_viewangles);
result.flags |= MOVERESULT_MOVEMENTVIEW;
//
VectorCopy(dir, result.movedir);
//
return result;
} //end of the function BotFinishTravel_WaterJump
//===========================================================================
//
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -