📄 bg_pmove.c
字号:
}
PM_Accelerate (wishdir, wishspeed, pm_wateraccelerate);
// make sure we can go up slopes easily under water
if ( pml.groundPlane && DotProduct( pm->ps->velocity, pml.groundTrace.plane.normal ) < 0 ) {
vel = VectorLength(pm->ps->velocity);
// slide along the ground plane
PM_ClipVelocity (pm->ps->velocity, pml.groundTrace.plane.normal,
pm->ps->velocity, OVERCLIP );
VectorNormalize(pm->ps->velocity);
VectorScale(pm->ps->velocity, vel, pm->ps->velocity);
}
PM_SlideMove( qfalse );
}
#ifdef MISSIONPACK
/*
===================
PM_InvulnerabilityMove
Only with the invulnerability powerup
===================
*/
static void PM_InvulnerabilityMove( void ) {
pm->cmd.forwardmove = 0;
pm->cmd.rightmove = 0;
pm->cmd.upmove = 0;
VectorClear(pm->ps->velocity);
}
#endif
/*
===================
PM_FlyMove
Only with the flight powerup
===================
*/
static void PM_FlyMove( void ) {
int i;
vec3_t wishvel;
float wishspeed;
vec3_t wishdir;
float scale;
// normal slowdown
PM_Friction ();
scale = PM_CmdScale( &pm->cmd );
//
// user intentions
//
if ( !scale ) {
wishvel[0] = 0;
wishvel[1] = 0;
wishvel[2] = 0;
} else {
for (i=0 ; i<3 ; i++) {
wishvel[i] = scale * pml.forward[i]*pm->cmd.forwardmove + scale * pml.right[i]*pm->cmd.rightmove;
}
wishvel[2] += scale * pm->cmd.upmove;
}
VectorCopy (wishvel, wishdir);
wishspeed = VectorNormalize(wishdir);
PM_Accelerate (wishdir, wishspeed, pm_flyaccelerate);
PM_StepSlideMove( qfalse );
}
/*
===================
PM_AirMove
===================
*/
static void PM_AirMove( void ) {
int i;
vec3_t wishvel;
float fmove, smove;
vec3_t wishdir;
float wishspeed;
float scale;
usercmd_t cmd;
PM_Friction();
fmove = pm->cmd.forwardmove;
smove = pm->cmd.rightmove;
cmd = pm->cmd;
scale = PM_CmdScale( &cmd );
// set the movementDir so clients can rotate the legs for strafing
PM_SetMovementDir();
// project moves down to flat plane
pml.forward[2] = 0;
pml.right[2] = 0;
VectorNormalize (pml.forward);
VectorNormalize (pml.right);
for ( i = 0 ; i < 2 ; i++ ) {
wishvel[i] = pml.forward[i]*fmove + pml.right[i]*smove;
}
wishvel[2] = 0;
VectorCopy (wishvel, wishdir);
wishspeed = VectorNormalize(wishdir);
wishspeed *= scale;
// not on ground, so little effect on velocity
PM_Accelerate (wishdir, wishspeed, pm_airaccelerate);
// we may have a ground plane that is very steep, even
// though we don't have a groundentity
// slide along the steep plane
if ( pml.groundPlane ) {
PM_ClipVelocity (pm->ps->velocity, pml.groundTrace.plane.normal,
pm->ps->velocity, OVERCLIP );
}
#if 0
//ZOID: If we are on the grapple, try stair-stepping
//this allows a player to use the grapple to pull himself
//over a ledge
if (pm->ps->pm_flags & PMF_GRAPPLE_PULL)
PM_StepSlideMove ( qtrue );
else
PM_SlideMove ( qtrue );
#endif
PM_StepSlideMove ( qtrue );
}
/*
===================
PM_GrappleMove
===================
*/
static void PM_GrappleMove( void ) {
vec3_t vel, v;
float vlen;
VectorScale(pml.forward, -16, v);
VectorAdd(pm->ps->grapplePoint, v, v);
VectorSubtract(v, pm->ps->origin, vel);
vlen = VectorLength(vel);
VectorNormalize( vel );
if (vlen <= 100)
VectorScale(vel, 10 * vlen, vel);
else
VectorScale(vel, 800, vel);
VectorCopy(vel, pm->ps->velocity);
pml.groundPlane = qfalse;
}
/*
===================
PM_WalkMove
===================
*/
static void PM_WalkMove( void ) {
int i;
vec3_t wishvel;
float fmove, smove;
vec3_t wishdir;
float wishspeed;
float scale;
usercmd_t cmd;
float accelerate;
float vel;
if ( pm->waterlevel > 2 && DotProduct( pml.forward, pml.groundTrace.plane.normal ) > 0 ) {
// begin swimming
PM_WaterMove();
return;
}
if ( PM_CheckJump () ) {
// jumped away
if ( pm->waterlevel > 1 ) {
PM_WaterMove();
} else {
PM_AirMove();
}
return;
}
PM_Friction ();
fmove = pm->cmd.forwardmove;
smove = pm->cmd.rightmove;
cmd = pm->cmd;
scale = PM_CmdScale( &cmd );
// set the movementDir so clients can rotate the legs for strafing
PM_SetMovementDir();
// project moves down to flat plane
pml.forward[2] = 0;
pml.right[2] = 0;
// project the forward and right directions onto the ground plane
PM_ClipVelocity (pml.forward, pml.groundTrace.plane.normal, pml.forward, OVERCLIP );
PM_ClipVelocity (pml.right, pml.groundTrace.plane.normal, pml.right, OVERCLIP );
//
VectorNormalize (pml.forward);
VectorNormalize (pml.right);
for ( i = 0 ; i < 3 ; i++ ) {
wishvel[i] = pml.forward[i]*fmove + pml.right[i]*smove;
}
// when going up or down slopes the wish velocity should Not be zero
// wishvel[2] = 0;
VectorCopy (wishvel, wishdir);
wishspeed = VectorNormalize(wishdir);
wishspeed *= scale;
// clamp the speed lower if ducking
if ( pm->ps->pm_flags & PMF_DUCKED ) {
if ( wishspeed > pm->ps->speed * pm_duckScale ) {
wishspeed = pm->ps->speed * pm_duckScale;
}
}
// clamp the speed lower if wading or walking on the bottom
if ( pm->waterlevel ) {
float waterScale;
waterScale = pm->waterlevel / 3.0;
waterScale = 1.0 - ( 1.0 - pm_swimScale ) * waterScale;
if ( wishspeed > pm->ps->speed * waterScale ) {
wishspeed = pm->ps->speed * waterScale;
}
}
// when a player gets hit, they temporarily lose
// full control, which allows them to be moved a bit
if ( ( pml.groundTrace.surfaceFlags & SURF_SLICK ) || pm->ps->pm_flags & PMF_TIME_KNOCKBACK ) {
accelerate = pm_airaccelerate;
} else {
accelerate = pm_accelerate;
}
PM_Accelerate (wishdir, wishspeed, accelerate);
//Com_Printf("velocity = %1.1f %1.1f %1.1f\n", pm->ps->velocity[0], pm->ps->velocity[1], pm->ps->velocity[2]);
//Com_Printf("velocity1 = %1.1f\n", VectorLength(pm->ps->velocity));
if ( ( pml.groundTrace.surfaceFlags & SURF_SLICK ) || pm->ps->pm_flags & PMF_TIME_KNOCKBACK ) {
pm->ps->velocity[2] -= pm->ps->gravity * pml.frametime;
} else {
// don't reset the z velocity for slopes
// pm->ps->velocity[2] = 0;
}
vel = VectorLength(pm->ps->velocity);
// slide along the ground plane
PM_ClipVelocity (pm->ps->velocity, pml.groundTrace.plane.normal,
pm->ps->velocity, OVERCLIP );
// don't decrease velocity when going up or down a slope
VectorNormalize(pm->ps->velocity);
VectorScale(pm->ps->velocity, vel, pm->ps->velocity);
// don't do anything if standing still
if (!pm->ps->velocity[0] && !pm->ps->velocity[1]) {
return;
}
PM_StepSlideMove( qfalse );
//Com_Printf("velocity2 = %1.1f\n", VectorLength(pm->ps->velocity));
}
/*
==============
PM_DeadMove
==============
*/
static void PM_DeadMove( void ) {
float forward;
if ( !pml.walking ) {
return;
}
// extra friction
forward = VectorLength (pm->ps->velocity);
forward -= 20;
if ( forward <= 0 ) {
VectorClear (pm->ps->velocity);
} else {
VectorNormalize (pm->ps->velocity);
VectorScale (pm->ps->velocity, forward, pm->ps->velocity);
}
}
/*
===============
PM_NoclipMove
===============
*/
static void PM_NoclipMove( void ) {
float speed, drop, friction, control, newspeed;
int i;
vec3_t wishvel;
float fmove, smove;
vec3_t wishdir;
float wishspeed;
float scale;
pm->ps->viewheight = DEFAULT_VIEWHEIGHT;
// friction
speed = VectorLength (pm->ps->velocity);
if (speed < 1)
{
VectorCopy (vec3_origin, pm->ps->velocity);
}
else
{
drop = 0;
friction = pm_friction*1.5; // extra friction
control = speed < pm_stopspeed ? pm_stopspeed : speed;
drop += control*friction*pml.frametime;
// scale the velocity
newspeed = speed - drop;
if (newspeed < 0)
newspeed = 0;
newspeed /= speed;
VectorScale (pm->ps->velocity, newspeed, pm->ps->velocity);
}
// accelerate
scale = PM_CmdScale( &pm->cmd );
fmove = pm->cmd.forwardmove;
smove = pm->cmd.rightmove;
for (i=0 ; i<3 ; i++)
wishvel[i] = pml.forward[i]*fmove + pml.right[i]*smove;
wishvel[2] += pm->cmd.upmove;
VectorCopy (wishvel, wishdir);
wishspeed = VectorNormalize(wishdir);
wishspeed *= scale;
PM_Accelerate( wishdir, wishspeed, pm_accelerate );
// move
VectorMA (pm->ps->origin, pml.frametime, pm->ps->velocity, pm->ps->origin);
}
//============================================================================
/*
================
PM_FootstepForSurface
Returns an event number apropriate for the groundsurface
================
*/
static int PM_FootstepForSurface( void ) {
if ( pml.groundTrace.surfaceFlags & SURF_NOSTEPS ) {
return 0;
}
if ( pml.groundTrace.surfaceFlags & SURF_METALSTEPS ) {
return EV_FOOTSTEP_METAL;
}
return EV_FOOTSTEP;
}
/*
=================
PM_CrashLand
Check for hard landings that generate sound events
=================
*/
static void PM_CrashLand( void ) {
float delta;
float dist;
float vel, acc;
float t;
float a, b, c, den;
// decide which landing animation to use
if ( pm->ps->pm_flags & PMF_BACKWARDS_JUMP ) {
PM_ForceLegsAnim( LEGS_LANDB );
} else {
PM_ForceLegsAnim( LEGS_LAND );
}
pm->ps->legsTimer = TIMER_LAND;
// calculate the exact velocity on landing
dist = pm->ps->origin[2] - pml.previous_origin[2];
vel = pml.previous_velocity[2];
acc = -pm->ps->gravity;
a = acc / 2;
b = vel;
c = -dist;
den = b * b - 4 * a * c;
if ( den < 0 ) {
return;
}
t = (-b - sqrt( den ) ) / ( 2 * a );
delta = vel + t * acc;
delta = delta*delta * 0.0001;
// ducking while falling doubles damage
if ( pm->ps->pm_flags & PMF_DUCKED ) {
delta *= 2;
}
// never take falling damage if completely underwater
if ( pm->waterlevel == 3 ) {
return;
}
// reduce falling damage if there is standing water
if ( pm->waterlevel == 2 ) {
delta *= 0.25;
}
if ( pm->waterlevel == 1 ) {
delta *= 0.5;
}
if ( delta < 1 ) {
return;
}
// create a local entity event to play the sound
// SURF_NODAMAGE is used for bounce pads where you don't ever
// want to take damage or play a crunch sound
if ( !(pml.groundTrace.surfaceFlags & SURF_NODAMAGE) ) {
if ( delta > 60 ) {
PM_AddEvent( EV_FALL_FAR );
} else if ( delta > 40 ) {
// this is a pain grunt, so don't play it if dead
if ( pm->ps->stats[STAT_HEALTH] > 0 ) {
PM_AddEvent( EV_FALL_MEDIUM );
}
} else if ( delta > 7 ) {
PM_AddEvent( EV_FALL_SHORT );
} else {
PM_AddEvent( PM_FootstepForSurface() );
}
}
// start footstep cycle over
pm->ps->bobCycle = 0;
}
/*
=============
PM_CheckStuck
=============
*/
/*
void PM_CheckStuck(void) {
trace_t trace;
pm->trace (&trace, pm->ps->origin, pm->mins, pm->maxs, pm->ps->origin, pm->ps->clientNum, pm->tracemask);
if (trace.allsolid) {
//int shit = qtrue;
}
}
*/
/*
=============
PM_CorrectAllSolid
=============
*/
static int PM_CorrectAllSolid( trace_t *trace ) {
int i, j, k;
vec3_t point;
if ( pm->debugLevel ) {
Com_Printf("%i:allsolid\n", c_pmove);
}
// jitter around
for (i = -1; i <= 1; i++) {
for (j = -1; j <= 1; j++) {
for (k = -1; k <= 1; k++) {
VectorCopy(pm->ps->origin, point);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -