/* ============== ClientEndFrame Called at the end of each server frame for each connected client A fast client will have multiple ClientThink for each ClientEdFrame, while a slow client may have multiple ClientEndFrame between ClientThink. ============== */ void ClientEndFrame( gentity_t *ent ) { if ( G_IsClientSpectating ( ent->client ) ) { SpectatorClientEndFrame( ent ); return; } clientPersistant_t *pers = &ent->client->pers; // // If the end of unit layout is displayed, don't give // the player any normal movement attributes // if ( level.intermissiontime ) { return; } // burn from lava, etc P_WorldEffects (ent); // apply all the damage taken this frame P_DamageFeedback (ent); // add the EF_CONNECTION flag if we haven't gotten commands recently if ( level.time - ent->client->lastCmdTime > 1000 ) { ent->s.eFlags |= EF_CONNECTION; } else { ent->s.eFlags &= ~EF_CONNECTION; } // FIXME: get rid of ent->health... ent->client->ps.stats[STAT_HEALTH] = ent->health; G_SetClientSound (ent); // set the latest infor if (g_smoothClients.integer) { BG_PlayerStateToEntityStateExtraPolate( &ent->client->ps, &ent->s, ent->client->ps.commandTime, true ); } else { BG_PlayerStateToEntityState( &ent->client->ps, &ent->s, true ); } SendPendingPredictableEvents( &ent->client->ps ); // set the bit for the reachability area the client is currently in // i = trap_AAS_PointReachabilityAreaIndex( ent->client->ps.origin ); // ent->client->areabits[i >> 3] |= 1 << (i & 7); }
/* ============== ClientEndFrame Called at the end of each server frame for each connected client A fast client will have multiple ClientThink for each ClientEdFrame, while a slow client may have multiple ClientEndFrame between ClientThink. ============== */ void ClientEndFrame( gentity_t *ent ) { clientPersistant_t *pers; if( ent->client->sess.sessionTeam == TEAM_SPECTATOR ) { SpectatorClientEndFrame( ent ); return; } pers = &ent->client->pers; // // If the end of unit layout is displayed, don't give // the player any normal movement attributes // if( level.intermissiontime ) return; // burn from lava, etc P_WorldEffects( ent ); // apply all the damage taken this frame P_DamageFeedback( ent ); // add the EF_CONNECTION flag if we haven't gotten commands recently if( level.time - ent->client->lastCmdTime > 1000 ) ent->s.eFlags |= EF_CONNECTION; else ent->s.eFlags &= ~EF_CONNECTION; ent->client->ps.stats[ STAT_HEALTH ] = ent->health; // FIXME: get rid of ent->health... G_SetClientSound( ent ); // set the latest infor if( g_smoothClients.integer ) BG_PlayerStateToEntityStateExtraPolate( &ent->client->ps, &ent->s, ent->client->ps.commandTime, qtrue ); else BG_PlayerStateToEntityState( &ent->client->ps, &ent->s, qtrue ); SendPendingPredictableEvents( &ent->client->ps ); }
/* ============== ClientEndFrame Called at the end of each server frame for each connected client A fast client will have multiple ClientThink for each ClientEndFrame, while a slow client may have multiple ClientEndFrame between ClientThink. ============== */ void ClientEndFrame(gentity_t *ent) { int i; // Nico, flood protection if (level.time >= (ent->client->sess.nextReliableTime + 1000) && ent->client->sess.numReliableCmds) { ent->client->sess.numReliableCmds--; // Reset the threshold because they were good for a bit if (!ent->client->sess.numReliableCmds) { ent->client->sess.thresholdTime = 0; } } // Nico, update best speeds if (ent->client->sess.timerunActive) { float currentSpeed; currentSpeed = sqrt(ent->client->ps.velocity[0] * ent->client->ps.velocity[0] + ent->client->ps.velocity[1] * ent->client->ps.velocity[1]); // Nico, update overall max speed if (currentSpeed > ent->client->sess.overallMaxSpeed) { ent->client->sess.overallMaxSpeed = currentSpeed; } // Nico, update max speed of the current run if (currentSpeed > ent->client->sess.maxSpeed) { ent->client->sess.maxSpeed = currentSpeed; } } // used for informing of speclocked teams. // Zero out here and set only for certain specs ent->client->ps.powerups[PW_BLACKOUT] = 0; if ((ent->client->sess.sessionTeam == TEAM_SPECTATOR) || (ent->client->ps.pm_flags & PMF_LIMBO)) { // JPW NERVE SpectatorClientEndFrame(ent); return; } // turn off any expired powerups // OSP -- range changed for MV for (i = 0 ; i < PW_NUM_POWERUPS ; ++i) { if (i == PW_FIRE || // these aren't dependant on level.time i == PW_ELECTRIC || i == PW_BREATHER || ent->client->ps.powerups[i] == 0 // OSP || i == PW_OPS_CLASS_1 || i == PW_OPS_CLASS_2 || i == PW_OPS_CLASS_3 ) { continue; } // OSP -- If we're paused, update powerup timers accordingly. // Make sure we dont let stuff like CTF flags expire. if (ent->client->ps.powerups[i] < level.time) { ent->client->ps.powerups[i] = 0; } } // // If the end of unit layout is displayed, don't give // the player any normal movement attributes // // burn from lava, etc P_WorldEffects(ent); // apply all the damage taken this frame P_DamageFeedback(ent); // add the EF_CONNECTION flag if we haven't gotten commands recently if (level.time - ent->client->lastCmdTime > 1000) { ent->s.eFlags |= EF_CONNECTION; } else { ent->s.eFlags &= ~EF_CONNECTION; } ent->client->ps.stats[STAT_HEALTH] = ent->health; // FIXME: get rid of ent->health... // Gordon: WHY? other ents use it. G_SetClientSound(ent); // set the latest infor // Ridah, fixes jittery zombie movement if (g_smoothClients.integer) { BG_PlayerStateToEntityStateExtraPolate(&ent->client->ps, &ent->s, level.time, qfalse); } else { BG_PlayerStateToEntityState(&ent->client->ps, &ent->s, qfalse); } // DHM - Nerve :: If it's been a couple frames since being revived, and props_frame_state // wasn't reset, go ahead and reset it if (ent->props_frame_state >= 0 && ((level.time - ent->s.effect3Time) > 100)) { ent->props_frame_state = -1; } // DHM - Nerve :: Reset 'count2' for flamethrower if (!(ent->client->buttons & BUTTON_ATTACK)) { ent->count2 = 0; } // dhm // zinx - #280 - run touch functions here too, so movers don't have to wait // until the next ClientThink, which will be too late for some map // scripts (railgun) G_TouchTriggers(ent); // run entity scripting G_Script_ScriptRun(ent); // store the client's current position for antilag traces G_StoreClientPosition(ent); }
/* ============== ClientEndFrame Called at the end of each server frame for each connected client A fast client will have multiple ClientThink for each ClientEdFrame, while a slow client may have multiple ClientEndFrame between ClientThink. ============== */ void ClientEndFrame(gentity_t * ent) { int i, frames; // clientPersistant_t *pers; if (ent->client->sess.sessionTeam == TEAM_SPECTATOR) { SpectatorClientEndFrame(ent); return; } // pers = &ent->client->pers; // turn off any expired powerups for (i = 0; i < MAX_POWERUPS; i++) { if (ent->client->ps.powerups[i] < level.time) { ent->client->ps.powerups[i] = 0; } } // save network bandwidth #if 0 if (!g_synchronousClients->integer && ent->client->ps.pm_type == PM_NORMAL) { // FIXME: this must change eventually for non-sync demo recording VectorClear(ent->client->ps.viewangles); } #endif // // If the end of unit layout is displayed, don't give // the player any normal movement attributes // if (level.intermissiontime) { return; } if (ent->client->bleeding) CheckBleeding(ent); // perform once-a-second actions // burn from lava, etc P_WorldEffects(ent); // apply all the damage taken this frame P_DamageFeedback(ent); // Update the clips Amount in weapon for the client ent->client->ps.stats[STAT_CLIPS] = ent->client->numClips[ent->client->ps.weapon]; ent->client->ps.stats[STAT_HEALTH] = ent->health; // FIXME: get rid of ent->health... //Elder: bleeding notification if (ent->client->bleeding || (ent->client->ps.stats[STAT_RQ3] & RQ3_LEGDAMAGE) == RQ3_LEGDAMAGE) { ent->client->ps.stats[STAT_RQ3] |= RQ3_BANDAGE_NEED; } else { ent->client->ps.stats[STAT_RQ3] &= ~RQ3_BANDAGE_NEED; } //Moved to pmove.c //Elder: M4 ride-up/kick -- condition for non-burst and ammo only if (ent->client->consecutiveShots && (ent->client->ps.ammo[WP_M4] <= 0 || ent->client->ps.weaponstate != WEAPON_FIRING)) { //Restore view after shots if not firing ent->client->ps.delta_angles[0] = ANGLE2SHORT(SHORT2ANGLE(ent->client->ps.delta_angles[0]) - ent->client->consecutiveShots * -0.8);//-0.7f); ent->client->consecutiveShots = 0; } // Check to reset our openDoor boolean if (ent->client->openDoorTime && level.time - ent->client->openDoorTime > MAXDOORTIME) { ent->client->openDoor = qfalse; ent->client->openDoorTime = 0; } // JBravo: multiple items if (ent->client->ps.stats[STAT_HOLDABLE_ITEM] & (1 << HI_LASER)) { //Try to turn the laser on if it's off if (ent->client->lasersight == NULL) Laser_Gen(ent, qtrue); } //Slicer if (ent->client->weapon_attempts > 0) Cmd_Weapon(ent); G_SetClientSound(ent); BG_PlayerStateToEntityState(&ent->client->ps, &ent->s, qtrue); SendPendingPredictableEvents(&ent->client->ps); // JBravo: unlagged ent->client->ps.eFlags &= ~EF_CONNECTION; frames = level.framenum - ent->client->lastUpdateFrame - 1; if (frames > 2) { frames = 2; ent->client->ps.eFlags |= EF_CONNECTION; ent->s.eFlags |= EF_CONNECTION; } if (frames > 0 && g_smoothClients.integer) { G_PredictPlayerMove(ent, (float)frames / sv_fps.integer); SnapVector(ent->s.pos.trBase); } }
/* ============== ClientEndFrame Called at the end of each server frame for each connected client A fast client will have multiple ClientThink for each ClientEndFrame, while a slow client may have multiple ClientEndFrame between ClientThink. ============== */ void ClientEndFrame( gentity_t *ent ) { int i; if ( ( ent->client->sess.sessionTeam == TEAM_SPECTATOR ) || ( ent->client->ps.pm_flags & PMF_LIMBO ) ) { // JPW NERVE SpectatorClientEndFrame( ent ); return; } if ( !ent->aiCharacter ) { // turn off any expired powerups for ( i = 0 ; i < MAX_POWERUPS ; i++ ) { if ( i == PW_FIRE || // these aren't dependant on level.time i == PW_ELECTRIC || i == PW_BREATHER || i == PW_NOFATIGUE ) { continue; } if ( ent->client->ps.powerups[ i ] < level.time ) { ent->client->ps.powerups[ i ] = 0; } } } // save network bandwidth #if 0 if ( !g_synchronousClients->integer && ent->client->ps.pm_type == PM_NORMAL ) { // FIXME: this must change eventually for non-sync demo recording VectorClear( ent->client->ps.viewangles ); } #endif // // If the end of unit layout is displayed, don't give // the player any normal movement attributes // if ( level.intermissiontime ) { return; } // burn from lava, etc P_WorldEffects( ent ); // apply all the damage taken this frame P_DamageFeedback( ent ); // add the EF_CONNECTION flag if we haven't gotten commands recently if ( level.time - ent->client->lastCmdTime > 1000 ) { ent->s.eFlags |= EF_CONNECTION; } else { ent->s.eFlags &= ~EF_CONNECTION; } ent->client->ps.stats[STAT_HEALTH] = ent->health; // FIXME: get rid of ent->health... G_SetClientSound( ent ); // set the latest infor // Ridah, fixes jittery zombie movement if ( g_smoothClients.integer ) { BG_PlayerStateToEntityStateExtraPolate( &ent->client->ps, &ent->s, ent->client->ps.commandTime, ( ( ent->r.svFlags & SVF_CASTAI ) == 0 ) ); } else { BG_PlayerStateToEntityState( &ent->client->ps, &ent->s, ( ( ent->r.svFlags & SVF_CASTAI ) == 0 ) ); } //SendPendingPredictableEvents( &ent->client->ps ); // DHM - Nerve :: If it's been a couple frames since being revived, and props_frame_state // wasn't reset, go ahead and reset it if ( ent->props_frame_state >= 0 && ( ( level.time - ent->s.effect3Time ) > 100 ) ) { ent->props_frame_state = -1; } if ( ent->health > 0 && StuckInClient( ent ) ) { G_DPrintf( "%s is stuck in a client.\n", ent->client->pers.netname ); ent->r.contents = CONTENTS_CORPSE; } if ( g_gametype.integer >= GT_WOLF && ent->health > 0 && ent->r.contents == CONTENTS_CORPSE ) { WolfReviveBbox( ent ); } // DHM - Nerve :: Reset 'count2' for flamethrower if ( !( ent->client->buttons & BUTTON_ATTACK ) ) { ent->count2 = 0; } // dhm }
/* ============== ClientEndFrame Called at the end of each server frame for each connected client A fast client will have multiple ClientThink for each ClientEdFrame, while a slow client may have multiple ClientEndFrame between ClientThink. ============== */ void ClientEndFrame( gentity_t *ent ) { int i; clientPersistant_t *pers; if ( ent->client->sess.sessionTeam == TEAM_SPECTATOR ) { SpectatorClientEndFrame( ent ); return; } pers = &ent->client->pers; // turn off any expired powerups for ( i = 0 ; i < MAX_POWERUPS ; i++ ) { if ( ent->client->ps.powerups[ i ] < level.time ) { ent->client->ps.powerups[ i ] = 0; } } // save network bandwidth #if 0 if ( !g_synchronousClients->integer && (ent->client->ps.pm_type == PM_NORMAL || ent->client->ps.pm_type == PM_FLOAT) ) { // FIXME: this must change eventually for non-sync demo recording VectorClear( ent->client->ps.viewangles ); } #endif // // If the end of unit layout is displayed, don't give // the player any normal movement attributes // if ( level.intermissiontime ) { return; } // burn from lava, etc P_WorldEffects (ent); // apply all the damage taken this frame P_DamageFeedback (ent); // add the EF_CONNECTION flag if we haven't gotten commands recently if ( level.time - ent->client->lastCmdTime > 1000 ) { ent->s.eFlags |= EF_CONNECTION; } else { ent->s.eFlags &= ~EF_CONNECTION; } ent->client->ps.stats[STAT_HEALTH] = ent->health; // FIXME: get rid of ent->health... G_SetClientSound (ent); // set the latest infor if (g_smoothClients.integer) { BG_PlayerStateToEntityStateExtraPolate( &ent->client->ps, &ent->s, ent->client->ps.commandTime, qtrue ); } else { BG_PlayerStateToEntityState( &ent->client->ps, &ent->s, qtrue ); } SendPendingPredictableEvents( &ent->client->ps ); // set the bit for the reachability area the client is currently in // i = trap_AAS_PointReachabilityAreaIndex( ent->client->ps.origin ); // ent->client->areabits[i >> 3] |= 1 << (i & 7); }