Beispiel #1
0
/*
==============
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;

	// 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;
		}
	}

	//
	// 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...

//	G_SetClientSound (ent);
}
Beispiel #2
0
/*
==============
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);
}
Beispiel #3
0
/*
==============
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 );
}
Beispiel #4
0
void ClientEndServerFrame (edict_t *ent)
{
	float	bobtime;
	int		i;

	current_player = ent;
	current_client = ent->client;

	//
	// If the origin or velocity have changed since ClientThink(),
	// update the pmove values.  This will happen when the client
	// is pushed by a bmodel or kicked by an explosion.
	// 
	// If it wasn't updated here, the view position would lag a frame
	// behind the body position when pushed -- "sinking into plats"
	//
	for (i=0 ; i<3 ; i++)
	{
		current_client->ps.pmove.origin[i] = ent->s.origin[i]*8.0;
		current_client->ps.pmove.velocity[i] = ent->velocity[i]*8.0;
	}

	//
	// If the end of unit layout is displayed, don't give
	// the player any normal movement attributes
	//
	if (level.intermissiontime)
	{
		// FIXME: add view drifting here?
		current_client->ps.blend[3] = 0;
		current_client->ps.fov = 90;
		G_SetStats (ent);
		return;
	}

	AngleVectors (ent->client->v_angle, forward, right, up);

	// burn from lava, etc
	P_WorldEffects ();

	//
	// set model angles from view angles so other things in
	// the world can tell which direction you are looking
	//
	if (ent->client->v_angle[PITCH] > 180)
		ent->s.angles[PITCH] = (-360 + ent->client->v_angle[PITCH])/3;
	else
		ent->s.angles[PITCH] = ent->client->v_angle[PITCH]/3;
	ent->s.angles[YAW] = ent->client->v_angle[YAW];
	ent->s.angles[ROLL] = 0;
	ent->s.angles[ROLL] = SV_CalcRoll (ent->s.angles, ent->velocity)*4;

	//
	// calculate speed and cycle to be used for
	// all cyclic walking effects
	//
	xyspeed = sqrt(ent->velocity[0]*ent->velocity[0] + ent->velocity[1]*ent->velocity[1]);

	if (xyspeed < 5)
	{
		bobmove = 0;
		current_client->bobtime = 0;	// start at beginning of cycle again
	}
	//Kngightmare- exception for wading
	else if (ent->groundentity || ent->waterlevel == 2)
	{	// so bobbing only cycles when on ground
		if (xyspeed > 450) // Knightmare added
			bobmove = 0.50;
		else if (xyspeed > 210)
			bobmove = 0.25;
		else if (!ent->groundentity && ent->waterlevel == 2 && xyspeed > 100)
			bobmove = 0.45;
		else if (xyspeed > 100)
			bobmove = 0.125;
		else if (!ent->groundentity && ent->waterlevel == 2)
			bobmove = 0.325;
		else
			bobmove = 0.0625;
	}
	
	bobtime = (current_client->bobtime += bobmove);

	if (current_client->ps.pmove.pm_flags & PMF_DUCKED)
		bobtime *= 4;

	bobcycle = (int)bobtime;

	// Lazarus: vehicle drivers don't bob
	if(ent->vehicle)
		bobfracsin = 0.;
	else
		bobfracsin = fabs(sin(bobtime*M_PI));

	// detect hitting the floor
	P_FallingDamage (ent);

	// Lazarus: detect hitting walls
	P_SlamDamage (ent);

	// apply all the damage taken this frame
	P_DamageFeedback (ent);

	// determine the view offsets
	SV_CalcViewOffset (ent);

	// determine the gun offsets
	SV_CalcGunOffset (ent);

	// determine the full screen color blend
	// must be after viewoffset, so eye contents can be
	// accurately determined
	// FIXME: with client prediction, the contents
	// should be determined by the client
	SV_CalcBlend (ent);

	// chase cam stuff
	if (ent->client->resp.spectator)
		G_SetSpectatorStats(ent);
//ZOID
	else //if (!ent->client->chase_target)
//ZOID
		G_SetStats (ent);

	G_CheckChaseStats(ent);

	G_SetClientEvent (ent);

	G_SetClientEffects (ent);

	G_SetClientSound (ent);

	G_SetClientFrame (ent);

	VectorCopy (ent->velocity, ent->client->oldvelocity);
	VectorCopy (ent->client->ps.viewangles, ent->client->oldviewangles);

	// clear weapon kicks
	VectorClear (ent->client->kick_origin);
	VectorClear (ent->client->kick_angles);

	// if the scoreboard is up, update it
	if (!(level.framenum & 31))
	{
		if (ent->client->showscores)
		{
			if (ent->client->menu)
			{
			//	PMenu_Update(ent);
				PMenu_Do_Update(ent);
				ent->client->menudirty = false;
				ent->client->menutime = level.time;
			}
			else if (ent->client->textdisplay)
				Text_Update(ent);
			else
				DeathmatchScoreboardMessage (ent, ent->enemy);
			gi.unicast (ent, false);
		}
		else if(ent->client->whatsit)
			WhatsIt(ent);
	}

	// tpp
	if (ent->client->chasetoggle == 1)
		CheckChasecam_Viewent(ent);
	// end tpp

}
Beispiel #5
0
/*
 * Called for each player at the end of
 * the server frame and right after spawning
 */
void
ClientEndServerFrame(edict_t *ent)
{
	float bobtime;
	int i;

  	if (!ent)
	{
		return;
	}

	current_player = ent;
	current_client = ent->client;

    /* If the origin or velocity have changed since ClientThink(),
	   update the pmove values. This will happen when the client
	   is pushed by a bmodel or kicked by an explosion.
	   If it wasn't updated here, the view position would lag a frame
	   behind the body position when pushed -- "sinking into plats" */
	for (i = 0; i < 3; i++)
	{
		current_client->ps.pmove.origin[i] = ent->s.origin[i] * 8.0;
		current_client->ps.pmove.velocity[i] = ent->velocity[i] * 8.0;
	}

	/* If the end of unit layout is displayed, don't give
	   the player any normal movement attributes */
	if (level.intermissiontime)
	{
		current_client->ps.blend[3] = 0;
		current_client->ps.fov = 90;
		G_SetStats(ent);
		return;
	}

	AngleVectors(ent->client->v_angle, forward, right, up);

	/* burn from lava, etc */
	P_WorldEffects();

    /* set model angles from view angles so other things in
	   the world can tell which direction you are looking */
	if (ent->client->v_angle[PITCH] > 180)
	{
		ent->s.angles[PITCH] = (-360 + ent->client->v_angle[PITCH]) / 3;
	}
	else
	{
		ent->s.angles[PITCH] = ent->client->v_angle[PITCH] / 3;
	}

	ent->s.angles[YAW] = ent->client->v_angle[YAW];
	ent->s.angles[ROLL] = 0;
	ent->s.angles[ROLL] = SV_CalcRoll(ent->s.angles, ent->velocity) * 4;

	/* calculate speed and cycle to be used for
	   all cyclic walking effects */
	xyspeed = sqrt(ent->velocity[0] * ent->velocity[0] +
			ent->velocity[1] * ent->velocity[1]);

	if (xyspeed < 5)
	{
		bobmove = 0;
		current_client->bobtime = 0; /* start at beginning of cycle again */
	}
	else if (ent->groundentity)
	{
		/* so bobbing only cycles when on ground */
		if (xyspeed > 210)
		{
			bobmove = 0.25;
		}
		else if (xyspeed > 100)
		{
			bobmove = 0.125;
		}
		else
		{
			bobmove = 0.0625;
		}
	}

	bobtime = (current_client->bobtime += bobmove);

	if (current_client->ps.pmove.pm_flags & PMF_DUCKED)
	{
		bobtime *= 4;
	}

	bobcycle = (int)bobtime;
	bobfracsin = fabs(sin(bobtime * M_PI));

	/* detect hitting the floor */
	P_FallingDamage(ent);

	/* apply all the damage taken this frame */
	P_DamageFeedback(ent);

	/* determine the view offsets */
	SV_CalcViewOffset(ent);

	/* determine the gun offsets */
	SV_CalcGunOffset(ent);

	/* determine the full screen color blend
	   must be after viewoffset, so eye contents
	   can be accurately determined */
	SV_CalcBlend(ent);

	/* chase cam stuff */
	if (ent->client->resp.spectator)
	{
		G_SetSpectatorStats(ent);
	}
	else
	{
		G_SetStats(ent);
	}

	G_CheckChaseStats(ent);
	G_SetClientEvent(ent);
	G_SetClientEffects(ent);
	G_SetClientSound(ent);
	G_SetClientFrame(ent);

	VectorCopy(ent->velocity, ent->client->oldvelocity);
	VectorCopy(ent->client->ps.viewangles, ent->client->oldviewangles);

	/* clear weapon kicks */
	VectorClear(ent->client->kick_origin);
	VectorClear(ent->client->kick_angles);

	if (!(level.framenum & 31))
	{
		/* if the scoreboard is up, update it */
		if (ent->client->showscores)
		{
			DeathmatchScoreboardMessage(ent, ent->enemy);
			gi.unicast(ent, false);
		}

		/* if the help computer is up, update it */
		if (ent->client->showhelp)
		{
			ent->client->pers.helpchanged = 0;
			HelpComputerMessage(ent);
			gi.unicast(ent, false);
		}
	}

	/* if the inventory is up, update it */
	if (ent->client->showinventory)
	{
		InventoryMessage(ent);
		gi.unicast(ent, false);
	}
}
Beispiel #6
0
/*
==============
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);
}
Beispiel #7
0
/*
=================
ClientEndServerFrame

Called for each player at the end of the server frame
and right after spawning
=================
*/
void ClientEndServerFrame (edict_t *ent)
{
	float	bobtime;
	int		i, updateFrame;

	current_player = ent;
	current_client = ent->client;

	//
	// If the origin or velocity have changed since ClientThink(),
	// update the pmove values.  This will happen when the client
	// is pushed by a bmodel or kicked by an explosion.
	// 
	// If it wasn't updated here, the view position would lag a frame
	// behind the body position when pushed -- "sinking into plats"
	//
	for (i=0 ; i<3 ; i++)
	{
		current_client->ps.pmove.origin[i] = ent->s.origin[i]*8.0;
		current_client->ps.pmove.velocity[i] = ent->velocity[i]*8.0;
	}

	//
	// If the end of unit layout is displayed, don't give
	// the player any normal movement attributes
	//
	if (level.intermissiontime)
	{
		// FIXME: add view drifting here?
		current_client->ps.blend[3] = 0;
		current_client->ps.fov = 90;
		G_SetStats (ent);
		return;
	}

	AngleVectors (ent->client->v_angle, forward, right, up);

	// burn from lava, etc
	P_WorldEffects ();

	//
	// set model angles from view angles so other things in
	// the world can tell which direction you are looking
	//
	if (ent->client->v_angle[PITCH] > 180)
		ent->s.angles[PITCH] = (-360 + ent->client->v_angle[PITCH])/3;
	else
		ent->s.angles[PITCH] = ent->client->v_angle[PITCH]/3;
	//GHz START
	// monsters don't use pitch
	if (ent->mtype)
		ent->s.angles[PITCH] = 0;
	//GHz END
	ent->s.angles[YAW] = ent->client->v_angle[YAW];
	ent->s.angles[ROLL] = 0;
	ent->s.angles[ROLL] = SV_CalcRoll (ent->s.angles, ent->velocity)*4;

	//
	// calculate speed and cycle to be used for
	// all cyclic walking effects
	//
	xyspeed = sqrt(ent->velocity[0]*ent->velocity[0] + ent->velocity[1]*ent->velocity[1]);

	if (xyspeed < 5)
	{
		bobmove = 0;
		current_client->bobtime = 0;	// start at beginning of cycle again
	}
	else if (ent->groundentity)
	{	// so bobbing only cycles when on ground
		if (xyspeed > 210)
			bobmove = 0.25;
		else if (xyspeed > 100)
			bobmove = 0.125;
		else
			bobmove = 0.0625;
	}
	
	bobtime = (current_client->bobtime += bobmove);

	if (current_client->ps.pmove.pm_flags & PMF_DUCKED)
		bobtime *= 4;

	bobcycle = (int)bobtime;
	bobfracsin = fabs(sin(bobtime*M_PI));

	// detect hitting the floor
	P_FallingDamage (ent);

	// apply all the damage taken this frame
	P_DamageFeedback (ent);

	// determine the view offsets
	SV_CalcViewOffset (ent);

	// determine the gun offsets
	SV_CalcGunOffset (ent);

	// determine the full screen color blend
	// must be after viewoffset, so eye contents can be
	// accurately determined
	// FIXME: with client prediction, the contents
	// should be determined by the client
	SV_CalcBlend (ent);

	// chase cam stuff
	if (ent->client->resp.spectator)
		G_SetSpectatorStats(ent);
	else
		G_SetStats (ent);

	G_CheckChaseStats(ent);

	G_SetClientEvent (ent);

	G_SetClientEffects (ent);

	G_SetClientSound (ent);

	G_SetClientFrame (ent);

	VectorCopy (ent->velocity, ent->client->oldvelocity);
	VectorCopy (ent->client->ps.viewangles, ent->client->oldviewangles);

	// clear weapon kicks
	VectorClear (ent->client->kick_origin);
	VectorClear (ent->client->kick_angles);

	if (ent->client->pers.scanner_active & 1)
		updateFrame = SCANNER_UPDATE_FREQ;
	else
		updateFrame = 31;

	// if the scoreboard is up, update it
	//if (ent->client->showscores && !(level.framenum & 31) && !ent->client->menustorage.menu_active)
	if (((ent->client->showscores || ent->client->pers.scanner_active) && !ent->client->menustorage.menu_active && !ent->client->show_allyinfo
		&& !(level.framenum % updateFrame)) || (ent->client->pers.scanner_active & 2))
	{
		DeathmatchScoreboardMessage (ent, ent->enemy);
		gi.unicast (ent, false);
	}
	else if (ent->client->show_allyinfo && !(level.framenum%10))
	{
		ShowAllyInfo(ent);
	}
	//GHz START
	else if (!ent->client->showscores && ent->client->menustorage.menu_active)
	{
		closemenu(ent);
	}
	//GHz END

//	P_FollowWall(ent);
}
Beispiel #8
0
/*
=================
ClientEndServerFrame

Called for each player at the end of the server frame
and right after spawning
=================
*/
void ClientEndServerFrame (edict_t * ent)
{
	float bobtime;
	int i;
	//char player_name[30];
	//char temp[40];
	//        int             damage; // zucc for bleeding

	current_player = ent;
	current_client = ent->client;

	//AQ2:TNG - Slicer : Stuffs the client x seconds after he enters the server, needed for Video check
	if (ent->client->resp.checktime[0] <= level.time)
	{
		ent->client->resp.checktime[0] = level.time + video_checktime->value;
		if (video_check->value || video_check_lockpvs->value
			|| video_check_glclear->value || darkmatch->value)
			stuffcmd (ent, "%!fc $vid_ref\n");
		if (video_force_restart->value && video_check->value && !ent->client->resp.checked)
		{
			stuffcmd (ent, "vid_restart\n");
			ent->client->resp.checked = true;
		}

	}
	if (ent->client->resp.checktime[1] <= level.time)
	{
		ent->client->resp.checktime[1] = level.time + video_checktime->value;
		ent->client->resp.checktime[2] = level.time + 1;
		if (video_check->value || video_check_lockpvs->value
			|| video_check_glclear->value || darkmatch->value)
		{
			if (ent->client->resp.vidref && Q_stricmp(ent->client->resp.vidref, "soft"))
				stuffcmd (ent, "%cpsi $gl_modulate $gl_lockpvs $gl_clear $gl_dynamic $gl_driver\n");
		}

	}
	if (ent->client->resp.checktime[2] <= level.time)
	{
		// ent->client->resp.checktime[2] = level.time + video_checktime->value;
		if (video_check->value || video_check_lockpvs->value
			|| video_check_glclear->value || darkmatch->value)
		{
			if (ent->client->resp.vidref && Q_stricmp(ent->client->resp.vidref, "soft"))
				VideoCheckClient (ent);
		}

	}

	if(pause_time)
	{
		G_SetStats (ent);
		return;
	}

	//FIREBLADE - Unstick avoidance stuff.
	if (ent->solid == SOLID_TRIGGER && !lights_camera_action)
	{
		edict_t *overlap;
		if ((overlap = FindOverlap (ent, NULL)) == NULL)
		{
			ent->solid = SOLID_BBOX;
			gi.linkentity (ent);
			RemoveFromTransparentList (ent);
		}
		else
		{
			do
			{
				if (overlap->solid == SOLID_BBOX)
				{
					overlap->solid = SOLID_TRIGGER;
					gi.linkentity (overlap);
					AddToTransparentList (overlap);
				}
				overlap = FindOverlap (ent, overlap);
			}
			while (overlap != NULL);
		}
	}
	//FIREBLADE

	//
	// If the origin or velocity have changed since ClientThink(),
	// update the pmove values.  This will happen when the client
	// is pushed by a bmodel or kicked by an explosion.
	// 
	// If it wasn't updated here, the view position would lag a frame
	// behind the body position when pushed -- "sinking into plats"
	//
	for (i = 0; i < 3; i++)
	{
		current_client->ps.pmove.origin[i] = ent->s.origin[i] * 8.0;
		current_client->ps.pmove.velocity[i] = ent->velocity[i] * 8.0;
	}

	//
	// If the end of unit layout is displayed, don't give
	// the player any normal movement attributes
	//
	if (level.intermissiontime)
	{
		// FIXME: add view drifting here?
		current_client->ps.blend[3] = 0;
		current_client->ps.fov = 90;
		G_SetStats (ent);
		return;
	}

	AngleVectors (ent->client->v_angle, forward, right, up);

	// burn from lava, etc
	P_WorldEffects ();

	//
	// set model angles from view angles so other things in
	// the world can tell which direction you are looking
	//
	if (ent->client->v_angle[PITCH] > 180)
		ent->s.angles[PITCH] = (-360 + ent->client->v_angle[PITCH]) / 3;
	else
		ent->s.angles[PITCH] = ent->client->v_angle[PITCH] / 3;
	ent->s.angles[YAW] = ent->client->v_angle[YAW];
	ent->s.angles[ROLL] = 0;
	ent->s.angles[ROLL] = SV_CalcRoll (ent->s.angles, ent->velocity) * 4;

	//
	// calculate speed and cycle to be used for
	// all cyclic walking effects
	//
	xyspeed = sqrt(ent->velocity[0]*ent->velocity[0] + ent->velocity[1]*ent->velocity[1]);

	if (xyspeed < 5 || ent->solid == SOLID_NOT)
	{
		bobmove = 0;
		current_client->bobtime = 0;	// start at beginning of cycle again
	}
	else if (ent->groundentity)
	{	// so bobbing only cycles when on ground
		if (xyspeed > 210)
			bobmove = 0.25;
		else if (xyspeed > 100)
			bobmove = 0.125;
		else
			bobmove = 0.0625;
	}

	bobtime = (current_client->bobtime += bobmove);

	if (current_client->ps.pmove.pm_flags & PMF_DUCKED)
		bobtime *= 4;

	bobcycle = (int) bobtime;
	bobfracsin = fabs (sin (bobtime * M_PI));

	// detect hitting the floor
	P_FallingDamage (ent);

	// zucc handle any bleeding damage here
	Do_Bleeding (ent);

	// apply all the damage taken this frame
	P_DamageFeedback (ent);

	// determine the view offsets
	SV_CalcViewOffset (ent);

	// determine the gun offsets
	SV_CalcGunOffset (ent);

	// determine the full screen color blend
	// must be after viewoffset, so eye contents can be
	// accurately determined
	// FIXME: with client prediction, the contents
	// should be determined by the client
	SV_CalcBlend (ent);

	G_SetStats (ent);

	//FIREBLADE
	for (i = 1; i <= maxclients->value; i++)
	{
		int stats_copy;
		edict_t *e = g_edicts + i;

		if (!ent->inuse || e->client->chase_mode == 0 || e->client->chase_target != ent)
			continue;

		for (stats_copy = 0; stats_copy < MAX_STATS; stats_copy++)
		{
			if (stats_copy >= STAT_TEAM_HEADER && stats_copy <= STAT_TEAM2_SCORE)
				continue;		// protect these
			if (stats_copy >= STAT_TEAM3_PIC && stats_copy <= STAT_TEAM3_SCORE)
				continue;		// protect these
			if (stats_copy == STAT_LAYOUTS || stats_copy == STAT_ID_VIEW)
				continue;		// protect these
			if (stats_copy == STAT_SNIPER_ICON && e->client->chase_mode != 2)
				continue;		// only show sniper lens when in chase mode 2
			if (stats_copy == STAT_FRAGS)
				continue;
			e->client->ps.stats[stats_copy] = ent->client->ps.stats[stats_copy];
		}

	//FB                e->client->ps.stats[STAT_LAYOUTS] = 1;
	//FB                break;
	}
	//FIREBLADE

	G_SetClientEvent (ent);

	G_SetClientEffects (ent);

	G_SetClientSound (ent);

	G_SetClientFrame (ent);

	VectorCopy (ent->velocity, ent->client->oldvelocity);
	VectorCopy (ent->client->ps.viewangles, ent->client->oldviewangles);

	// clear weapon kicks
	VectorClear (ent->client->kick_origin);
	VectorClear (ent->client->kick_angles);


	// zucc - clear the open door command
	ent->client->doortoggle = 0;

	if (ent->client->push_timeout > 0)
		ent->client->push_timeout--;
  /*              else
	 {
	 ent->client->attacker = NULL;
	 ent->client->attacker_mod = MOD_BLEEDING;
	 }
   */
	if (ent->client->reload_attempts > 0)
	{
		if (((ent->client->latched_buttons | ent->client->buttons) & BUTTON_ATTACK)
		&& canFire(ent))
		{
			ent->client->reload_attempts = 0;
		}
		else
		{
			Cmd_Reload_f (ent);
		}
	}
	if (ent->client->weapon_attempts > 0)
		Cmd_Weapon_f (ent);

	// if the scoreboard is up, update it
	if (ent->client->showscores && !(level.framenum & 31))
	{
		//FIREBLADE
		if (ent->client->menu)
		{
			PMenu_Update (ent);
		}
		else
		//FIREBLADE
			DeathmatchScoreboardMessage (ent, ent->enemy);
		gi.unicast (ent, false);
	}

	//FIREBLADE
	if(!pause_time)
		RadioThink (ent);
	//FIREBLADE
}
Beispiel #9
0
/*
==============
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);
	}
}
Beispiel #10
0
/*
==============
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
}
Beispiel #11
0
/*
==============
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);
}
Beispiel #12
0
/*
=================
ClientEndServerFrame

Called for each player at the end of the server frame
and right after spawning
=================
*/
void ClientEndServerFrame (edict_t *ent)
{
	float	bobtime;
	int		i;

	current_player = ent;
	current_client = ent->client;

	if (ent->client->chase_target)
		UpdateChaseCam(ent);

	if (kpded2)
	{
		// if eyecam is enabled, set who's eyes we're looking through
		if (ent->client->chase_target && ent->client->chasemode == EYECAM_CHASE)
			ent->client->pov = ent->client->chase_target - g_edicts - 1;
		else
			ent->client->pov = -1;

		// set team info to be shown in server browsers
		ent->client->team = ent->client->pers.team;

		// don't send any entities/players to spectators when spectating is disabled
		if (level.modeset == MATCH && no_spec->value && ent->client->pers.spectator == SPECTATING && !ent->client->pers.admin && !ent->client->pers.rconx[0])
			ent->client->noents = true;
		else
			ent->client->noents = false;
	}

	//
	// If the origin or velocity have changed since ClientThink(),
	// update the pmove values.  This will happen when the client
	// is pushed by a bmodel or kicked by an explosion.
	// 
	// If it wasn't updated here, the view position would lag a frame
	// behind the body position when pushed -- "sinking into plats"
	//
	for (i=0 ; i<3 ; i++)
	{
		current_client->ps.pmove.origin[i] = ent->s.origin[i]*8.0;
		// make sure the velocity can overflow ("trigger_push" may exceed the limit) for back-compatibility (newer GCC may otherwise give 0x8000)
		current_client->ps.pmove.velocity[i] = (int)(ent->velocity[i]*8.0);
	}

	//
	// If the end of unit layout is displayed, don't give
	// the player any normal movement attributes
	//
	if (level.intermissiontime)
	{
		// darken the intermission background
		current_client->ps.blend[0] = 0;
		current_client->ps.blend[1] = 0;
		current_client->ps.blend[2] = 0;
		current_client->ps.blend[3] = 0.5;
		current_client->ps.fov = 90;
		if (level.framenum == level.startframe) return; // delay hud refresh to avoid overflow
		G_SetStats (ent);
		goto updatescore;
	}

	if (ent->client->chase_target && ent->client->chasemode == EYECAM_CHASE)
	{
		G_SetStats (ent);
		goto updatescore;
	}

	if (ent->client->chase_target)
		ent->client->ps.fov = 90;

	AngleVectors (ent->client->v_angle, forward, right, up);

	// burn from lava, etc
	P_WorldEffects ();

	//
	// set model angles from view angles so other things in
	// the world can tell which direction you are looking
	//

	// Ridah, Hovercars, handle angles differently
	if (ent->flags & (FL_HOVERCAR | FL_HOVERCAR_GROUND | FL_BIKE))
	{
		if (current_client->ps.fov < 105)
			current_client->ps.fov = 105;	// fix FOV while in Hovercar

		if (ent->client->v_angle[PITCH] > 180)
			ent->s.angles[PITCH] = (-360 + ent->client->v_angle[PITCH]);
		else
			ent->s.angles[PITCH] = ent->client->v_angle[PITCH];
	}
	else
	// done.
	{
		if (ent->client->v_angle[PITCH] > 180)
			ent->s.angles[PITCH] = (-360 + ent->client->v_angle[PITCH])/3;
		else
			ent->s.angles[PITCH] = ent->client->v_angle[PITCH]/3;

		// Ridah, snap the pitch so that it doesn't change as often (cut network bandwidth)
		ent->s.angles[PITCH] = (int)(((int)ent->s.angles[PITCH]) / 5) * 5;
	}
	ent->s.angles[YAW] = ent->client->v_angle[YAW];
	ent->s.angles[ROLL] = 0;
	ent->s.angles[ROLL] = SV_CalcRoll (ent->s.angles, ent->velocity)*4;
/*
	if (ent->client->anim_end == FRAME_lside_run_07)
		ent->s.angles[YAW] = anglemod(ent->s.angles[YAW] - 90);
	else if (ent->client->anim_end == FRAME_rside_run_07)
		ent->s.angles[YAW] = anglemod(ent->s.angles[YAW] + 90);
*/
	// Ridah, Hovercars
	if (ent->flags & (FL_HOVERCAR | FL_HOVERCAR_GROUND | FL_BIKE))
		ent->s.angles[ROLL] *= 0.5;
	// done.

	//
	// calculate speed and cycle to be used for
	// all cyclic walking effects
	//
	xyspeed = sqrt(ent->velocity[0]*ent->velocity[0] + ent->velocity[1]*ent->velocity[1]);

	if (xyspeed < 5)
	{
		bobmove = 0;
		current_client->bobtime = 0;	// start at beginning of cycle again
	}
	else if (ent->groundentity)
	{	// so bobbing only cycles when on ground
		if (xyspeed > 210)
			bobmove = 0.25;
		else if (xyspeed > 100)
			bobmove = 0.125;
		else
			bobmove = 0.0625;
	}
	else
		bobmove = 0; // stop bobbing when off ground

	bobtime = (current_client->bobtime += bobmove);

	if (current_client->ps.pmove.pm_flags & PMF_DUCKED)
		bobtime *= 4;

	bobcycle = (int)bobtime;
	bobfracsin = fabs(sin(bobtime*M_PI));

	// detect hitting the floor
// Ridah, Hovercars, no falling damage
if (!(ent->flags & (FL_HOVERCAR | FL_HOVERCAR_GROUND | FL_BIKE)))
// done.
	P_FallingDamage (ent);

	// apply all the damage taken this frame
// Ridah, doesn't work with new palette?
	P_DamageFeedback (ent);

	// determine the view offsets
// Ridah, Hovercars, no view offsets
if (ent->flags & (FL_HOVERCAR | FL_HOVERCAR_GROUND | FL_BIKE))
	ent->client->ps.viewoffset[2] = ent->viewheight;
else
// done.
	SV_CalcViewOffset (ent);


	// determine the gun offsets
// Ridah, Hovercars, no gun offsets
if (ent->flags & (FL_HOVERCAR | FL_HOVERCAR_GROUND | FL_BIKE))
// done.
	SV_CalcGunOffset (ent);

	// Ridah, fade out kicks, which are used for mono's
	if (ent->flags & (FL_BIKE))
	{
		if (ent->client->kick_angles[PITCH] > 0)
		{
			ent->client->kick_angles[PITCH] -= 5 * FRAMETIME;
			if (ent->client->kick_angles[PITCH] < 0)
				ent->client->kick_angles[PITCH] = 0;
		}
		else if (ent->client->kick_angles[PITCH] < 0)
		{
			ent->client->kick_angles[PITCH] += 5 * FRAMETIME;
			if (ent->client->kick_angles[PITCH] > 0)
				ent->client->kick_angles[PITCH] = 0;
		}

		VectorCopy( ent->client->kick_angles, ent->client->ps.kick_angles );
	}

	// determine the full screen color blend
	// must be after viewoffset, so eye contents can be
	// accurately determined
	// FIXME: with client prediction, the contents
	// should be determined by the client
	SV_CalcBlend (ent);

	G_SetStats (ent);

	G_SetClientEvent (ent);

	G_SetClientEffects (ent);

	G_SetClientSound (ent);

	G_SetClientFrame (ent);

	VectorCopy (ent->velocity, ent->client->oldvelocity);
	VectorCopy (ent->client->ps.viewangles, ent->client->oldviewangles);

	// clear weapon kicks
	VectorClear (ent->client->kick_origin);

	// Ridah, fade out kicks, which are used for mono's
	if (!(ent->flags & FL_BIKE))
	{
		VectorClear (ent->client->kick_angles);
	}

	// store the client's position for backward reconciliation later
	if (antilag->value && ent->solid != SOLID_NOT)
		G_StoreHistory(ent);

updatescore:
	if (ent->client->resp.enterframe == level.framenum) return;

	if (ent->client->showscores == SCORE_MOTD && (level.framenum == (ent->client->resp.enterframe + 150)
		|| (level.modeset == ENDGAMEVOTE && level.framenum == (ent->client->resp.enterframe + 100))))
	{
		if (level.modeset == ENDGAMEVOTE)
			ent->client->showscores = SCORE_MAP_VOTE;
		else
			ent->client->showscores = SCOREBOARD;
		ent->client->resp.scoreboard_frame = 0;
	}
	if (level.modeset == ENDGAMEVOTE && ent->client->showscores == SCOREBOARD && level.framenum == (level.startframe + 150) && !ent->client->resp.vote)
	{
		ent->client->showscores = SCORE_MAP_VOTE;
		ent->client->resp.scoreboard_frame = 0;
	}
	// if the scoreboard is due for an update, update it
	if ((!ent->client->resp.scoreboard_frame || (ent->client->showscores && !ent->client->resp.textbuf[0] && level.framenum >= (ent->client->resp.scoreboard_frame + 30)))
		&& level.framenum >= (ent->client->resp.enterframe + 5))
	{
		DeathmatchScoreboard(ent);
		return;
	}

	if (ent->client->resp.textbuf[0])
	{
		char *b = ent->client->resp.textbuf;
		int j = strlen(b);
		if (j > 300)
		{
			for (i = 300; i < j-20; i++)
				if (b[i] == '\n')
				{
					b[i] = 0;
					gi.cprintf(ent, PRINT_HIGH, "%s\n", b);
					memmove(b, b + i + 1, j - i);
					goto donetext;
				}
		}
		gi.cprintf(ent, PRINT_HIGH, "%s", b);
		b[0] = 0;
	}
donetext:
	if (level.intermissiontime) return;

	if (level.framenum > ent->client->resp.checkdelta)
	{
		ent->client->resp.checkdelta = level.framenum + 70 + (rand()&7);
		gi.WriteByte(svc_stufftext);
		gi.WriteString("cl_nodelta 0\n");
		gi.unicast(ent, false);
	}
	else if (level.framenum > ent->client->resp.checktex)
	{
		ent->client->resp.checktex = level.framenum + 80 + (rand()&7);
		gi.WriteByte(svc_stufftext);
		gi.WriteString(va("cmd %sA $gl_picmip $gl_maxtexsize $gl_polyblend\n", cmd_check));
		gi.unicast(ent, false);
	}
	else if (level.framenum > ent->client->resp.checkpvs)
	{
		ent->client->resp.checkpvs = level.framenum + 80 + (rand()&7);
		gi.WriteByte(svc_stufftext);
		gi.WriteString(va("cmd %sB $gl_clear $r_drawworld\n", cmd_check)); /* $gl_ztrick */
		gi.unicast(ent, false);
	}
	else if (ent->solid != SOLID_NOT && !ent->deadflag)
	{
		if (level.framenum > ent->client->resp.checkmouse)
		{
			ent->client->resp.checkmouse = level.framenum + 30 + (rand()&3);
			gi.WriteByte(svc_stufftext);
			if (antilag->value)
				gi.WriteString(va("cmd %sC $m_pitch $antilag\n", cmd_check)); // piggy-back the mouse check
			else
				gi.WriteString(va("cmd %sC $m_pitch\n", cmd_check));
			gi.unicast(ent, true);
		}
	}
}