summaryrefslogtreecommitdiff
path: root/src/game/physics
diff options
context:
space:
mode:
authoraura <nw@moneybot.cc>2026-02-27 12:23:01 +0100
committeraura <nw@moneybot.cc>2026-02-27 12:23:01 +0100
commit39beab16f12a574af6d5ea4bf907e23ea0078863 (patch)
treec799cc4334bb2bd7cd22d737a9636371b1dd1782 /src/game/physics
parent7c0e1e9b3beb0ab5f00c27eb97b84570c532b9ac (diff)
movement polishes
Diffstat (limited to 'src/game/physics')
-rw-r--r--src/game/physics/movement.cpp59
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 ) );