qboolean CL_AddVisibleEntity( cl_entity_t *ent, int entityType ) { if( !ent || !ent->model ) return false; if( entityType == ET_TEMPENTITY ) { // copy actual origin and angles back to let StudioModelRenderer // get actual value directly from curstate VectorCopy( ent->origin, ent->curstate.origin ); VectorCopy( ent->angles, ent->curstate.angles ); } if( CL_IsInMenu( ) && ( !cl.background || ent->player )) { // menu entities ignores client filter if( !R_AddEntity( ent, entityType )) return false; } else { // check for adding this entity if( !clgame.dllFuncs.pfnAddEntity( entityType, ent, ent->model->name )) return false; // don't add himself on firstperson if( RP_LOCALCLIENT( ent ) && !cl.thirdperson && cls.key_dest != key_menu && cl.refdef.viewentity == ( cl.playernum + 1 )) { if( gl_allow_mirrors->integer && world.has_mirrors ) { if( !R_AddEntity( ent, entityType )) return false; } // otherwise just pass to player effects like flashlight, particles etc } else if( entityType == ET_BEAM ) { CL_AddCustomBeam( ent ); return true; } else if( !R_AddEntity( ent, entityType )) { return false; } } // set actual entity type ent->curstate.entityType = entityType; // apply effects if( ent->curstate.effects & EF_BRIGHTFIELD ) CL_EntityParticles( ent ); // add in muzzleflash effect if( ent->curstate.effects & EF_MUZZLEFLASH ) { dlight_t *dl; if( ent == &clgame.viewent ) ent->curstate.effects &= ~EF_MUZZLEFLASH; dl = CL_AllocElight( 0 ); VectorCopy( ent->attachment[0], dl->origin ); dl->die = cl.time + 0.05f; dl->color.r = 255; dl->color.g = 180; dl->color.b = 64; dl->radius = 100; } // add light effect if( ent->curstate.effects & EF_LIGHT ) { dlight_t *dl = CL_AllocDlight( ent->curstate.number ); VectorCopy( ent->origin, dl->origin ); dl->die = cl.time; // die at next frame dl->color.r = 100; dl->color.g = 100; dl->color.b = 100; dl->radius = 200; CL_RocketFlare( ent->origin ); } // add dimlight if( ent->curstate.effects & EF_DIMLIGHT ) { if( entityType == ET_PLAYER ) { CL_UpdateFlashlight( ent ); } else { dlight_t *dl = CL_AllocDlight( ent->curstate.number ); VectorCopy( ent->origin, dl->origin ); dl->die = cl.time; // die at next frame dl->color.r = 255; dl->color.g = 255; dl->color.b = 255; dl->radius = Com_RandomLong( 200, 230 ); } } if( ent->curstate.effects & EF_BRIGHTLIGHT ) { dlight_t *dl = CL_AllocDlight( 0 ); VectorSet( dl->origin, ent->origin[0], ent->origin[1], ent->origin[2] + 16.0f ); dl->die = cl.time + 0.001f; // die at next frame dl->color.r = 255; dl->color.g = 255; dl->color.b = 255; if( entityType == ET_PLAYER ) dl->radius = 430; else dl->radius = Com_RandomLong( 400, 430 ); } if( ent->model->type == mod_studio ) { if( ent->model->flags & STUDIO_ROTATE ) ent->angles[1] = anglemod( 100.0f * cl.time ); if( ent->model->flags & STUDIO_GIB ) CL_RocketTrail( ent->prevstate.origin, ent->curstate.origin, 2 ); else if( ent->model->flags & STUDIO_ZOMGIB ) CL_RocketTrail( ent->prevstate.origin, ent->curstate.origin, 4 ); else if( ent->model->flags & STUDIO_TRACER ) CL_RocketTrail( ent->prevstate.origin, ent->curstate.origin, 3 ); else if( ent->model->flags & STUDIO_TRACER2 ) CL_RocketTrail( ent->prevstate.origin, ent->curstate.origin, 5 ); else if( ent->model->flags & STUDIO_ROCKET ) { dlight_t *dl = CL_AllocDlight( ent->curstate.number ); VectorCopy( ent->origin, dl->origin ); dl->color.r = 255; dl->color.g = 255; dl->color.b = 255; // HACKHACK: get radius from head entity if( ent->curstate.rendermode != kRenderNormal ) dl->radius = max( 0, ent->curstate.renderamt - 55 ); else dl->radius = 200; dl->die = cl.time + 0.01f; CL_RocketTrail( ent->prevstate.origin, ent->curstate.origin, 0 ); } else if( ent->model->flags & STUDIO_GRENADE ) CL_RocketTrail( ent->prevstate.origin, ent->curstate.origin, 1 ); else if( ent->model->flags & STUDIO_TRACER3 ) CL_RocketTrail( ent->prevstate.origin, ent->curstate.origin, 6 ); } return true; }
void R_Strobe_Tick( void ) { double delta, delta2; double currentTime = Sys_DoubleTime( ); static int frameSnapshot = 0; static double recentTime2 = 0.0; static double recentTime = 0.0; static double deltaArray[DEVIATION_SIZE] = {0.0}; if ( CL_IsInMenu( ) || ( !vid_fullscreen->integer && CL_IsInConsole( ) ) ) // Disable when not in fullscreen due to viewport problems { R_Set2DMode( false ); return; } delta2 = currentTime - recentTime2; recentTime2 = currentTime; strobe.elapsedTime = currentTime - strobe.initialTime; /* if (deltaArray[0] == -1.0) { for ( int k = 0; k < ARRAYSIZE( deltaArray ); ++k ) { deltaArray[k] = _currentFPS( ); } } */ if ( strobe.cdTimer >= 0.0 && delta2 > 0.0 ) strobe.cdTimer += delta2; if ( strobe.fCounter - frameSnapshot == 1 ) { deltaArray[strobe.fCounter % ARRAYSIZE( deltaArray )] = _currentFPS( ); strobe.deviation = _standardDeviation( deltaArray, ARRAYSIZE( deltaArray ) ); } frameSnapshot = strobe.fCounter; if ( r_strobe_cooldown->integer > 0 ) { if ( ( strobe.cdTimer > (double)abs( r_strobe_cooldown->integer ) ) && strobe.cdTriggered == true ) { strobe.cdTriggered = false; strobe.cdTimer = -1.0; } if ( strobe.fCounter > ARRAYSIZE( deltaArray ) ) { if ( strobe.deviation > DEVIATION_LIMIT ) { strobe.cdTriggered = true; strobe.cdTimer = 0.0; } } } else { strobe.cdTriggered = false; } if ( ( ( strobe.strobeInterval != r_strobe->integer ) && ( strobe.strobeInterval ) ) || /*((swapInterval != r_strobe_swapinterval->integer) && (swapInterval != 0)) || */ strobe.fCounter == INT_MAX ) { _reset( ); R_Strobe_Tick( ); } strobe.strobeInterval = r_strobe->integer; strobe.swapInterval = r_strobe_swapinterval->integer; if ( ( strobe.strobeInterval == 0 ) || ( ( gl_swapInterval->integer == 0 ) && ( strobe.strobeInterval ) ) || ( strobe.strobeInterval > 25 || strobe.strobeInterval < -25 ) ) { if ( !gl_swapInterval->integer ) MsgDev( D_WARN, "Strobing requires V-SYNC enabled! (gl_swapInterval != 0) \n" ); if ( strobe.strobeInterval ) { Cvar_Set( "r_strobe", "0" ); } R_Set2DMode( false ); return; } if ( ( strobe.fCounter % 2 ) == 0 ) { ++strobe.pCounter; strobe.frameState |= PHASE_POSITIVE; } else { ++strobe.nCounter; strobe.frameState &= ~PHASE_POSITIVE; } if ( strobe.swapInterval < 0 ) strobe.swapInterval = abs( strobe.swapInterval ); if ( ( strobe.swapInterval ) && ( strobe.strobeInterval % 2 ) ) // Swapping not enabled for even intervals as it is neither necessary nor works as intended { delta = currentTime - recentTime; if ( ( delta >= (double)( strobe.swapInterval ) ) && ( delta < (double)( 2 * strobe.swapInterval ) ) ) // Basic timer { strobe.frameState |= PHASE_INVERTED; } else if ( delta < (double)( strobe.swapInterval ) ) { strobe.frameState &= ~PHASE_INVERTED; } else //if (delta >= (double)(2 * swapInterval)) { recentTime = currentTime; } } switch ( strobe.frameState & ( PHASE_POSITIVE | PHASE_INVERTED ) ) { case ( PHASE_POSITIVE | PHASE_INVERTED ): if ( ( abs( strobe.strobeInterval ) % 2 ) == 0 ) strobe.frameState = ( ( ( strobe.pCounter - 1 ) % ( abs( strobe.strobeInterval ) + 1 ) ) == ( abs( strobe.strobeInterval ) / 2 ) ) ? strobe.frameState | FRAME_RENDER : strobe.frameState & ~FRAME_RENDER; //even else strobe.frameState &= ~FRAME_RENDER; break; case ( PHASE_POSITIVE & ~PHASE_INVERTED ): if ( abs( strobe.strobeInterval ) % 2 == 0 ) strobe.frameState = ( ( ( strobe.pCounter - 1 ) % ( abs( strobe.strobeInterval ) + 1 ) ) == 0 ) ? strobe.frameState | FRAME_RENDER : strobe.frameState & ~FRAME_RENDER; //even else { if ( abs( strobe.strobeInterval ) == 1 ) strobe.frameState |= FRAME_RENDER; else strobe.frameState = ( ( ( strobe.pCounter - 1 ) % ( ( abs( strobe.strobeInterval ) + 1 ) / 2 ) ) == 0 ) ? strobe.frameState | FRAME_RENDER : strobe.frameState & ~FRAME_RENDER; //odd } break; case ( ~PHASE_POSITIVE & PHASE_INVERTED ): if ( abs( strobe.strobeInterval ) % 2 == 0 ) strobe.frameState = ( ( ( strobe.nCounter - 1 ) % ( abs( strobe.strobeInterval ) + 1 ) ) == 0 ) ? strobe.frameState | FRAME_RENDER : strobe.frameState & ~FRAME_RENDER; //even else { if ( abs( strobe.strobeInterval ) == 1 ) strobe.frameState |= FRAME_RENDER; else strobe.frameState = ( ( ( strobe.nCounter - 1 ) % ( ( abs( strobe.strobeInterval ) + 1 ) / 2 ) ) == 0 ) ? strobe.frameState | FRAME_RENDER : strobe.frameState & ~FRAME_RENDER; //odd } break; case 0: if ( ( abs( strobe.strobeInterval ) % 2 ) == 0 ) strobe.frameState = ( ( ( strobe.nCounter - 1 ) % ( abs( strobe.strobeInterval ) + 1 ) ) == ( abs( strobe.strobeInterval ) / 2 ) ) ? strobe.frameState | FRAME_RENDER : strobe.frameState & ~FRAME_RENDER; //even else strobe.frameState &= ~FRAME_RENDER; break; default: strobe.frameState = ( PHASE_POSITIVE | FRAME_RENDER ); } if ( strobe.strobeInterval < 0 ) strobe.frameState ^= FRAME_RENDER; _processFrame( ); }
/* ================= Host_Error ================= */ void Host_Error( const char *error, ... ) { static char hosterror1[MAX_SYSPATH]; static char hosterror2[MAX_SYSPATH]; static qboolean recursive = false; va_list argptr; if( host.mouse_visible && !CL_IsInMenu( )) { // hide VGUI mouse #ifdef XASH_SDL SDL_ShowCursor( false ); #endif host.mouse_visible = false; } va_start( argptr, error ); Q_vsprintf( hosterror1, error, argptr ); va_end( argptr ); CL_WriteMessageHistory (); // before Q_error call if( host.framecount < 3 ) { Sys_Error( "Host_InitError: %s", hosterror1 ); } else if( host.framecount == host.errorframe ) { Sys_Error( "Host_MultiError: %s", hosterror2 ); return; } else { if( host.developer > 0 ) { UI_SetActiveMenu( false ); Key_SetKeyDest( key_console ); Msg( "^1Host_Error: ^7%s", hosterror1 ); } else MSGBOX2( hosterror1 ); } // host is shutting down. don't invoke infinite loop if( host.state == HOST_SHUTDOWN ) return; if( recursive ) { Msg( "Host_RecursiveError: %s", hosterror2 ); Sys_Error( hosterror1 ); return; // don't multiple executes } recursive = true; Q_strncpy( hosterror2, hosterror1, MAX_SYSPATH ); host.errorframe = host.framecount; // to avoid multple calls per frame Q_sprintf( host.finalmsg, "Server crashed: %s", hosterror1 ); // clear cmd buffer to prevent execution of any commands Cbuf_Clear(); SV_Shutdown( false ); CL_Drop(); // drop clients // recreate world if required CL_ClearEdicts (); // release all models Mod_ClearAll( false ); recursive = false; Host_AbortCurrentFrame(); }