diff options
Diffstat (limited to 'src/game/bg_pmove.c')
-rw-r--r-- | src/game/bg_pmove.c | 215 |
1 files changed, 176 insertions, 39 deletions
diff --git a/src/game/bg_pmove.c b/src/game/bg_pmove.c index 80ca7715..e7915b96 100644 --- a/src/game/bg_pmove.c +++ b/src/game/bg_pmove.c @@ -260,9 +260,15 @@ static void PM_Friction( void ) if( !( pm->ps->pm_flags & PMF_TIME_KNOCKBACK ) ) { float stopSpeed = BG_FindStopSpeedForClass( pm->ps->stats[ STAT_PCLASS ] ); + float friction = BG_FindFrictionForClass( pm->ps->stats[ STAT_PCLASS ] ); + + // when landing a dodge, extra friction + if( pm->ps->pm_flags & PMF_TIME_LAND ) + friction *= 1.f + HUMAN_LAND_FRICTION * + pm->ps->pm_time / HUMAN_DODGE_TIMEOUT; control = speed < stopSpeed ? stopSpeed : speed; - drop += control * BG_FindFrictionForClass( pm->ps->stats[ STAT_PCLASS ] ) * pml.frametime; + drop += control * friction * pml.frametime; } } } @@ -387,11 +393,19 @@ static float PM_CmdScale( usercmd_t *cmd ) else modifier *= CREEP_MODIFIER; } + if( pm->ps->stats[ STAT_STATE ] & SS_POISONCLOUDED ) + { + if( BG_InventoryContainsUpgrade( UP_LIGHTARMOUR, pm->ps->stats ) || + BG_InventoryContainsUpgrade( UP_BATTLESUIT, pm->ps->stats ) ) + modifier *= PCLOUD_ARMOUR_MODIFIER; + else + modifier *= PCLOUD_MODIFIER; + } } if( pm->ps->weapon == WP_ALEVEL4 && pm->ps->pm_flags & PMF_CHARGE ) - modifier *= ( 1.0f + ( pm->ps->stats[ STAT_MISC ] / (float)LEVEL4_CHARGE_TIME ) * - ( LEVEL4_CHARGE_SPEED - 1.0f ) ); + modifier *= ( 1.0f + ( pm->ps->stats[ STAT_MISC ] / + (float)LEVEL4_TRAMPLE_CHARGE_MAX ) * ( LEVEL4_TRAMPLE_SPEED - 1.0f ) ); //slow player if charging up for a pounce if( ( pm->ps->weapon == WP_ALEVEL3 || pm->ps->weapon == WP_ALEVEL3_UPG ) && @@ -510,12 +524,22 @@ static qboolean PM_CheckPounce( void ) pm->ps->weapon != WP_ALEVEL3_UPG ) return qfalse; + // we were pouncing, but we've landed + if( pm->ps->groundEntityNum != ENTITYNUM_NONE && + ( pm->ps->pm_flags & PMF_CHARGE ) ) + { + pm->ps->pm_flags &= ~PMF_CHARGE; + return qfalse; + } + + // we're building up for a pounce if( pm->cmd.buttons & BUTTON_ATTACK2 ) { pm->ps->pm_flags &= ~PMF_CHARGE; return qfalse; } + // already a pounce in progress if( pm->ps->pm_flags & PMF_CHARGE ) return qfalse; @@ -660,6 +684,10 @@ static qboolean PM_CheckJump( void ) { vec3_t normal; + // don't rejump after a dodge or jump + if( pm->ps->pm_flags & PMF_TIME_LAND ) + return qfalse; + if( BG_FindJumpMagnitudeForClass( pm->ps->stats[ STAT_PCLASS ] ) == 0.0f ) return qfalse; @@ -709,7 +737,7 @@ static qboolean PM_CheckJump( void ) // take some stamina off if( pm->ps->stats[ STAT_PTEAM ] == PTE_HUMANS ) - pm->ps->stats[ STAT_STAMINA ] -= 500; + pm->ps->stats[ STAT_STAMINA ] -= STAMINA_JUMP_TAKE; pm->ps->groundEntityNum = ENTITYNUM_NONE; @@ -789,6 +817,108 @@ static qboolean PM_CheckWaterJump( void ) return qtrue; } +/* +================== +PM_CheckDodge + +Starts a human dodge or sprint +================== +*/ +static qboolean PM_CheckDodge( void ) +{ + vec3_t right, forward, velocity = { 0.0f, 0.0f, 0.0f }; + float jump; + int i; + + if( pm->ps->stats[ STAT_PTEAM ] != PTE_HUMANS ) + return qfalse; + + // Landed a dodge + if( ( pm->ps->pm_flags & PMF_CHARGE ) && + pm->ps->groundEntityNum != ENTITYNUM_NONE ) + { + pm->ps->pm_flags = ( pm->ps->pm_flags & ~PMF_CHARGE ) | PMF_TIME_LAND; + pm->ps->pm_time = HUMAN_DODGE_TIMEOUT; + } + + // Reasons to stop a sprint + if( pm->cmd.forwardmove <= 64 || + pm->cmd.upmove < 0 || + pm->ps->pm_type != PM_NORMAL ) + pm->ps->stats[ STAT_STATE ] &= ~SS_SPEEDBOOST; + + // Reasons why we can't start a dodge or sprint + if( !( pm->cmd.buttons & BUTTON_DODGE ) || + pm->ps->pm_type != PM_NORMAL || + ( pm->ps->pm_flags & PMF_CROUCH_HELD ) || + pm->ps->stats[ STAT_STAMINA ] < 0 ) + return qfalse; + + // Start a sprint instead of forward leaps + if( pm->cmd.forwardmove > 0 ) + { + if( pm->cmd.buttons & BUTTON_WALKING ) + return qfalse; + pm->ps->stats[ STAT_STATE ] |= SS_SPEEDBOOST; + return qfalse; + } + + // Reasons why we can't start a dodge only + if( pm->ps->pm_flags & ( PMF_TIME_LAND | PMF_CHARGE ) || + pm->ps->groundEntityNum == ENTITYNUM_NONE ) + return qfalse; + + // Dodge direction specified with movement keys + if( ( !pm->cmd.rightmove && !pm->cmd.forwardmove ) || pm->cmd.upmove ) + return qfalse; + AngleVectors( pm->ps->viewangles, NULL, right, NULL ); + forward[ 0 ] = -right[ 1 ]; + forward[ 1 ] = right[ 0 ]; + forward[ 2 ] = 0.0f; + + // Dodge magnitude is based on the jump magnitude scaled by the modifiers + jump = BG_FindJumpMagnitudeForClass( pm->ps->stats[ STAT_PCLASS ] ); + if( pm->cmd.rightmove && pm->cmd.forwardmove ) + jump *= ( 0.5f * M_SQRT2 ); + + // The dodge sets minimum velocity + if( pm->cmd.rightmove ) + { + if( pm->cmd.rightmove < 0 ) + VectorNegate( right, right ); + VectorMA( velocity, jump * HUMAN_DODGE_SIDE_MODIFIER, right, velocity ); + } + if( pm->cmd.forwardmove ) + { + if( pm->cmd.forwardmove < 0 ) + VectorNegate( forward, forward ); + VectorMA( velocity, jump * HUMAN_DODGE_SIDE_MODIFIER, forward, velocity ); + } + velocity[ 2 ] = jump * HUMAN_DODGE_UP_MODIFIER; + + // Make sure client has minimum velocity + for( i = 0; i < 3; i++ ) + { + if( ( velocity[ i ] < 0.0f && + pm->ps->velocity[ i ] > velocity[ i ] ) || + ( velocity[ i ] > 0.0f && + pm->ps->velocity[ i ] < velocity[ i ] ) ) + pm->ps->velocity[ i ] = velocity[ i ]; + } + + // Jumped away + pml.groundPlane = qfalse; + pml.walking = qfalse; + pm->ps->groundEntityNum = ENTITYNUM_NONE; + pm->ps->pm_flags |= PMF_CHARGE; + pm->ps->stats[ STAT_STAMINA ] -= STAMINA_DODGE_TAKE; + pm->ps->legsAnim = ( ( pm->ps->legsAnim & ANIM_TOGGLEBIT ) ^ + ANIM_TOGGLEBIT ) | LEGS_JUMP; + PM_AddEvent( EV_JUMP ); + + return qtrue; +} + //============================================================================ @@ -1176,8 +1306,7 @@ static void PM_WalkMove( void ) return; } - - if( PM_CheckJump( ) || PM_CheckPounce( ) ) + if( PM_CheckJump( ) || PM_CheckPounce( ) || PM_CheckDodge( ) ) { // jumped away if( pm->waterlevel > 1 ) @@ -1529,10 +1658,6 @@ static void PM_CrashLand( void ) 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; @@ -1964,7 +2089,7 @@ static void PM_GroundClimbTrace( void ) // hitting solid ground will end a waterjump if( pm->ps->pm_flags & PMF_TIME_WATERJUMP ) { - pm->ps->pm_flags &= ~(PMF_TIME_WATERJUMP | PMF_TIME_LAND); + pm->ps->pm_flags &= ~PMF_TIME_WATERJUMP; pm->ps->pm_time = 0; } @@ -2107,8 +2232,7 @@ static void PM_GroundTrace( void ) VectorMA( pm->ps->origin, 0.25f, movedir, point ); pm->trace( &trace, pm->ps->origin, pm->mins, pm->maxs, point, pm->ps->clientNum, pm->tracemask ); - if( trace.fraction < 1.0f && !( trace.surfaceFlags & ( SURF_SKY | SURF_SLICK ) ) && - ( trace.entityNum == ENTITYNUM_WORLD ) ) + if( trace.fraction < 1.0f && !( trace.surfaceFlags & ( SURF_SKY | SURF_SLICK ) ) ) { if( !VectorCompare( trace.plane.normal, pm->ps->grapplePoint ) ) { @@ -2174,7 +2298,7 @@ static void PM_GroundTrace( void ) // hitting solid ground will end a waterjump if( pm->ps->pm_flags & PMF_TIME_WATERJUMP ) { - pm->ps->pm_flags &= ~( PMF_TIME_WATERJUMP | PMF_TIME_LAND ); + pm->ps->pm_flags &= ~PMF_TIME_WATERJUMP; pm->ps->pm_time = 0; } @@ -2184,17 +2308,12 @@ static void PM_GroundTrace( void ) if( pm->debugLevel ) Com_Printf( "%i:Land\n", c_pmove ); + // communicate the fall velocity to the server + pm->pmext->fallVelocity = pml.previous_velocity[ 2 ]; + if( BG_ClassHasAbility( pm->ps->stats[ STAT_PCLASS ], SCA_TAKESFALLDAMAGE ) ) PM_CrashLand( ); - - // don't do landing time if we were just going down a slope - if( pml.previous_velocity[ 2 ] < -200 ) - { - // don't allow another jump for a little while - pm->ps->pm_flags |= PMF_TIME_LAND; - pm->ps->pm_time = 250; } - } pm->ps->groundEntityNum = trace.entityNum; @@ -2282,7 +2401,7 @@ static void PM_CheckDuck (void) if( pm->ps->pm_type == PM_DEAD ) { pm->maxs[ 2 ] = -8; - pm->ps->viewheight = DEAD_VIEWHEIGHT; + pm->ps->viewheight = PCmins[ 2 ] + DEAD_VIEWHEIGHT; return; } @@ -2678,6 +2797,9 @@ static void PM_Weapon( void ) if( pm->ps->stats[ STAT_STATE ] & SS_HOVELING ) return; + if( pm->ps->stats[ STAT_STATE ] & SS_CHARGING ) + return; + // check for dead player if( pm->ps->stats[ STAT_HEALTH ] <= 0 ) { @@ -2685,9 +2807,24 @@ static void PM_Weapon( void ) return; } + // no bite during pounce + if( ( pm->ps->weapon == WP_ALEVEL3 || pm->ps->weapon == WP_ALEVEL3_UPG ) + && ( pm->cmd.buttons & BUTTON_ATTACK ) + && ( pm->ps->pm_flags & PMF_CHARGE ) ) + { + return; + } + // make weapon function if( pm->ps->weaponTime > 0 ) pm->ps->weaponTime -= pml.msec; + if( pm->ps->weaponTime < 0 ) + pm->ps->weaponTime = 0; + + if( pm->ps->stats[ STAT_MISC2 ] > 0 ) + pm->ps->stats[ STAT_MISC2 ] -= pml.msec; + if( pm->ps->stats[ STAT_MISC2 ] < 0 ) + pm->ps->stats[ STAT_MISC2 ] = 0; // check for weapon change // can't change if weapon is firing, but can change @@ -2733,6 +2870,10 @@ static void PM_Weapon( void ) if( pm->ps->weaponTime > 0 ) return; + // luci uses STAT_MISC2 as an alternate weaponTime + if( pm->ps->weapon == WP_LUCIFER_CANNON && pm->ps->stats[ STAT_MISC2 ] > 0 ) + return; + // change weapon if time if( pm->ps->weaponstate == WEAPON_DROPPING ) { @@ -2812,15 +2953,7 @@ static void PM_Weapon( void ) { case WP_ALEVEL0: //venom is only autohit - attack1 = attack2 = attack3 = qfalse; - - if( !pm->autoWeaponHit[ pm->ps->weapon ] ) - { - pm->ps->weaponTime = 0; - pm->ps->weaponstate = WEAPON_READY; - return; - } - break; + return; case WP_ALEVEL3: case WP_ALEVEL3_UPG: @@ -2829,12 +2962,9 @@ static void PM_Weapon( void ) attack2 = pm->cmd.buttons & BUTTON_ATTACK2; attack3 = pm->cmd.buttons & BUTTON_USE_HOLDABLE; - if( !pm->autoWeaponHit[ pm->ps->weapon ] && !attack1 && !attack2 && !attack3 ) - { - pm->ps->weaponTime = 0; - pm->ps->weaponstate = WEAPON_READY; + // pounce is autohit + if( !attack1 && !attack2 && !attack3 ) return; - } break; case WP_LUCIFER_CANNON: @@ -2842,7 +2972,9 @@ static void PM_Weapon( void ) attack2 = pm->cmd.buttons & BUTTON_ATTACK2; attack3 = qfalse; - if( attack1 ) + if( attack1 || pm->ps->stats[ STAT_MISC ] > 0 ) + attack2 = qfalse; + if( ( attack1 || pm->ps->stats[ STAT_MISC ] == 0 ) && !attack2 && !attack3 ) { attack2 = qfalse; @@ -3310,7 +3442,9 @@ void PmoveSingle( pmove_t *pmove ) pmove->cmd.buttons = BUTTON_TALK; pmove->cmd.forwardmove = 0; pmove->cmd.rightmove = 0; - pmove->cmd.upmove = 0; + + if( pmove->cmd.upmove > 0 ) + pmove->cmd.upmove = 0; } // clear all pmove local vars @@ -3485,6 +3619,9 @@ void Pmove( pmove_t *pmove ) msec = 66; } + // force crouch + if( pmove->ps->pm_flags & PMF_FORCE_CROUCH ) + pmove->cmd.upmove = -127; pmove->cmd.serverTime = pmove->ps->commandTime + msec; PmoveSingle( pmove ); |