diff options
Diffstat (limited to 'src/game/physics')
| -rw-r--r-- | src/game/physics/movement.cpp | 59 |
1 files changed, 42 insertions, 17 deletions
diff --git a/src/game/physics/movement.cpp b/src/game/physics/movement.cpp index 31ae63f..73c5202 100644 --- a/src/game/physics/movement.cpp +++ b/src/game/physics/movement.cpp @@ -189,7 +189,7 @@ void gmove_categorize_pos() { gmove_touch_ground( &tr, bump, point ); if( !tr.hit || tr.normal.z < 0.7f ) { gmove_touch_ground_quadrants( &tr, bump, point ); - if( !tr.hit || tr.normal.z < 0.7f ) { + if( !tr.hit || tr.normal.z < 0.7f ) { gmove->ground = 0; if( gmove->velocity.z > 0.f ) { @@ -268,11 +268,10 @@ F32 gmove_try_move( BSP_TRACE* t, VEC3* pos, VEC3* vel ) { void gmove_check_stuck( VEC3* in_pos ) { BSP_TRACE t; VEC3 pos = *in_pos; + U32 i; if( vec_len( gmove->unstuck_vel ) < 0.f ) gmove->unstuck_vel = { 0, 0, 1.f }; - if( gmove->ground ) - pos.z += 2.f; bsp_trace( &t, gmove->bsp, gmove->aabb, pos, pos ); if( !t.hit ) { if( vec_len( gmove->velocity ) > 1.f ) { @@ -284,16 +283,25 @@ void gmove_check_stuck( VEC3* in_pos ) { VEC3 p1 = pos; defer( { - if( !t.hit ) *in_pos = pos; + if( !t.hit ) { + *in_pos = pos; + gmove_categorize_pos(); + } } ); - for( U32 i = 1; i <= 32; i *= 2 ) { + for( i = 1; i <= 32; i *= 2 ) { // try nudge away from wall pos = p1 + t.normal * BSP_TRACE_EPSILON * (F32)i; bsp_trace( &t, gmove->bsp, gmove->aabb, pos, pos ); if( !t.hit ) return; + // try moving up + pos = p1 + VEC3{ 0, 0, 2.f } * (F32)i; + bsp_trace( &t, gmove->bsp, gmove->aabb, pos, pos ); + if( !t.hit ) + return; + // nudge +90deg away horizontal pos = p1 + VEC3{ -t.normal.y, t.normal.x, t.normal.z } * (F32)i; bsp_trace( &t, gmove->bsp, gmove->aabb, pos, pos ); @@ -312,14 +320,14 @@ void gmove_check_stuck( VEC3* in_pos ) { if( !t.hit ) return; - pos = p1 + (gmove->unstuck_vel * -1.f) * TICK_INTERVAL * (F32)i; - bsp_trace( &t, gmove->bsp, gmove->aabb, pos, pos ); - if( !t.hit ) - return; + // move back 1 tick + if( vec_lensq( gmove->velocity ) > 10.f ) { + pos = p1 + vec_normalize( gmove->unstuck_vel * -1.f ) * TICK_INTERVAL * (F32)i; + bsp_trace( &t, gmove->bsp, gmove->aabb, pos, pos ); + if( !t.hit ) + return; + } } - - // todo : loop over every dir from current pos and incrementally increase distance. - // kinda like source } void gmove_accelerate( VEC3& wishdir, F32 wishspeed, F32 accel ) { @@ -389,14 +397,14 @@ void gmove_stay_on_ground() { end.z -= gmove->pl->stepsize; bsp_trace( &tr, gmove->bsp, gmove->aabb, start, end ); - start = tr.point; + start = tr.point + BSP_TRACE_EPSILON; bsp_trace( &tr, gmove->bsp, gmove->aabb, start, end ); if( tr.frac > 0.f && tr.frac < 1.f && !tr.startsolid && tr.normal.z >= 0.7f ) { F32 delta = fabs( gmove->pos.z - tr.point.z ); - if( delta > 0.5f * BSP_TRACE_EPSILON ) - gmove->pos = tr.point; + if( delta > BSP_TRACE_EPSILON ) + gmove->pos = tr.point + tr.normal * BSP_EDGE_TOLERANCE; } } @@ -410,6 +418,7 @@ void gmove_step_move( VEC3 dest, BSP_TRACE* tr ) { VEC3 upvel = vel, downvel = vel; gmove_try_move( tr, &down, &downvel ); + VEC3 downn = tr->normal; endpos.z += gmove->pl->stepsize + BSP_DIST_EPSILON; bsp_trace( tr, gmove->bsp, gmove->aabb, pos, endpos ); @@ -422,8 +431,12 @@ void gmove_step_move( VEC3 dest, BSP_TRACE* tr ) { endpos.z -= (gmove->pl->stepsize + BSP_DIST_EPSILON); bsp_trace( tr, gmove->bsp, gmove->aabb, up, endpos ); + + defer( gmove_check_stuck( &gmove->pos ) ); if( tr->normal.z < 0.7 ) { // not ground, slope gmove->pos = down; + if( downn.z < 0.99f ) + gmove->pos += downn * BSP_TRACE_EPSILON * 2.f; gmove->velocity = downvel; F32 step_dist = gmove->pos.z - pos.z; gmove->out_step = step_dist; @@ -440,12 +453,23 @@ void gmove_step_move( VEC3 dest, BSP_TRACE* tr ) { gmove->out_step = gmove->pos.z - pos.z; if( downdist > updist ) { gmove->pos = down; + if( downn.z < 0.99f ) + gmove->pos += downn * BSP_TRACE_EPSILON * 2.f; gmove->velocity = downvel; } else { - gmove->pos = up; + VEC3 delta = up - pos; + F32 dist = vec_len( delta ); + F32 speed = vec_len( gmove->velocity ) * TICK_INTERVAL; + if( dist > speed ) { + for( U32 i = 0; i < 2; ++i ) + delta[i] *= speed / dist; + } + + gmove->pos += delta; + if( tr->normal.z < 0.99f ) + gmove->pos += tr->normal * BSP_TRACE_EPSILON * 2.f; gmove->velocity = upvel; - return; } } @@ -469,6 +493,7 @@ void gmove_walk_move() { } gmove_accelerate( wishdir, speed, var_getf( mv_accelerate ) ); + gmove->velocity[2] = 0; speed = vec_len( gmove->velocity ); defer( gmove_check_stuck( &gmove->pos ) ); |
