diff --git a/engine/client/cl_frame.c b/engine/client/cl_frame.c index 8d1fb663..079f78c3 100644 --- a/engine/client/cl_frame.c +++ b/engine/client/cl_frame.c @@ -39,6 +39,9 @@ void CL_UpdateEntityFields( cl_entity_t *ent ) if( ent->model && ent->model->type != mod_brush && !ent->curstate.scale ) ent->curstate.scale = 1.0f; + if( ent->player ) // stupid Half-Life bug + ent->angles[PITCH] = -ent->angles[PITCH]; + // make me lerp if( ent->curstate.eflags & EFLAG_SLERP ) { diff --git a/engine/client/cl_main.c b/engine/client/cl_main.c index 88e94f35..d4515cdf 100644 --- a/engine/client/cl_main.c +++ b/engine/client/cl_main.c @@ -254,6 +254,7 @@ usercmd_t CL_CreateCmd( void ) { usercmd_t cmd; color24 color; + vec3_t angles; int ms; ms = host.frametime * 1000; @@ -261,6 +262,7 @@ usercmd_t CL_CreateCmd( void ) Mem_Set( &cmd, 0, sizeof( cmd )); + VectorCopy( cl.refdef.cl_viewangles, angles ); VectorCopy( cl.frame.local.client.origin, cl.data.origin ); VectorCopy( cl.refdef.cl_viewangles, cl.data.viewangles ); cl.data.iWeaponBits = cl.frame.local.client.weapons; @@ -276,7 +278,7 @@ usercmd_t CL_CreateCmd( void ) // allways dump the first ten messages, // because it may contain leftover inputs // from the last level - if( cl.background || ++cl.movemessages <= 10 ) + if( ++cl.movemessages <= 10 ) return cmd; clgame.dllFuncs.CL_CreateMove( cl.time - cl.oldtime, &cmd, ( cls.state == ca_active && !cl.refdef.paused )); @@ -288,6 +290,12 @@ usercmd_t CL_CreateCmd( void ) // because is potential backdoor for cheating cmd.msec = ms; + if( cl.background ) + { + VectorCopy( angles, cl.refdef.cl_viewangles ); + VectorCopy( angles, cmd.viewangles ); + cmd.msec = 0; + } return cmd; } @@ -1501,7 +1509,7 @@ CL_SendCommand void CL_SendCommand( void ) { // send intentions now - if( !SV_Active()) CL_SendCmd (); + CL_SendCmd (); // resend a connection request if necessary CL_CheckForResend (); @@ -1536,12 +1544,6 @@ void Host_ClientFrame( void ) // fetch results from server CL_ReadPackets(); - // send a new command message to the server - CL_SendCommand(); - - // predict all unacknowledged movements - CL_PredictMovement(); - VID_CheckChanges(); // allow sound and video DLL change @@ -1557,6 +1559,12 @@ void Host_ClientFrame( void ) // update audio S_RenderFrame( &cl.refdef ); + // send a new command message to the server + CL_SendCommand(); + + // predict all unacknowledged movements + CL_PredictMovement(); + // decay dynamic lights CL_DecayLights (); diff --git a/engine/client/gl_rmain.c b/engine/client/gl_rmain.c index b564073c..3f787123 100644 --- a/engine/client/gl_rmain.c +++ b/engine/client/gl_rmain.c @@ -833,6 +833,8 @@ void R_DrawEntitiesOnList( void ) clgame.dllFuncs.pfnDrawTransparentTriangles (); R_DrawViewModel(); + + CL_ExtraUpdate(); } /* @@ -901,6 +903,8 @@ void R_BeginFrame( qboolean clearScene ) // swapinterval stuff GL_UpdateSwapInterval(); + + CL_ExtraUpdate (); } /* diff --git a/engine/client/gl_studio.c b/engine/client/gl_studio.c index ef7b371d..5665f4b0 100644 --- a/engine/client/gl_studio.c +++ b/engine/client/gl_studio.c @@ -1883,10 +1883,7 @@ static void R_StudioClientEvents( void ) return; if( e->syncbase == -0.01f ) - { flEventFrame = 0.0f; - //Msg( "Sequence changed\n" ); - } // stalled? if( flEventFrame == e->syncbase ) @@ -1919,18 +1916,12 @@ static void R_StudioClientEvents( void ) if( bLooped ) { if(( pevent[i].frame > e->syncbase || pevent[i].frame <= flEventFrame )) - { - //Msg( "FE %i Looped frame %i, prev %f ev %f (time %.3f)\n", pevent[i].event, pevent[i].frame, e->syncbase, flEventFrame, RI.refdef.time ); clgame.dllFuncs.pfnStudioEvent( &pevent[i], e ); - } } else { if(( pevent[i].frame > e->syncbase && pevent[i].frame <= flEventFrame )) - { - //Msg( "FE %i Normal frame %i, prev %f ev %f (time %.3f)\n", pevent[i].event, pevent[i].frame, e->syncbase, flEventFrame, RI.refdef.time ); clgame.dllFuncs.pfnStudioEvent( &pevent[i], e ); - } } } @@ -1992,7 +1983,7 @@ static void R_StudioSetupRenderer( int rendermode ) if( RI.currententity == &clgame.viewent ) { // hack the depth range to prevent view model from poking into walls - pglDepthRange( gldepthmin, gldepthmin + 0.3f * ( gldepthmax - gldepthmin ) ); + pglDepthRange( gldepthmin, gldepthmin + 0.3f * ( gldepthmax - gldepthmin )); // backface culling for left-handed weapons if( r_lefthand->integer == 1 ) GL_FrontFace( !glState.frontFace ); diff --git a/engine/common/host.c b/engine/common/host.c index 805296b5..d5dce6c0 100644 --- a/engine/common/host.c +++ b/engine/common/host.c @@ -383,10 +383,6 @@ void Host_Frame( float time ) if( !Host_FilterTime( time )) return; - // if running the server locally, make intentions now - // (this is prevent lag on rpg laserspot in singleplayer) - if( SV_Active()) CL_SendCmd (); - Host_ServerFrame (); // server frame Host_ClientFrame (); // client frame diff --git a/engine/server/server.h b/engine/server/server.h index 543836f8..151e9256 100644 --- a/engine/server/server.h +++ b/engine/server/server.h @@ -424,6 +424,7 @@ qboolean SV_RunThink( edict_t *ent ); void SV_FreeOldEntities( void ); qboolean SV_TestEntityPosition( edict_t *ent ); // for EntityInSolid checks qboolean SV_TestPlayerPosition( edict_t *ent ); // for PlayerInSolid checks +void SV_Impact( edict_t *e1, trace_t *trace ); // // sv_move.c diff --git a/engine/server/sv_game.c b/engine/server/sv_game.c index 3c1ce218..7980d5db 100644 --- a/engine/server/sv_game.c +++ b/engine/server/sv_game.c @@ -1447,9 +1447,6 @@ int pfnDropToFloor( edict_t* e ) vec3_t end; trace_t trace; - if( sv.loadgame ) - return 0; - if( !SV_IsValidEdict( e )) { MsgDev( D_ERROR, "SV_DropToFloor: invalid entity %s\n", SV_ClassName( e )); diff --git a/engine/server/sv_phys.c b/engine/server/sv_phys.c index c08fabac..9e70ed1f 100644 --- a/engine/server/sv_phys.c +++ b/engine/server/sv_phys.c @@ -175,20 +175,29 @@ void SV_Impact( edict_t *e1, trace_t *trace ) { edict_t *e2 = trace->ent; - // custom user filter - if( svgame.dllFuncs2.pfnShouldCollide ) + if(( e1->v.flags|e2->v.flags ) & FL_SPECTATOR ) + return; + + if( e1->v.groupinfo && e2->v.groupinfo ) { - if( !svgame.dllFuncs2.pfnShouldCollide( e1, e2 )) + if(( svs.groupop == 0 && ( e1->v.groupinfo & e2->v.groupinfo )) == 0 || + (svs.groupop == 1 && (e1->v.groupinfo & e2->v.groupinfo) != 0 )) return; } svgame.globals->time = sv.time; - if( !e1->free && !e2->free && e1->v.solid != SOLID_NOT ) + if( e1->v.solid != SOLID_NOT ) + { + SV_CopyTraceToGlobal( trace ); svgame.dllFuncs.pfnTouch( e1, e2 ); + } - if( !e1->free && !e2->free && e2->v.solid != SOLID_NOT ) + if( e2->v.solid != SOLID_NOT ) + { + SV_CopyTraceToGlobal( trace ); svgame.dllFuncs.pfnTouch( e2, e1 ); + } } /* diff --git a/engine/server/sv_pmove.c b/engine/server/sv_pmove.c index af791fff..52c0c128 100644 --- a/engine/server/sv_pmove.c +++ b/engine/server/sv_pmove.c @@ -590,7 +590,6 @@ static void SV_SetupPMove( playermove_t *pmove, edict_t *clent, usercmd_t *ucmd, static void SV_FinishPMove( playermove_t *pmove, edict_t *clent ) { clent->v.teleport_time = pmove->waterjumptime; - VectorCopy( pmove->angles, clent->v.v_angle ); VectorCopy( pmove->origin, clent->v.origin ); VectorCopy( pmove->view_ofs, clent->v.view_ofs ); VectorCopy( pmove->velocity, clent->v.velocity ); @@ -638,6 +637,15 @@ static void SV_FinishPMove( playermove_t *pmove, edict_t *clent ) clent->v.groundentity = EDICT_NUM( pmove->physents[pmove->onground].info ); else clent->v.groundentity = NULL; #endif + // angles + // show 1/3 the pitch angle and all the roll angle + if( !clent->v.fixangle ) + { + VectorCopy( pmove->angles, clent->v.v_angle ); + clent->v.angles[PITCH] = -clent->v.v_angle[PITCH] / 3; + clent->v.angles[ROLL] = clent->v.v_angle[ROLL]; + clent->v.angles[YAW] = clent->v.v_angle[YAW]; + } } int nofind = 0; @@ -879,7 +887,6 @@ void SV_RunCmd( sv_client_t *cl, usercmd_t *ucmd, int random_seed ) return; } - PM_CheckMovingGround( clent, ucmd->msec * 0.001f ); VectorCopy( clent->v.v_angle, svgame.pmove->oldangles ); // save oldangles @@ -889,17 +896,6 @@ void SV_RunCmd( sv_client_t *cl, usercmd_t *ucmd, int random_seed ) clent->v.button = ucmd->buttons; if( ucmd->impulse ) clent->v.impulse = ucmd->impulse; - // angles - // show 1/3 the pitch angle and all the roll angle - if( clent->v.deadflag < DEAD_DEAD ) - { - if( !clent->v.fixangle ) - { - clent->v.angles[PITCH] = -clent->v.v_angle[PITCH] / 3; - clent->v.angles[YAW] = clent->v.v_angle[YAW]; - } - } - if( clent->v.flags & FL_DUCKING ) SV_SetMinMaxSize( clent, svgame.pmove->player_mins[1], svgame.pmove->player_maxs[1] ); else SV_SetMinMaxSize( clent, svgame.pmove->player_mins[0], svgame.pmove->player_maxs[0] ); @@ -911,7 +907,7 @@ void SV_RunCmd( sv_client_t *cl, usercmd_t *ucmd, int random_seed ) SV_RunThink( clent ); // clients cannot be deleted from map // If conveyor, or think, set basevelocity, then send to client asap too. - if( VectorLength( clent->v.basevelocity ) > 0.0f ) + if( !VectorIsNull( clent->v.basevelocity )) VectorCopy( clent->v.basevelocity, clent->v.clbasevelocity ); } @@ -946,8 +942,25 @@ void SV_RunCmd( sv_client_t *cl, usercmd_t *ucmd, int random_seed ) if( touch == clent ) continue; VectorCopy( svgame.pmove->touchindex[i].deltavelocity, clent->v.velocity ); - SV_CopyPmtraceToGlobal( &svgame.pmove->touchindex[i] ); - svgame.dllFuncs.pfnTouch( touch, clent ); + + if( touch->v.groupinfo && clent->v.groupinfo ) + { + if(( svs.groupop == 0 && ( touch->v.groupinfo & clent->v.groupinfo )) == 0 || + (svs.groupop == 1 && (touch->v.groupinfo & clent->v.groupinfo) != 0 )) + continue; + } + + if( touch->v.solid != SOLID_NOT ) + { + SV_CopyPmtraceToGlobal( &svgame.pmove->touchindex[i] ); + svgame.dllFuncs.pfnTouch( touch, clent ); + } + + if( clent->v.solid != SOLID_NOT ) + { + SV_CopyPmtraceToGlobal( &svgame.pmove->touchindex[i] ); + svgame.dllFuncs.pfnTouch( clent, touch ); + } } // restore velocity diff --git a/engine/server/sv_world.c b/engine/server/sv_world.c index 5706a488..1a769a79 100644 --- a/engine/server/sv_world.c +++ b/engine/server/sv_world.c @@ -1151,6 +1151,13 @@ static void SV_ClipToLinks( areanode_t *node, moveclip_t *clip ) if( clip->passedict && !VectorIsNull( clip->passedict->v.size ) && VectorIsNull( touch->v.size )) continue; // points never interact + // custom user filter + if( svgame.dllFuncs2.pfnShouldCollide ) + { + if( !svgame.dllFuncs2.pfnShouldCollide( touch, clip->passedict )) + continue; + } + // monsterclip filter if( modType == mod_brush && ( touch->v.flags & FL_MONSTERCLIP )) {