/* ============= CL_ParseReliableEvent ============= */ void CL_ParseReliableEvent( sizebuf_t *msg ) { int event_index; event_args_t nullargs, args; float delay = 0.0f; cl_entity_t *pEnt; Q_memset( &nullargs, 0, sizeof( nullargs )); event_index = BF_ReadUBitLong( msg, MAX_EVENT_BITS ); if( BF_ReadOneBit( msg )) delay = (float)BF_ReadWord( msg ) * (1.0f / 100.0f); // reliable events not use delta-compression just null-compression MSG_ReadDeltaEvent( msg, &nullargs, &args ); if(( pEnt = CL_GetEntityByIndex( args.entindex )) != NULL ) { if( VectorIsNull( args.origin )) VectorCopy( pEnt->curstate.origin, args.origin ); if( VectorIsNull( args.angles )) VectorCopy( pEnt->curstate.angles, args.angles ); if( VectorIsNull( args.velocity )) VectorCopy( pEnt->curstate.velocity, args.velocity ); } CL_QueueEvent( FEV_RELIABLE|FEV_SERVER, event_index, delay, &args ); }
/* ============= CL_PlaybackEvent ============= */ void CL_PlaybackEvent( int flags, const edict_t *pInvoker, word eventindex, float delay, float *origin, float *angles, float fparam1, float fparam2, int iparam1, int iparam2, int bparam1, int bparam2 ) { event_args_t args; int invokerIndex = 0; // first check event for out of bounds if( eventindex < 1 || eventindex > MAX_EVENTS ) { MsgDev( D_ERROR, "CL_PlaybackEvent: invalid eventindex %i\n", eventindex ); return; } if( flags & FEV_SERVER ) { MsgDev( D_WARN, "CL_PlaybackEvent: event with FEV_SERVER flag!\n" ); return; } // check event for precached if( !CL_EventIndex( cl.event_precache[eventindex] )) { MsgDev( D_ERROR, "CL_PlaybackEvent: event %i was not precached\n", eventindex ); return; } flags |= FEV_CLIENT; // it's a client event flags &= ~(FEV_NOTHOST|FEV_HOSTONLY|FEV_GLOBAL); if( delay < 0.0f ) delay = 0.0f; // fixup negative delays invokerIndex = cl.playernum + 1; // only local client can issue client events args.flags = 0; args.entindex = invokerIndex; if( !angles || VectorIsNull( angles )) VectorCopy( cl.refdef.cl_viewangles, args.angles ); else VectorCopy( angles, args.angles ); if( !origin || VectorIsNull( origin )) VectorCopy( cl.frame.local.client.origin, args.origin ); else VectorCopy( origin, args.origin ); VectorCopy( cl.frame.local.client.velocity, args.velocity ); args.ducking = cl.frame.local.playerstate.usehull == 1; args.fparam1 = fparam1; args.fparam2 = fparam2; args.iparam1 = iparam1; args.iparam2 = iparam2; args.bparam1 = bparam1; args.bparam2 = bparam2; CL_QueueEvent( flags, eventindex, delay, &args ); }
/* ============= CL_ParseEvent ============= */ void CL_ParseEvent( sizebuf_t *msg ) { int event_index; int i, num_events; int packet_ent; event_args_t nullargs, args; qboolean has_update; entity_state_t *state; cl_entity_t *pEnt; float delay; Q_memset( &nullargs, 0, sizeof( nullargs )); num_events = BF_ReadUBitLong( msg, 5 ); // parse events queue for( i = 0 ; i < num_events; i++ ) { event_index = BF_ReadUBitLong( msg, MAX_EVENT_BITS ); Q_memset( &args, 0, sizeof( args )); has_update = false; if( BF_ReadOneBit( msg )) { packet_ent = BF_ReadUBitLong( msg, MAX_ENTITY_BITS ); if( BF_ReadOneBit( msg )) { MSG_ReadDeltaEvent( msg, &nullargs, &args ); has_update = true; } } else packet_ent = -1; if( packet_ent != -1 ) state = &cls.packet_entities[(cl.frame.first_entity+packet_ent)%cls.num_client_entities]; else state = NULL; // it's a client. Override some params if( args.entindex >= 1 && args.entindex <= cl.maxclients ) { if(( args.entindex - 1 ) == cl.playernum ) { if( state && !CL_IsPredicted( )) { // restore viewangles from angles args.angles[PITCH] = -state->angles[PITCH] * 3; args.angles[YAW] = state->angles[YAW]; args.angles[ROLL] = 0; // no roll } else { // get the predicted angles VectorCopy( cl.refdef.cl_viewangles, args.angles ); } VectorCopy( cl.frame.local.client.origin, args.origin ); VectorCopy( cl.frame.local.client.velocity, args.velocity ); } else if( state ) { // restore viewangles from angles args.angles[PITCH] = -state->angles[PITCH] * 3; args.angles[YAW] = state->angles[YAW]; args.angles[ROLL] = 0; // no roll // if we restore origin and velocity everytime, why don't do it here also? if( VectorIsNull( args.origin )) VectorCopy( state->origin, args.origin ); if( VectorIsNull( args.velocity )) VectorCopy( state->velocity, args.velocity ); } } else if( state ) { if( VectorIsNull( args.origin )) VectorCopy( state->origin, args.origin ); if( VectorIsNull( args.angles )) VectorCopy( state->angles, args.angles ); if( VectorIsNull( args.velocity )) VectorCopy( state->velocity, args.velocity ); } else if(( pEnt = CL_GetEntityByIndex( args.entindex )) != NULL ) { if( VectorIsNull( args.origin )) VectorCopy( pEnt->curstate.origin, args.origin ); if( VectorIsNull( args.angles )) VectorCopy( pEnt->curstate.angles, args.angles ); if( VectorIsNull( args.velocity )) VectorCopy( pEnt->curstate.velocity, args.velocity ); } if( BF_ReadOneBit( msg )) delay = (float)BF_ReadWord( msg ) * (1.0f / 100.0f); else delay = 0.0f; // g-cont. should we need find the event with same index? CL_QueueEvent( 0, event_index, delay, &args ); } }
void EngineWrapper::CL_QueueEvent(int flags, int index, float delay, event_args_t *pargs) { #ifndef SWDS CL_QueueEvent(flags, index, delay, pargs); #endif // SWDS }