📄 be_ai_move.c
字号:
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
bot_moveresult_t BotTravel_WalkOffLedge(bot_movestate_t *ms, aas_reachability_t *reach)
{
vec3_t hordir, dir;
float dist, speed, reachhordist;
bot_moveresult_t result;
BotClearMoveResult(&result);
//check if the bot is blocked by anything
VectorSubtract(reach->start, ms->origin, dir);
VectorNormalize(dir);
BotCheckBlocked(ms, dir, qtrue, &result);
//if the reachability start and end are practially above each other
VectorSubtract(reach->end, reach->start, dir);
dir[2] = 0;
reachhordist = VectorLength(dir);
//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);
//if pretty close to the start focus on the reachability end
if (dist < 48)
{
hordir[0] = reach->end[0] - ms->origin[0];
hordir[1] = reach->end[1] - ms->origin[1];
hordir[2] = 0;
VectorNormalize(hordir);
//
if (reachhordist < 20)
{
speed = 100;
} //end if
else if (!AAS_HorizontalVelocityForJump(0, reach->start, reach->end, &speed))
{
speed = 400;
} //end if
} //end if
else
{
if (reachhordist < 20)
{
if (dist > 64) dist = 64;
speed = 400 - (256 - 4 * dist);
} //end if
else
{
speed = 400;
} //end else
} //end else
//
BotCheckBlocked(ms, hordir, qtrue, &result);
//elemantary action
EA_Move(ms->client, hordir, speed);
VectorCopy(hordir, result.movedir);
//
return result;
} //end of the function BotTravel_WalkOffLedge
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
int BotAirControl(vec3_t origin, vec3_t velocity, vec3_t goal, vec3_t dir, float *speed)
{
vec3_t org, vel;
float dist;
int i;
VectorCopy(origin, org);
VectorScale(velocity, 0.1, vel);
for (i = 0; i < 50; i++)
{
vel[2] -= sv_gravity->value * 0.01;
//if going down and next position would be below the goal
if (vel[2] < 0 && org[2] + vel[2] < goal[2])
{
VectorScale(vel, (goal[2] - org[2]) / vel[2], vel);
VectorAdd(org, vel, org);
VectorSubtract(goal, org, dir);
dist = VectorNormalize(dir);
if (dist > 32) dist = 32;
*speed = 400 - (400 - 13 * dist);
return qtrue;
} //end if
else
{
VectorAdd(org, vel, org);
} //end else
} //end for
VectorSet(dir, 0, 0, 0);
*speed = 400;
return qfalse;
} //end of the function BotAirControl
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
bot_moveresult_t BotFinishTravel_WalkOffLedge(bot_movestate_t *ms, aas_reachability_t *reach)
{
vec3_t dir, hordir, end, v;
float dist, speed;
bot_moveresult_t result;
BotClearMoveResult(&result);
//
VectorSubtract(reach->end, ms->origin, dir);
BotCheckBlocked(ms, dir, qtrue, &result);
//
VectorSubtract(reach->end, ms->origin, v);
v[2] = 0;
dist = VectorNormalize(v);
if (dist > 16) VectorMA(reach->end, 16, v, end);
else VectorCopy(reach->end, end);
//
if (!BotAirControl(ms->origin, ms->velocity, end, hordir, &speed))
{
//go straight to the reachability end
VectorCopy(dir, hordir);
hordir[2] = 0;
//
dist = VectorNormalize(hordir);
speed = 400;
} //end if
//
EA_Move(ms->client, hordir, speed);
VectorCopy(hordir, result.movedir);
//
return result;
} //end of the function BotFinishTravel_WalkOffLedge
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
/*
bot_moveresult_t BotTravel_Jump(bot_movestate_t *ms, aas_reachability_t *reach)
{
vec3_t hordir;
float dist, gapdist, speed, horspeed, sv_jumpvel;
bot_moveresult_t result;
BotClearMoveResult(&result);
//
sv_jumpvel = botlibglobals.sv_jumpvel->value;
//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);
//
speed = 350;
//
gapdist = BotGapDistance(ms, hordir, ms->entitynum);
//if pretty close to the start focus on the reachability end
if (dist < 50 || (gapdist && gapdist < 50))
{
//NOTE: using max speed (400) works best
//if (AAS_HorizontalVelocityForJump(sv_jumpvel, ms->origin, reach->end, &horspeed))
//{
// speed = horspeed * 400 / botlibglobals.sv_maxwalkvelocity->value;
//} //end if
hordir[0] = reach->end[0] - ms->origin[0];
hordir[1] = reach->end[1] - ms->origin[1];
VectorNormalize(hordir);
//elemantary action jump
EA_Jump(ms->client);
//
ms->jumpreach = ms->lastreachnum;
speed = 600;
} //end if
else
{
if (AAS_HorizontalVelocityForJump(sv_jumpvel, reach->start, reach->end, &horspeed))
{
speed = horspeed * 400 / botlibglobals.sv_maxwalkvelocity->value;
} //end if
} //end else
//elemantary action
EA_Move(ms->client, hordir, speed);
VectorCopy(hordir, result.movedir);
//
return result;
} //end of the function BotTravel_Jump*/
/*
bot_moveresult_t BotTravel_Jump(bot_movestate_t *ms, aas_reachability_t *reach)
{
vec3_t hordir, dir1, dir2, mins, maxs, start, end;
float dist1, dist2, speed;
bot_moveresult_t result;
bsp_trace_t trace;
BotClearMoveResult(&result);
//
hordir[0] = reach->start[0] - reach->end[0];
hordir[1] = reach->start[1] - reach->end[1];
hordir[2] = 0;
VectorNormalize(hordir);
//
VectorCopy(reach->start, start);
start[2] += 1;
//minus back the bouding box size plus 16
VectorMA(reach->start, 80, hordir, end);
//
AAS_PresenceTypeBoundingBox(PRESENCE_NORMAL, mins, maxs);
//check for solids
trace = AAS_Trace(start, mins, maxs, end, ms->entitynum, MASK_PLAYERSOLID);
if (trace.startsolid) VectorCopy(start, trace.endpos);
//check for a gap
for (dist1 = 0; dist1 < 80; dist1 += 10)
{
VectorMA(start, dist1+10, hordir, end);
end[2] += 1;
if (AAS_PointAreaNum(end) != ms->reachareanum) break;
} //end for
if (dist1 < 80) VectorMA(reach->start, dist1, hordir, trace.endpos);
// dist1 = BotGapDistance(start, hordir, ms->entitynum);
// if (dist1 && dist1 <= trace.fraction * 80) VectorMA(reach->start, dist1-20, hordir, trace.endpos);
//
VectorSubtract(ms->origin, reach->start, dir1);
dir1[2] = 0;
dist1 = VectorNormalize(dir1);
VectorSubtract(ms->origin, trace.endpos, dir2);
dir2[2] = 0;
dist2 = VectorNormalize(dir2);
//if just before the reachability start
if (DotProduct(dir1, dir2) < -0.8 || dist2 < 5)
{
//botimport.Print(PRT_MESSAGE, "between jump start and run to point\n");
hordir[0] = reach->end[0] - ms->origin[0];
hordir[1] = reach->end[1] - ms->origin[1];
hordir[2] = 0;
VectorNormalize(hordir);
//elemantary action jump
if (dist1 < 24) EA_Jump(ms->client);
else if (dist1 < 32) EA_DelayedJump(ms->client);
EA_Move(ms->client, hordir, 600);
//
ms->jumpreach = ms->lastreachnum;
} //end if
else
{
//botimport.Print(PRT_MESSAGE, "going towards run to point\n");
hordir[0] = trace.endpos[0] - ms->origin[0];
hordir[1] = trace.endpos[1] - ms->origin[1];
hordir[2] = 0;
VectorNormalize(hordir);
//
if (dist2 > 80) dist2 = 80;
speed = 400 - (400 - 5 * dist2);
EA_Move(ms->client, hordir, speed);
} //end else
VectorCopy(hordir, result.movedir);
//
return result;
} //end of the function BotTravel_Jump*/
//*
bot_moveresult_t BotTravel_Jump(bot_movestate_t *ms, aas_reachability_t *reach)
{
vec3_t hordir, dir1, dir2, start, end, runstart;
// vec3_t runstart, dir1, dir2, hordir;
float dist1, dist2, speed;
bot_moveresult_t result;
BotClearMoveResult(&result);
//
AAS_JumpReachRunStart(reach, runstart);
//*
hordir[0] = runstart[0] - reach->start[0];
hordir[1] = runstart[1] - reach->start[1];
hordir[2] = 0;
VectorNormalize(hordir);
//
VectorCopy(reach->start, start);
start[2] += 1;
VectorMA(reach->start, 80, hordir, runstart);
//check for a gap
for (dist1 = 0; dist1 < 80; dist1 += 10)
{
VectorMA(start, dist1+10, hordir, end);
end[2] += 1;
if (AAS_PointAreaNum(end) != ms->reachareanum) break;
} //end for
if (dist1 < 80) VectorMA(reach->start, dist1, hordir, runstart);
//
VectorSubtract(ms->origin, reach->start, dir1);
dir1[2] = 0;
dist1 = VectorNormalize(dir1);
VectorSubtract(ms->origin, runstart, dir2);
dir2[2] = 0;
dist2 = VectorNormalize(dir2);
//if just before the reachability start
if (DotProduct(dir1, dir2) < -0.8 || dist2 < 5)
{
// botimport.Print(PRT_MESSAGE, "between jump start and run start point\n");
hordir[0] = reach->end[0] - ms->origin[0];
hordir[1] = reach->end[1] - ms->origin[1];
hordir[2] = 0;
VectorNormalize(hordir);
//elemantary action jump
if (dist1 < 24) EA_Jump(ms->client);
else if (dist1 < 32) EA_DelayedJump(ms->client);
EA_Move(ms->client, hordir, 600);
//
ms->jumpreach = ms->lastreachnum;
} //end if
else
{
// botimport.Print(PRT_MESSAGE, "going towards run start point\n");
hordir[0] = runstart[0] - ms->origin[0];
hordir[1] = runstart[1] - ms->origin[1];
hordir[2] = 0;
VectorNormalize(hordir);
//
if (dist2 > 80) dist2 = 80;
speed = 400 - (400 - 5 * dist2);
EA_Move(ms->client, hordir, speed);
} //end else
VectorCopy(hordir, result.movedir);
//
return result;
} //end of the function BotTravel_Jump*/
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
bot_moveresult_t BotFinishTravel_Jump(bot_movestate_t *ms, aas_reachability_t *reach)
{
vec3_t hordir, hordir2;
float speed, dist;
bot_moveresult_t result;
BotClearMoveResult(&result);
//if not jumped yet
if (!ms->jumpreach) return result;
//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);
//
hordir2[0] = reach->end[0] - reach->start[0];
hordir2[1] = reach->end[1] - reach->start[1];
hordir2[2] = 0;
VectorNormalize(hordir2);
//
if (DotProduct(hordir, hordir2) < -0.5 && dist < 24) return result;
//always use max speed when traveling through the air
speed = 800;
//
EA_Move(ms->client, hordir, speed);
VectorCopy(hordir, result.movedir);
//
return result;
} //end of the function BotFinishTravel_Jump
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
bot_moveresult_t BotTravel_Ladder(bot_movestate_t *ms, aas_reachability_t *reach)
{
//float dist, speed;
vec3_t dir, viewdir;//, hordir;
vec3_t origin = {0, 0, 0};
// vec3_t up = {0, 0, 1};
bot_moveresult_t result;
BotClearMoveResult(&result);
//
// if ((ms->moveflags & MFL_AGAINSTLADDER))
//NOTE: not a good idea for ladders starting in water
// || !(ms->moveflags & MFL_ONGROUND))
{
//botimport.Print(PRT_MESSAGE, "against ladder or not on ground\n");
VectorSubtract(reach->end, ms->origin, dir);
VectorNormalize(dir);
//set the ideal view angles, facing the ladder up or down
viewdir[0] = dir[0];
viewdir[1] = dir[1];
viewdir[2] = 3 * dir[2];
Vector2Angles(viewdir, result.ideal_viewangles);
//elemantary action
EA_Move(ms->client, origin, 0);
EA_MoveForward(ms->client);
//set movement view flag so the AI can see the view is focussed
result.flags |= MOVERESULT_MOVEMENTVIEW;
} //end if
/* else
{
//botimport.Print(PRT_MESSAGE, "moving towards ladder\n");
VectorSubtract(reach->end, ms->origin, dir);
//make sure the horizontal movement is large anough
VectorCopy(dir, hordir);
hordir[2] = 0;
dist = VectorNormalize
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -