diff options
| author | aura <nw@moneybot.cc> | 2026-02-25 14:45:28 +0100 |
|---|---|---|
| committer | aura <nw@moneybot.cc> | 2026-02-25 14:45:28 +0100 |
| commit | b384930de5044934207d1b2ceb4fa55705094f8b (patch) | |
| tree | 7937d3382e83ead2db1851b4a02b8378d02ac150 | |
| parent | cabe4471c309b2bba3be78b8346c9007485b1d57 (diff) | |
movement stuff + fix map zoom when dragging
| -rw-r--r-- | src/editor/view2d.cpp | 2 | ||||
| -rw-r--r-- | src/game.cpp | 1 | ||||
| -rw-r--r-- | src/game/physics/movement.cpp | 204 | ||||
| -rw-r--r-- | src/game/physics/movement.h | 21 | ||||
| -rw-r--r-- | src/game/player.cpp | 3 | ||||
| -rw-r--r-- | src/game/player.h | 5 | ||||
| -rw-r--r-- | src/game/vars.cpp | 71 | ||||
| -rw-r--r-- | src/game/vars.h | 5 | ||||
| -rw-r--r-- | src/game/world/trace.cpp | 3 | ||||
| -rw-r--r-- | src/game/world/trace.h | 1 |
10 files changed, 270 insertions, 46 deletions
diff --git a/src/editor/view2d.cpp b/src/editor/view2d.cpp index ee7e4d7..4498248 100644 --- a/src/editor/view2d.cpp +++ b/src/editor/view2d.cpp @@ -747,6 +747,8 @@ void gui_editor_2dview_input_scroll( GUI_EDITOR_2DVIEW* view ) { VEC2 world_after = gui_editor_2dview_screen_to_world( view, mx, my ); view->posx += world_before.x - world_after.x; view->posy += world_before.y - world_after.y; + + view->dragheld = 0; } void gui_editor_2dview_input_tool_wall( GUI_EDITOR_2DVIEW* view ) { diff --git a/src/game.cpp b/src/game.cpp index 6202145..663681f 100644 --- a/src/game.cpp +++ b/src/game.cpp @@ -34,7 +34,6 @@ GAME_DATA* game_init( GL_DATA* gl ) { assets_init( game ); assets_on_frame( game ); - varl = vars_init(); objl = objl_init(); gmove_init( game ); diff --git a/src/game/physics/movement.cpp b/src/game/physics/movement.cpp index e9e0132..c9b7688 100644 --- a/src/game/physics/movement.cpp +++ b/src/game/physics/movement.cpp @@ -5,6 +5,12 @@ #include "../../game.h" GAME_MOVEMENT* gmove; +CVAR* mv_gravity = var_new( "mv_gravity", 5.5f ); +CVAR* mv_friction = var_new( "mv_friction", 5.f ); +CVAR* mv_accelerate = var_new( "mv_accelerate", 5.5f ); +CVAR* mv_airaccelerate = var_new( "mv_airaccelerate", 12.f ); +CVAR* mv_wallboost = var_new( "mv_wallboost", 0 ); +CVAR* mv_maxspeed = var_new( "mv_maxspeed", 3500.f ); void gmove_init( GAME_DATA* game ) { gmove = new GAME_MOVEMENT; @@ -45,6 +51,24 @@ void gmove_set_player( PLAYER* player ) { gmove->input = &player->input; } +void gmove_start_tick() { + PLAYER* p = gmove->pl; + gmove->velocity = p->velocity; + gmove->pos = p->pos; + gmove->angle = p->rot; + gmove->maxspeed = p->maxspeed; + gmove->walkspeed = p->walkspeed; + gmove->aabb.min = p->mins; + gmove->aabb.max = p->maxs; + gmove->bsp = gmove->game->state.map->bsp; +} + +void gmove_end_tick() { + PLAYER* p = gmove->pl; + p->velocity = gmove->velocity; + p->pos = gmove->pos; +} + VEC3 gmove_clip_velocity( VEC3 in, VEC3 norm, F32 overbounce ) { F32 blocked = vec_dot( in, norm ); F32 backoff = blocked * overbounce; @@ -54,14 +78,83 @@ VEC3 gmove_clip_velocity( VEC3 in, VEC3 norm, F32 overbounce ) { if( adjust < 0.f ) out -= (norm * adjust); - // uncomment to enable quake/hl1-like wallboosting - // F32 len = vec_len( out ); - // if( len > 0.f ) - // out *= ( -1.f * blocked + len ) / len; + if( var_geti( mv_wallboost ) ) { + F32 len = vec_len( out ); + if( len > 0.f ) + out *= ( -1.f * blocked + len ) / len; + } return out; } +void gmove_check_velocity() { + F32 maxspeed = var_getf( mv_maxspeed ); + + for( U32 i = 0; i < 3; ++i ) { + F32* v = &gmove->pl->velocity[i]; + if( isnan( *v ) ) *v = 0.f; continue; + if( *v > maxspeed ) *v = maxspeed; + if( *v < -maxspeed ) *v = -maxspeed; + } +} + +void gmove_start_gravity() { + F32 gravity = gmove->pl->gravity * var_getf( mv_gravity ); + + gmove->velocity.z -= gravity * 0.5f * TICK_INTERVAL; + gmove_check_velocity(); +} + +void gmove_end_gravity() { + +} + +void gmove_accelerate( VEC3& wishdir, F32 wishspeed, F32 accel ) { + F32 addspeed, accelspeed, currentspeed; + F32 surf_friction = 1.f; + + currentspeed = vec_dot( gmove->pl->velocity, wishdir ); + addspeed = wishspeed - currentspeed; + if( addspeed <= 0 ) + return; + + accelspeed = accel * TICK_INTERVAL * wishspeed * surf_friction; + if( accelspeed > addspeed ) + accelspeed = addspeed; + + gmove->velocity += wishdir * accelspeed; +} + +// todo: player hull extends at center instead of at feet +// should extend at feet +void gmove_stay_on_ground() { + BSP_TRACE tr{}; + VEC3 start = gmove->pos; + VEC3 end = gmove->pos; + + start.z += 2.f; + end.z -= gmove->pl->stepsize; + + bsp_trace( &tr, gmove->bsp, gmove->aabb, start, end ); + start = tr.point; + + 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; + } +} + +void gmove_airaccelerate() { + +} + +void gmove_categorize_pos() { + +} + VEC3 gmove_clip_planes( VEC3 vel, LIST<VEC3>* planes, F32 overbounce ) { if( planes->size > 2 ) vel = {}; @@ -90,12 +183,13 @@ VEC3 gmove_clip_planes( VEC3 vel, LIST<VEC3>* planes, F32 overbounce ) { return vel; } -F32 gmove_try_move( BSP_TRACE* t, AABB aabb, VEC3* pos, VEC3 vel ) { - F32 dt = TICK_INTERVAL; +F32 gmove_try_move( BSP_TRACE* t, VEC3* pos, VEC3* vel ) { + F32 dt = TICK_INTERVAL; + AABB aabb = gmove->aabb; LIST<VEC3> planes; for( U32 bump = 0; bump < 4; ++bump ) { - VEC3 wishmove = vel * dt; + VEC3 wishmove = *vel * dt; bsp_trace( t, gmove->game->state.map->bsp, aabb, *pos, *pos + wishmove ); if( !t->hit ) { *pos = t->point; @@ -112,38 +206,100 @@ F32 gmove_try_move( BSP_TRACE* t, AABB aabb, VEC3* pos, VEC3 vel ) { if( dt <= 0.0001f ) break; - vel = gmove_clip_planes( vel, &planes, 1.f /* surface friction */ ); + *vel = gmove_clip_planes( *vel, &planes, 1.f /* todo : surface friction */ ); } return dt < 0 ? 0 : dt; } +void gmove_step_move( VEC3 dest, BSP_TRACE* tr ) { + VEC3 endpos = dest; + VEC3 pos = gmove->pos; + VEC3 vel = gmove->velocity; + + VEC3 up = pos, down = pos; + VEC3 upvel = vel, downvel = vel; + + gmove_try_move( tr, &down, &downvel ); + + endpos.z += gmove->pl->stepsize + BSP_DIST_EPSILON; + bsp_trace( tr, gmove->bsp, gmove->aabb, pos, endpos ); + if( !tr->startsolid && tr->frac > BSP_TRACE_EPSILON ) { + up = tr->point; + } + + gmove_try_move( tr, &up, &upvel ); + endpos = up; + endpos.z -= (gmove->pl->stepsize + BSP_DIST_EPSILON); + + bsp_trace( tr, gmove->bsp, gmove->aabb, up, endpos ); + if( tr->normal.z < 0.7 ) { // not ground, slope + gmove->pos = down; + gmove->velocity = downvel; + F32 step_dist = gmove->pos.z - pos.z; + gmove->out_step = step_dist; + return; + } + + if( !tr->startsolid && tr->frac > BSP_TRACE_EPSILON ) { + up = tr->point; + } + + F32 updist = vec_dist( pos, up ); + F32 downdist = vec_dist( pos, down ); + + gmove->out_step = gmove->pos.z - pos.z; + if( downdist > updist ) { + gmove->pos = down; + gmove->velocity = downvel; + } + else { + gmove->pos = up; + gmove->velocity = upvel; + return; + } +} + void gmove_walk_move() { - PLAYER* p = gmove->pl; - VEC2 move = gmove->input->move; - F32 yawrad = m_deg2rad( p->rot.y ); - VEC3 wishdir = { + VEC2 move = gmove->input->move; + F32 yawrad = m_deg2rad( gmove->angle.y ); + VEC3 wishdir = { move.x * cosf( yawrad ) - move.y * sinf( yawrad ), move.y * cosf( yawrad ) + move.x * sinf( yawrad ), 0 }; - VEC3 vel = wishdir * p->maxspeed; - VEC3 wishmove = vel * TICK_INTERVAL; - p->velocity = vel; + VEC3 vel = wishdir * gmove->walkspeed; + F32 speed = vec_len( vel ); + if( speed > gmove->maxspeed ) { + vel *= gmove->maxspeed / speed; + speed = gmove->maxspeed; + } - if( vec_len( wishmove ) < BSP_TRACE_EPSILON ) + gmove_accelerate( wishdir, speed, var_getf( mv_accelerate ) ); + speed = vec_len( vel ); + + if( speed < 1.f ) { + gmove->velocity = {}; return; + } + VEC3 dest = gmove->pos + vel * TICK_INTERVAL; BSP_TRACE tr{}; - AABB aabb{}; - aabb.min = p->mins; - aabb.max = p->maxs; - VEC3 npos = p->pos; + bsp_trace( &tr, gmove->bsp, gmove->aabb, gmove->pos, dest ); + + if( !tr.hit ) { + gmove->pos = dest; + gmove_stay_on_ground(); + return; + } + + gmove_step_move( dest, &tr ); + gmove_stay_on_ground(); +} - F32 frac = gmove_try_move( &tr, aabb, &npos, vel ); - p->velocity *= frac / TICK_INTERVAL; - p->pos = npos; +void gmove_full_walk_move() { + } void gmove_process_move() { @@ -153,5 +309,7 @@ void gmove_process_move() { void gmove_tick() { if( !gmove_check_valid( "gmove_tick()" ) ) return; + gmove_start_tick(); gmove_process_move(); + gmove_end_tick(); } diff --git a/src/game/physics/movement.h b/src/game/physics/movement.h index 7c78d79..47aa97d 100644 --- a/src/game/physics/movement.h +++ b/src/game/physics/movement.h @@ -1,11 +1,32 @@ #pragma once +#include "../../util/aabb.h" +#include "../world/bsp.h" #include "../player.h" +#include "../vars.h" + +extern CVAR* mv_gravity; +extern CVAR* mv_friction; +extern CVAR* mv_accelerate; +extern CVAR* mv_airaccelerate; +extern CVAR* mv_wallboost; +extern CVAR* mv_maxspeed; + struct GAME_MOVEMENT { PLAYER* pl; PLAYER_INPUT* input; GAME_DATA* game; + + VEC3 velocity; + VEC3 pos; + VEC3 angle; + F32 maxspeed; + F32 walkspeed; + AABB aabb; + BSP* bsp; + + F32 out_step; }; extern void gmove_init( GAME_DATA* game ); diff --git a/src/game/player.cpp b/src/game/player.cpp index 65daa9b..74ecea2 100644 --- a/src/game/player.cpp +++ b/src/game/player.cpp @@ -6,7 +6,8 @@ #include <cmath> #include "player.h" -F32 PLAYER_HULL_HEIGHT = 50.f; +// todo : temporary +F32 PLAYER_HULL_HEIGHT = 1.f; F32 PLAYER_HULL_WIDTH = 32.f; PLAYER* player_create( VEC3 origin, F32 yaw ) { diff --git a/src/game/player.h b/src/game/player.h index c0e126d..7dfd009 100644 --- a/src/game/player.h +++ b/src/game/player.h @@ -2,7 +2,6 @@ #include "object.h" #include "camera.h" - struct PLAYER_INPUT { PLAYER_CAMERA cam; struct PLAYER* pobj; @@ -23,7 +22,11 @@ struct PLAYER : OBJECT { VEC3 mins; VEC3 maxs; + F32 gravity{1.f}; F32 maxspeed{70.f}; + F32 walkspeed{70.f}; + F32 stepsize{16.f}; + VEC3 velocity; }; diff --git a/src/game/vars.cpp b/src/game/vars.cpp index d7b1f9b..3d1eaf4 100644 --- a/src/game/vars.cpp +++ b/src/game/vars.cpp @@ -4,16 +4,18 @@ VAR_LIST* varl; +void vars_check_global_list() { + if( !varl ) + varl = vars_init(); +} + VAR_LIST* vars_init() { VAR_LIST* ret = new VAR_LIST; return ret; } CVAR* var_new( const char* name, F32 v ) { - if( !varl ) { - dlog( "var_new() : error: varl null\n" ); - return 0; - } + vars_check_global_list(); CVAR* ret = new CVAR; memset( ret, 0 , sizeof( CVAR ) ); @@ -26,10 +28,7 @@ CVAR* var_new( const char* name, F32 v ) { } CVAR* var_new( const char* name, I32 i ) { - if( !varl ) { - dlog( "var_new() : error: varl null\n" ); - return 0; - } + vars_check_global_list(); CVAR* ret = new CVAR; memset( ret, 0 , sizeof( CVAR ) ); @@ -42,10 +41,7 @@ CVAR* var_new( const char* name, I32 i ) { } CVAR* var_new( const char* name, CLR c ) { - if( !varl ) { - dlog( "var_new() : error: varl null\n" ); - return 0; - } + vars_check_global_list(); CVAR* ret = new CVAR; memset( ret, 0 , sizeof( CVAR ) ); @@ -58,10 +54,7 @@ CVAR* var_new( const char* name, CLR c ) { } CVAR* var_new( const char* name, CVAR_FUNC func ) { - if( !varl ) { - dlog( "var_new() : error: varl null\n" ); - return 0; - } + vars_check_global_list(); CVAR* ret = new CVAR; memset( ret, 0 , sizeof( CVAR ) ); @@ -74,10 +67,7 @@ CVAR* var_new( const char* name, CVAR_FUNC func ) { } CVAR* var_new( const char* name, const char* v ) { - if( !varl ) { - dlog( "var_new() : error: varl null\n" ); - return 0; - } + vars_check_global_list(); CVAR* ret = new CVAR; memset( ret, 0, sizeof( CVAR ) ); @@ -113,3 +103,44 @@ I32 var_call( CVAR *cmdvar, const char *cmdline ) { return cmdvar->fn_v( cmdvar, cmdline ); } + +F32 var_getf( CVAR *var ) { + switch( var->type ) { + case CVAR_TYPE_FLOAT: return var->fl_v; + case CVAR_TYPE_INT: return (F32)var->fl_v; + default: return 0.f; + } +} + +I32 var_geti( CVAR *var ) { + switch( var->type ) { + case CVAR_TYPE_INT: return var->fl_v; + case CVAR_TYPE_FLOAT: return (I32)var->fl_v; + default: return 0; + } +} + +CLR var_getclr( CVAR *var ) { + switch( var->type ) { + case CVAR_TYPE_COLOR: return var->clr_v; + case CVAR_TYPE_FLOAT: return (CLR){ var->fl_v, var->fl_v, var->fl_v, 1.f }; + default: return {}; + } +} + +const char* var_gets( CVAR *var ) { + switch( var->type ) { + case CVAR_TYPE_STRING: return var->str_v; + case CVAR_TYPE_FLOAT: + sprintf( var->str_v + sizeof(F32), "%f", var->fl_v ); + return var->str_v + sizeof(F32); + case CVAR_TYPE_INT: + sprintf( var->str_v + sizeof(I32), "%d", var->i_v ); + return var->str_v + sizeof(I32); + case CVAR_TYPE_COLOR: + sprintf( var->str_v + sizeof(CLR), "%f %f %f %f", var->clr_v.r, var->clr_v.g, var->clr_v.b, var->clr_v.a ); + return var->str_v + sizeof(CLR); + default: + return ""; + } +} diff --git a/src/game/vars.h b/src/game/vars.h index 395c470..8abe2fa 100644 --- a/src/game/vars.h +++ b/src/game/vars.h @@ -44,7 +44,12 @@ extern CVAR* var_new( const char* name, CLR v ); extern CVAR* var_new( const char* name, const char* v ); extern CVAR* var_new( const char* name, CVAR_FUNC fn ); + extern CVAR* var_find( const char* name ); extern I32 var_call( CVAR* cmdvar, const char* cmdline ); +extern F32 var_getf( CVAR* var ); +extern I32 var_geti( CVAR* var ); +extern CLR var_getclr( CVAR* var ); +extern const char* var_gets( CVAR* var ); extern VAR_LIST* varl; diff --git a/src/game/world/trace.cpp b/src/game/world/trace.cpp index 43f5f68..fd6a03b 100644 --- a/src/game/world/trace.cpp +++ b/src/game/world/trace.cpp @@ -165,6 +165,7 @@ U8 bsp_trace( BSP_TRACE* trace, BSP* bsp ) { } trace->hit = 0; + trace->startsolid = 0; bsp_trace_nudge( trace ); VEC3 start = trace->in_start; @@ -237,6 +238,7 @@ U8 bsp_trace_sweep_aabb_to_face( if( point_in_inflated_poly( start, face, hull, norm ) ) { trace->hit = 1; trace->frac = 0.f; + trace->startsolid = 1; trace->point = start; trace->normal = norm; trace->propid = face->propid; @@ -375,6 +377,7 @@ U8 bsp_trace( BSP_TRACE* trace, BSP* bsp, AABB hull ) { if( !trace || !bsp ) return 0; + trace->startsolid = 0; trace->hit = 0; bsp_trace_nudge( trace ); VEC3 start = trace->in_start; diff --git a/src/game/world/trace.h b/src/game/world/trace.h index 8a0f4eb..717fc8f 100644 --- a/src/game/world/trace.h +++ b/src/game/world/trace.h @@ -17,6 +17,7 @@ struct BSP_TRACE { U32 propid; I32 leafid; U32 faceid; + U8 startsolid; }; extern U8 bsp_trace( BSP_TRACE* trace, BSP* bsp ); |
