📄 be_aas_move.c
字号:
currentspeed = DotProduct(velocity, wishdir);
addspeed = wishspeed - currentspeed;
if (addspeed <= 0) {
return;
}
accelspeed = accel*frametime*wishspeed;
if (accelspeed > addspeed) {
accelspeed = addspeed;
}
for (i=0 ; i<3 ; i++) {
velocity[i] += accelspeed*wishdir[i];
}
} //end of the function AAS_Accelerate
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
void AAS_AirControl(vec3_t start, vec3_t end, vec3_t velocity, vec3_t cmdmove)
{
vec3_t dir;
VectorSubtract(end, start, dir);
} //end of the function AAS_AirControl
//===========================================================================
// applies ground friction to the given velocity
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
void AAS_ApplyFriction(vec3_t vel, float friction, float stopspeed,
float frametime)
{
float speed, control, newspeed;
//horizontal speed
speed = sqrt(vel[0] * vel[0] + vel[1] * vel[1]);
if (speed)
{
control = speed < stopspeed ? stopspeed : speed;
newspeed = speed - frametime * control * friction;
if (newspeed < 0) newspeed = 0;
newspeed /= speed;
vel[0] *= newspeed;
vel[1] *= newspeed;
} //end if
} //end of the function AAS_ApplyFriction
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
int AAS_ClipToBBox(aas_trace_t *trace, vec3_t start, vec3_t end, int presencetype, vec3_t mins, vec3_t maxs)
{
int i, j, side;
float front, back, frac, planedist;
vec3_t bboxmins, bboxmaxs, absmins, absmaxs, dir, mid;
AAS_PresenceTypeBoundingBox(presencetype, bboxmins, bboxmaxs);
VectorSubtract(mins, bboxmaxs, absmins);
VectorSubtract(maxs, bboxmins, absmaxs);
//
VectorCopy(end, trace->endpos);
trace->fraction = 1;
for (i = 0; i < 3; i++)
{
if (start[i] < absmins[i] && end[i] < absmins[i]) return qfalse;
if (start[i] > absmaxs[i] && end[i] > absmaxs[i]) return qfalse;
} //end for
//check bounding box collision
VectorSubtract(end, start, dir);
frac = 1;
for (i = 0; i < 3; i++)
{
//get plane to test collision with for the current axis direction
if (dir[i] > 0) planedist = absmins[i];
else planedist = absmaxs[i];
//calculate collision fraction
front = start[i] - planedist;
back = end[i] - planedist;
frac = front / (front-back);
//check if between bounding planes of next axis
side = i + 1;
if (side > 2) side = 0;
mid[side] = start[side] + dir[side] * frac;
if (mid[side] > absmins[side] && mid[side] < absmaxs[side])
{
//check if between bounding planes of next axis
side++;
if (side > 2) side = 0;
mid[side] = start[side] + dir[side] * frac;
if (mid[side] > absmins[side] && mid[side] < absmaxs[side])
{
mid[i] = planedist;
break;
} //end if
} //end if
} //end for
//if there was a collision
if (i != 3)
{
trace->startsolid = qfalse;
trace->fraction = frac;
trace->ent = 0;
trace->planenum = 0;
trace->area = 0;
trace->lastarea = 0;
//trace endpos
for (j = 0; j < 3; j++) trace->endpos[j] = start[j] + dir[j] * frac;
return qtrue;
} //end if
return qfalse;
} //end of the function AAS_ClipToBBox
//===========================================================================
// predicts the movement
// assumes regular bounding box sizes
// NOTE: out of water jumping is not included
// NOTE: grappling hook is not included
//
// Parameter: origin : origin to start with
// presencetype : presence type to start with
// velocity : velocity to start with
// cmdmove : client command movement
// cmdframes : number of frame cmdmove is valid
// maxframes : maximum number of predicted frames
// frametime : duration of one predicted frame
// stopevent : events that stop the prediction
// stopareanum : stop as soon as entered this area
// Returns: aas_clientmove_t
// Changes Globals: -
//===========================================================================
int AAS_ClientMovementPrediction(struct aas_clientmove_s *move,
int entnum, vec3_t origin,
int presencetype, int onground,
vec3_t velocity, vec3_t cmdmove,
int cmdframes,
int maxframes, float frametime,
int stopevent, int stopareanum,
vec3_t mins, vec3_t maxs, int visualize)
{
float phys_friction, phys_stopspeed, phys_gravity, phys_waterfriction;
float phys_watergravity;
float phys_walkaccelerate, phys_airaccelerate, phys_swimaccelerate;
float phys_maxwalkvelocity, phys_maxcrouchvelocity, phys_maxswimvelocity;
float phys_maxstep, phys_maxsteepness, phys_jumpvel, friction;
float gravity, delta, maxvel, wishspeed, accelerate;
//float velchange, newvel;
int n, i, j, pc, step, swimming, ax, crouch, event, jump_frame, areanum;
int areas[20], numareas;
vec3_t points[20];
vec3_t org, end, feet, start, stepend, lastorg, wishdir;
vec3_t frame_test_vel, old_frame_test_vel, left_test_vel;
vec3_t up = {0, 0, 1};
aas_plane_t *plane, *plane2;
aas_trace_t trace, steptrace;
if (frametime <= 0) frametime = 0.1f;
//
phys_friction = aassettings.phys_friction;
phys_stopspeed = aassettings.phys_stopspeed;
phys_gravity = aassettings.phys_gravity;
phys_waterfriction = aassettings.phys_waterfriction;
phys_watergravity = aassettings.phys_watergravity;
phys_maxwalkvelocity = aassettings.phys_maxwalkvelocity;// * frametime;
phys_maxcrouchvelocity = aassettings.phys_maxcrouchvelocity;// * frametime;
phys_maxswimvelocity = aassettings.phys_maxswimvelocity;// * frametime;
phys_walkaccelerate = aassettings.phys_walkaccelerate;
phys_airaccelerate = aassettings.phys_airaccelerate;
phys_swimaccelerate = aassettings.phys_swimaccelerate;
phys_maxstep = aassettings.phys_maxstep;
phys_maxsteepness = aassettings.phys_maxsteepness;
phys_jumpvel = aassettings.phys_jumpvel * frametime;
//
Com_Memset(move, 0, sizeof(aas_clientmove_t));
Com_Memset(&trace, 0, sizeof(aas_trace_t));
//start at the current origin
VectorCopy(origin, org);
org[2] += 0.25;
//velocity to test for the first frame
VectorScale(velocity, frametime, frame_test_vel);
//
jump_frame = -1;
//predict a maximum of 'maxframes' ahead
for (n = 0; n < maxframes; n++)
{
swimming = AAS_Swimming(org);
//get gravity depending on swimming or not
gravity = swimming ? phys_watergravity : phys_gravity;
//apply gravity at the START of the frame
frame_test_vel[2] = frame_test_vel[2] - (gravity * 0.1 * frametime);
//if on the ground or swimming
if (onground || swimming)
{
friction = swimming ? phys_friction : phys_waterfriction;
//apply friction
VectorScale(frame_test_vel, 1/frametime, frame_test_vel);
AAS_ApplyFriction(frame_test_vel, friction, phys_stopspeed, frametime);
VectorScale(frame_test_vel, frametime, frame_test_vel);
} //end if
crouch = qfalse;
//apply command movement
if (n < cmdframes)
{
ax = 0;
maxvel = phys_maxwalkvelocity;
accelerate = phys_airaccelerate;
VectorCopy(cmdmove, wishdir);
if (onground)
{
if (cmdmove[2] < -300)
{
crouch = qtrue;
maxvel = phys_maxcrouchvelocity;
} //end if
//if not swimming and upmove is positive then jump
if (!swimming && cmdmove[2] > 1)
{
//jump velocity minus the gravity for one frame + 5 for safety
frame_test_vel[2] = phys_jumpvel - (gravity * 0.1 * frametime) + 5;
jump_frame = n;
//jumping so air accelerate
accelerate = phys_airaccelerate;
} //end if
else
{
accelerate = phys_walkaccelerate;
} //end else
ax = 2;
} //end if
if (swimming)
{
maxvel = phys_maxswimvelocity;
accelerate = phys_swimaccelerate;
ax = 3;
} //end if
else
{
wishdir[2] = 0;
} //end else
//
wishspeed = VectorNormalize(wishdir);
if (wishspeed > maxvel) wishspeed = maxvel;
VectorScale(frame_test_vel, 1/frametime, frame_test_vel);
AAS_Accelerate(frame_test_vel, frametime, wishdir, wishspeed, accelerate);
VectorScale(frame_test_vel, frametime, frame_test_vel);
/*
for (i = 0; i < ax; i++)
{
velchange = (cmdmove[i] * frametime) - frame_test_vel[i];
if (velchange > phys_maxacceleration) velchange = phys_maxacceleration;
else if (velchange < -phys_maxacceleration) velchange = -phys_maxacceleration;
newvel = frame_test_vel[i] + velchange;
//
if (frame_test_vel[i] <= maxvel && newvel > maxvel) frame_test_vel[i] = maxvel;
else if (frame_test_vel[i] >= -maxvel && newvel < -maxvel) frame_test_vel[i] = -maxvel;
else frame_test_vel[i] = newvel;
} //end for
*/
} //end if
if (crouch)
{
presencetype = PRESENCE_CROUCH;
} //end if
else if (presencetype == PRESENCE_CROUCH)
{
if (AAS_PointPresenceType(org) & PRESENCE_NORMAL)
{
presencetype = PRESENCE_NORMAL;
} //end if
} //end else
//save the current origin
VectorCopy(org, lastorg);
//move linear during one frame
VectorCopy(frame_test_vel, left_test_vel);
j = 0;
do
{
VectorAdd(org, left_test_vel, end);
//trace a bounding box
trace = AAS_TraceClientBBox(org, end, presencetype, entnum);
//
//#ifdef AAS_MOVE_DEBUG
if (visualize)
{
if (trace.startsolid) botimport.Print(PRT_MESSAGE, "PredictMovement: start solid\n");
AAS_DebugLine(org, trace.endpos, LINECOLOR_RED);
} //end if
//#endif //AAS_MOVE_DEBUG
//
if (stopevent & (SE_ENTERAREA|SE_TOUCHJUMPPAD|SE_TOUCHTELEPORTER|SE_TOUCHCLUSTERPORTAL))
{
numareas = AAS_TraceAreas(org, trace.endpos, areas, points, 20);
for (i = 0; i < numareas; i++)
{
if (stopevent & SE_ENTERAREA)
{
if (areas[i] == stopareanum)
{
VectorCopy(points[i], move->endpos);
VectorScale(frame_test_vel, 1/frametime, move->velocity);
move->endarea = areas[i];
move->trace = trace;
move->stopevent = SE_ENTERAREA;
move->presencetype = presencetype;
move->endcontents = 0;
move->time = n * frametime;
move->frames = n;
return qtrue;
} //end if
} //end if
//NOTE: if not the first frame
if ((stopevent & SE_TOUCHJUMPPAD) && n)
{
if (aasworld.areasettings[areas[i]].contents & AREACONTENTS_JUMPPAD)
{
VectorCopy(points[i], move->endpos);
VectorScale(frame_test_vel, 1/frametime, move->velocity);
move->endarea = areas[i];
move->trace = trace;
move->stopevent = SE_TOUCHJUMPPAD;
move->presencetype = presencetype;
move->endcontents = 0;
move->time = n * frametime;
move->frames = n;
return qtrue;
} //end if
} //end if
if (stopevent & SE_TOUCHTELEPORTER)
{
if (aasworld.areasettings[areas[i]].contents & AREACONTENTS_TELEPORTER)
{
VectorCopy(points[i], move->endpos);
move->endarea = areas[i];
VectorScale(frame_test_vel, 1/frametime, move->velocity);
move->trace = trace;
move->stopevent = SE_TOUCHTELEPORTER;
move->presencetype = presencetype;
move->endcontents = 0;
move->time = n * frametime;
move->frames = n;
return qtrue;
} //end if
} //end if
if (stopevent & SE_TOUCHCLUSTERPORTAL)
{
if (aasworld.areasettings[areas[i]].contents & AREACONTENTS_CLUSTERPORTAL)
{
VectorCopy(points[i], move->endpos);
move->endarea = areas[i];
VectorScale(frame_test_vel, 1/frametime, move->velocity);
move->trace = trace;
move->stopevent = SE_TOUCHCLUSTERPORTAL;
move->presencetype = presencetype;
move->endcontents = 0;
move->time = n * frametime;
move->frames = n;
return qtrue;
} //end if
} //end if
} //end for
} //end if
//
if (stopevent & SE_HITBOUNDINGBOX)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -