Esempio n. 1
0
/*
=================
SV_UserinfoChanged

Pull specific info from a newly changed userinfo string
into a more C friendly form.
=================
*/
void SV_UserinfoChanged( client_t *cl ) {
	char	*val=NULL, *ip=NULL;
	int		i=0, len=0;

	// name for C code
	Q_strncpyz( cl->name, Info_ValueForKey (cl->userinfo, "name"), sizeof(cl->name) );

	// rate command

	// if the client is on the same subnet as the server and we aren't running an
	// internet public server, assume they don't need a rate choke
	if ( Sys_IsLANAddress( cl->netchan.remoteAddress ) && com_dedicated->integer != 2 && sv_lanForceRate->integer == 1 ) {
		cl->rate = 99999;	// lans should not rate limit
	} else {
		val = Info_ValueForKey (cl->userinfo, "rate");
		if (strlen(val)) {
			i = atoi(val);
			cl->rate = i;
			if (cl->rate < 1000) {
				cl->rate = 1000;
			} else if (cl->rate > 90000) {
				cl->rate = 90000;
			}
		} else {
			cl->rate = 3000;
		}
	}

	// snaps command
	//Note: cl->snapshotMsec is also validated in sv_main.cpp -> SV_CheckCvars if sv_fps, sv_snapsMin or sv_snapsMax is changed
	int minSnaps = Com_Clampi( 1, sv_snapsMax->integer, sv_snapsMin->integer ); // between 1 and sv_snapsMax ( 1 <-> 40 )
	int maxSnaps = min( sv_fps->integer, sv_snapsMax->integer ); // can't produce more than sv_fps snapshots/sec, but can send less than sv_fps snapshots/sec
	val = Info_ValueForKey( cl->userinfo, "snaps" );
	cl->wishSnaps = atoi( val );
	i = Com_Clampi( minSnaps, maxSnaps, cl->wishSnaps );
	cl->snapshotMsec = 1000/i;

	// TTimo
	// maintain the IP information
	// the banning code relies on this being consistently present
	if( NET_IsLocalAddress(cl->netchan.remoteAddress) )
		ip = "localhost";
	else
		ip = (char*)NET_AdrToString( cl->netchan.remoteAddress );

	val = Info_ValueForKey( cl->userinfo, "ip" );
	if( val[0] )
		len = strlen( ip ) - strlen( val ) + strlen( cl->userinfo );
	else
		len = strlen( ip ) + 4 + strlen( cl->userinfo );

	if( len >= MAX_INFO_STRING )
		SV_DropClient( cl, "userinfo string length exceeded" );
	else
		Info_SetValueForKey( cl->userinfo, "ip", ip );
}
Esempio n. 2
0
/*QUAKED target_location (0 0.5 0) (-8 -8 -8) (8 8 8)
Set "message" to the name of this location.
Set "count" to 0-7 for color.
0:white 1:red 2:green 3:yellow 4:blue 5:cyan 6:magenta 7:white

Closest target_location in sight used for the location, if none
in site, closest in distance
*/
void SP_target_location( gentity_t *self ) {
	if ( self->targetname && self->targetname[0] ) {
		SP_target_position( self );
		return;
	} else {
		static qboolean didwarn = qfalse;

		if ( !VALIDSTRING( self->message ) ) {
			G_Printf( "target_location with no message at %s\n", vtos( self->s.origin ) );
			G_FreeEntity( self );
			return;
		}

		if ( level.locations.legacy.num >= MAX_LOCATIONS ) {
			if ( !didwarn ) {
				G_Printf( "Maximum target_locations hit (%d)! Remaining locations will be removed.\n", MAX_LOCATIONS );
				didwarn = qtrue;
			}

			G_FreeEntity( self );
			return;
		}

		VectorCopy( self->s.origin, level.locations.legacy.data[level.locations.legacy.num].origin );
		Q_strncpyz( level.locations.legacy.data[level.locations.legacy.num].message, self->message, sizeof( level.locations.legacy.data[level.locations.legacy.num].message ) );
		level.locations.legacy.data[level.locations.legacy.num].count = Com_Clampi( 0, 9, self->count );

		level.locations.legacy.num++;

		G_FreeEntity( self );
	}
}
Esempio n. 3
0
void CG_Decrease(byte *work, float lerp, int *info)
{
	int		val;

	val = *work - origin_land->irand(2, 5);
	*work = (byte)Com_Clampi(1, 255, val);
}
Esempio n. 4
0
/*QUAKED target_location (0 0.5 0) (-8 -8 -8) (8 8 8)
Set "message" to the name of this location.
Set "count" to 0-7 for color.
0:white 1:red 2:green 3:yellow 4:blue 5:cyan 6:magenta 7:white

Closest target_location in sight used for the location, if none
in site, closest in distance
*/
void SP_target_location( gentity_t *self ) {
	if ( self->targetname && self->targetname[0] ) {
		SP_target_position( self );
		return;
	}
	else {
		static qboolean didwarn = qfalse;
		if ( !self->message ) {
			trap->Print( "target_location with no message at %s\n", vtos( self->s.origin ) );
			G_FreeEntity( self );
			return;
		}

		if ( level.locations.num >= MAX_LOCATIONS ) {
			if ( !didwarn ) {
				trap->Print( "Maximum target_locations hit (%d)\n", MAX_LOCATIONS );
				didwarn = qtrue;
			}
			G_FreeEntity( self );
			return;
		}

		VectorCopy( self->s.origin, level.locations.data[level.locations.num].origin );
		Q_strncpyz( level.locations.data[level.locations.num].message, self->message, sizeof( level.locations.data[level.locations.num].message ) );
		level.locations.data[level.locations.num].count = Com_Clampi( 0, 7, self->count );

		level.locations.num++;

		G_FreeEntity( self );
	}
}
Esempio n. 5
0
static void CG_ParseScores( void )
{
	int		i=0, scoreIndex=0, powerups=0, readScores=0;
	int		scoreOffset = GetScoreOffset();

	if ( Server_Supports( SSF_SCOREBOARD_LARGE ) )
		readScores = Com_Clampi( 0, MAX_CLIENTS, atoi( CG_Argv( 1 ) ) );
	else
		readScores = Com_Clampi( 0, MAX_CLIENT_SCORE_SEND, atoi( CG_Argv( 1 ) ) );
	cg.numScores = readScores;

	cg.teamScores[0] = atoi( CG_Argv( 2 ) );
	cg.teamScores[1] = atoi( CG_Argv( 3 ) );

	memset( cg.scores, 0, sizeof( cg.scores ) );
	for ( i=0, scoreIndex=0; i<readScores; i++ )
	{
		cg.scores[scoreIndex].client			= atoi( CG_Argv( i * scoreOffset +  4 ) );
		if ( cg.scores[scoreIndex].client < 0 || cg.scores[scoreIndex].client >= MAX_CLIENTS )
			continue;
		cg.scores[scoreIndex].score				= atoi( CG_Argv( i * scoreOffset +  5 ) );
		cg.scores[scoreIndex].ping				= atoi( CG_Argv( i * scoreOffset +  6 ) );
		cg.scores[scoreIndex].time				= atoi( CG_Argv( i * scoreOffset +  7 ) );
		cg.scores[scoreIndex].scoreFlags		= atoi( CG_Argv( i * scoreOffset +  8 ) );
		powerups								= atoi( CG_Argv( i * scoreOffset +  9 ) );
		cg.scores[scoreIndex].accuracy			= atoi( CG_Argv( i * scoreOffset + 10 ) );
		cg.scores[scoreIndex].impressiveCount	= atoi( CG_Argv( i * scoreOffset + 11 ) );
		cg.scores[scoreIndex].excellentCount	= atoi( CG_Argv( i * scoreOffset + 12 ) );
		cg.scores[scoreIndex].guantletCount		= atoi( CG_Argv( i * scoreOffset + 13 ) );
		cg.scores[scoreIndex].defendCount		= atoi( CG_Argv( i * scoreOffset + 14 ) );
		cg.scores[scoreIndex].assistCount		= atoi( CG_Argv( i * scoreOffset + 15 ) );
		cg.scores[scoreIndex].perfect			= atoi( CG_Argv( i * scoreOffset + 16 ) );
		cg.scores[scoreIndex].captures			= atoi( CG_Argv( i * scoreOffset + 17 ) );

		if ( Server_Supports( SSF_SCOREBOARD_KD ) )
			cg.scores[scoreIndex].deaths		= atoi( CG_Argv( i * scoreOffset + 18 ) );

		cgs.clientinfo[ cg.scores[scoreIndex].client ].score = cg.scores[scoreIndex].score;
		cgs.clientinfo[ cg.scores[scoreIndex].client ].powerups	= powerups;

		cg.scores[scoreIndex].team = cgs.clientinfo[ cg.scores[scoreIndex].client ].team;

		scoreIndex++;
	}

	CG_SetScoreSelection( NULL );
}
Esempio n. 6
0
/*
=================
CG_ParseTeamInfo

=================
*/
static void CG_ParseTeamInfo( void )
{
	int i=0, client=0;

	//Raz: avoid crash if server sends invalid range
	numSortedTeamPlayers = Com_Clampi( 0, TEAM_MAXOVERLAY, atoi( CG_Argv( 1 ) ) );

	for ( i=0; i<numSortedTeamPlayers; i++ )
	{
		client								= Com_Clampi( 0, MAX_CLIENTS, atoi( CG_Argv( i * 6 + 2 ) ) );
		sortedTeamPlayers[i]				= client;
		cgs.clientinfo[ client ].location	= atoi( CG_Argv( i * 6 + 3 ) );
		cgs.clientinfo[ client ].health		= atoi( CG_Argv( i * 6 + 4 ) );
		cgs.clientinfo[ client ].armor		= atoi( CG_Argv( i * 6 + 5 ) );
		cgs.clientinfo[ client ].curWeapon	= atoi( CG_Argv( i * 6 + 6 ) );
		cgs.clientinfo[ client ].powerups	= atoi( CG_Argv( i * 6 + 7 ) );
	}
}
Esempio n. 7
0
void R_RMGInit(void)
{
	char			newSky[MAX_QPATH];
	char			newFog[MAX_QPATH];
	shader_t		*fog;
	fog_t			*gfog;
	mgrid_t			*grid;
	char			temp[MAX_QPATH];
	int				i;
	unsigned short	*pos;

	ri.Cvar_VariableStringBuffer("RMG_sky", newSky, MAX_QPATH);
	// Get sunlight - this should set up all the sunlight data
	R_FindShader( newSky, lightmapsNone, stylesDefault, qfalse );

	// Remap sky
	R_RemapShader("textures/tools/_sky", newSky, NULL);

	// Fill in the lightgrid with sunlight
	if(tr.world->lightGridData)
	{
		grid = tr.world->lightGridData;
		grid->ambientLight[0][0] = (byte)Com_Clampi(0, 255, tr.sunAmbient[0] * 255.0f);
		grid->ambientLight[0][1] = (byte)Com_Clampi(0, 255, tr.sunAmbient[1] * 255.0f);
		grid->ambientLight[0][2] = (byte)Com_Clampi(0, 255, tr.sunAmbient[2] * 255.0f);
		R_ColorShiftLightingBytes(grid->ambientLight[0], grid->ambientLight[0]);

		grid->directLight[0][0] = (byte)Com_Clampi(0, 255, tr.sunLight[0]);
		grid->directLight[0][1] = (byte)Com_Clampi(0, 255, tr.sunLight[1]);
		grid->directLight[0][2] = (byte)Com_Clampi(0, 255, tr.sunLight[2]);
		R_ColorShiftLightingBytes(grid->directLight[0], grid->directLight[0]);

		NormalToLatLong(tr.sunDirection, grid->latLong);

		pos = tr.world->lightGridArray;
		for(i=0;i<tr.world->numGridArrayElements;i++)
		{
			*pos = 0;
			pos++;
		}
	}

	// Override the global fog with the defined one
	if(tr.world->globalFog != -1)
	{
		ri.Cvar_VariableStringBuffer("RMG_fog", newFog, MAX_QPATH);
		fog = R_FindShader( newFog, lightmapsNone, stylesDefault, qfalse);
		if (fog != tr.defaultShader)
		{
			gfog = tr.world->fogs + tr.world->globalFog;
			gfog->parms = *fog->fogParms;
			if (gfog->parms.depthForOpaque)
			{
				gfog->tcScale = 1.0f / ( gfog->parms.depthForOpaque * 8.0f );
				tr.distanceCull = gfog->parms.depthForOpaque;
				tr.distanceCullSquared = tr.distanceCull * tr.distanceCull;
				ri.Cvar_Set("RMG_distancecull", va("%f", tr.distanceCull));
			}
			else
			{
				gfog->tcScale = 1.0f;
			}
			gfog->colorInt = ColorBytes4 ( gfog->parms.color[0], 
										  gfog->parms.color[1], 
										  gfog->parms.color[2], 1.0f );
		}
	}

	ri.Cvar_VariableStringBuffer("RMG_weather", temp, MAX_QPATH);

	// Set up any weather effects
	switch(atol(temp))
	{
	case 0:
		break;
	case 1:
		RE_WorldEffectCommand("rain init 1000");
		RE_WorldEffectCommand("rain outside");
		break;
	case 2:
		RE_WorldEffectCommand("snow init 1000 outside");
		RE_WorldEffectCommand("snow outside");
		break;
	}
}
Esempio n. 8
0
/*
================
CG_ParseServerinfo

This is called explicitly when the gamestate is first received,
and whenever the server updates any serverinfo flagged cvars
================
*/
void CG_ParseServerinfo( void ) {
	const char *info = NULL, *tinfo = NULL;
	char *mapname;
	int i, value;

	info = CG_ConfigString( CS_SERVERINFO );

	cgs.debugMelee = atoi( Info_ValueForKey( info, "g_debugMelee" ) ); //trap->Cvar_GetHiddenVarValue("g_iknowkungfu");
	cgs.stepSlideFix = atoi( Info_ValueForKey( info, "g_stepSlideFix" ) );

	cgs.noSpecMove = atoi( Info_ValueForKey( info, "g_noSpecMove" ) );

	cgs.siegeTeamSwitch = atoi( Info_ValueForKey( info, "g_siegeTeamSwitch" ) );

	cgs.showDuelHealths = atoi( Info_ValueForKey( info, "g_showDuelHealths" ) );

	cgs.gametype = atoi( Info_ValueForKey( info, "g_gametype" ) );
	trap->Cvar_Set("g_gametype", va("%i", cgs.gametype));
	cgs.needpass = atoi( Info_ValueForKey( info, "g_needpass" ) );
	cgs.jediVmerc = atoi( Info_ValueForKey( info, "g_jediVmerc" ) );

	// this changes on map_restart, attempt to precache weapons
	value = atoi( Info_ValueForKey( info, "g_weaponDisable" ) );
	if ( cgs.wDisable != value ) {
		gitem_t *item = NULL;
		itemInfo_t *itemInfo = NULL;

		cgs.wDisable = value;

		for ( i=1, item=bg_itemlist, itemInfo = cg_items;
			i<bg_numItems;
			i++, item++, itemInfo++ )
		{// register all weapons that aren't disabled
			if ( item->giType == IT_WEAPON )
				CG_RegisterWeapon( item->giTag );
		}
	}

	cgs.fDisable = atoi( Info_ValueForKey( info, "g_forcePowerDisable" ) );
	cgs.dmflags = atoi( Info_ValueForKey( info, "dmflags" ) );
	cgs.duel_fraglimit = atoi( Info_ValueForKey( info, "duel_fraglimit" ) );
	cgs.capturelimit = atoi( Info_ValueForKey( info, "capturelimit" ) );

	// reset fraglimit warnings
	i = atoi( Info_ValueForKey( info, "fraglimit" ) );
	if ( cgs.fraglimit < i )
		cg.fraglimitWarnings &= ~(1|2|4);
	cgs.fraglimit = i;

	// reset timelimit warnings
	i = atoi( Info_ValueForKey( info, "timelimit" ) );
	if ( cgs.timelimit != i )
		cg.timelimitWarnings &= ~(1|2);
	cgs.timelimit = i;

	cgs.maxclients = Com_Clampi( 0, MAX_CLIENTS, atoi( Info_ValueForKey( info, "sv_maxclients" ) ) );
	mapname = Info_ValueForKey( info, "mapname" );

	//rww - You must do this one here, Info_ValueForKey always uses the same memory pointer.
	trap->Cvar_Set ( "ui_about_mapname", mapname );

	Com_sprintf( cgs.mapname, sizeof( cgs.mapname ), "maps/%s.bsp", mapname );
//	Q_strncpyz( cgs.redTeam, Info_ValueForKey( info, "g_redTeam" ), sizeof(cgs.redTeam) );
//	trap->Cvar_Set("g_redTeam", cgs.redTeam);
//	Q_strncpyz( cgs.blueTeam, Info_ValueForKey( info, "g_blueTeam" ), sizeof(cgs.blueTeam) );
//	trap->Cvar_Set("g_blueTeam", cgs.blueTeam);

	trap->Cvar_Set ( "ui_about_gametype", va("%i", cgs.gametype ) );
	trap->Cvar_Set ( "ui_about_fraglimit", va("%i", cgs.fraglimit ) );
	trap->Cvar_Set ( "ui_about_duellimit", va("%i", cgs.duel_fraglimit ) );
	trap->Cvar_Set ( "ui_about_capturelimit", va("%i", cgs.capturelimit ) );
	trap->Cvar_Set ( "ui_about_timelimit", va("%i", cgs.timelimit ) );
	trap->Cvar_Set ( "ui_about_maxclients", va("%i", cgs.maxclients ) );
	trap->Cvar_Set ( "ui_about_dmflags", va("%i", cgs.dmflags ) );
	trap->Cvar_Set ( "ui_about_hostname", Info_ValueForKey( info, "sv_hostname" ) );
	trap->Cvar_Set ( "ui_about_needpass", Info_ValueForKey( info, "g_needpass" ) );
	trap->Cvar_Set ( "ui_about_botminplayers", Info_ValueForKey ( info, "bot_minplayers" ) );

	//Set the siege teams based on what the server has for overrides.
	trap->Cvar_Set("cg_siegeTeam1", Info_ValueForKey(info, "g_siegeTeam1"));
	trap->Cvar_Set("cg_siegeTeam2", Info_ValueForKey(info, "g_siegeTeam2"));

	tinfo = CG_ConfigString( CS_TERRAINS + 1 );
	if ( !tinfo || !*tinfo )
	{
		cg.mInRMG = qfalse;
	}
	else
	{
		int weather = 0;

		cg.mInRMG = qtrue;
		trap->Cvar_Set("RMG", "1");

		weather = atoi( Info_ValueForKey( info, "RMG_weather" ) );

		trap->Cvar_Set("RMG_weather", va("%i", weather));

		if (weather == 1 || weather == 2)
		{
			cg.mRMGWeather = qtrue;
		}
		else
		{
			cg.mRMGWeather = qfalse;
		}
	}

	Q_strncpyz( cgs.voteString, CG_ConfigString( CS_VOTE_STRING ), sizeof( cgs.voteString ) );

	// synchronise our expected snaps/sec with the server's framerate
	i = atoi( Info_ValueForKey( info, "sv_fps" ) );
	if ( i )
		trap->Cvar_Set( "snaps", va( "%i", i ) );
}
Esempio n. 9
0
static QINLINE int JP_GetChatboxFont( void ) {
	return Com_Clampi( FONT_SMALL, FONT_NUM_FONTS, cg_chatboxFont.integer );
}
Esempio n. 10
0
void G_Give( gentity_t *ent, const char *name, const char *args, int argc )
{
	gitem_t		*it;
	int			i;
	qboolean	give_all = qfalse;

	if ( !Q_stricmp( name, "all" ) )
		give_all = qtrue;

	if ( give_all || !Q_stricmp( name, "health") )
	{
		if ( argc == 3 )
			ent->health = Com_Clampi( 1, ent->client->ps.stats[STAT_MAX_HEALTH], atoi( args ) );
		else
			ent->health = ent->client->ps.stats[STAT_MAX_HEALTH];
		if ( !give_all )
			return;
	}

	if ( give_all || !Q_stricmp( name, "armor" ) || !Q_stricmp( name, "shield" ) )
	{
		if ( argc == 3 )
			ent->client->ps.stats[STAT_ARMOR] = Com_Clampi( 0, ent->client->ps.stats[STAT_MAX_HEALTH], atoi( args ) );
		else
			ent->client->ps.stats[STAT_ARMOR] = ent->client->ps.stats[STAT_MAX_HEALTH];

		if ( !give_all )
			return;
	}

	if ( give_all || !Q_stricmp( name, "force" ) )
	{
		if ( argc == 3 )
			ent->client->ps.forcePower = Com_Clampi( 0, FORCE_POWER_MAX, atoi( args ) );
		else
			ent->client->ps.forcePower = FORCE_POWER_MAX;

		if ( !give_all )
			return;
	}

	if ( give_all || !Q_stricmp( name, "weapons" ) )
	{
		ent->client->ps.stats[STAT_WEAPONS] = (1 << (WP_MELEE)) - ( 1 << WP_NONE );
		if ( !give_all )
			return;
	}
	
	if ( !give_all && !Q_stricmp( name, "weaponnum" ) )
	{
		ent->client->ps.stats[STAT_WEAPONS] |= (1 << atoi( args ));
		return;
	}

	if ( !give_all && !Q_stricmp( name, "eweaps" ) )	//for developing, gives you all the weapons, including enemy
	{
		ent->client->ps.stats[STAT_WEAPONS] = (unsigned)(1 << WP_NUM_WEAPONS) - ( 1 << WP_NONE ); // NOTE: this wasn't giving the last weapon in the list
		return;
	}

	if ( give_all || !Q_stricmp( name, "ammo" ) )
	{
		int num = 999;
		if ( argc == 3 )
			num = Com_Clampi( 0, 999, atoi( args ) );
		for ( i=AMMO_FORCE; i<MAX_AMMO; i++ )
			ent->client->ps.ammo[i] = num != -1 ? num : ammoData[i].max;
		if ( !give_all )
			return;
	}

	if ( give_all || !Q_stricmp( name, "batteries" ) )
	{
		if ( argc == 3 )
			ent->client->ps.batteryCharge = Com_Clampi( 0, MAX_BATTERIES, atoi( args ) );
		else
			ent->client->ps.batteryCharge = MAX_BATTERIES;

		if (!give_all)
			return;
	}

	// spawn a specific item right on the player
	if ( !give_all ) {
		gentity_t	*it_ent;
		trace_t		trace;
		it = FindItem (args);
		if (!it) {
			it = FindItem (name);
			if (!it) {
				gi.SendServerCommand( ent-g_entities, "print \"unknown item\n\"");
				return;
			}
		}

		it_ent = G_Spawn();
		VectorCopy( ent->currentOrigin, it_ent->s.origin );
		it_ent->classname = G_NewString(it->classname);
		G_SpawnItem (it_ent, it);
		FinishSpawningItem(it_ent );
		memset( &trace, 0, sizeof( trace ) );
		Touch_Item (it_ent, ent, &trace);
		if (it_ent->inuse) {
			G_FreeEntity( it_ent );
		}
	}
}
Esempio n. 11
0
void CG_ParseServerinfo( void ) {
	const char *info = NULL, *tinfo = NULL;
	char *mapname;
	int i;

	info = CG_ConfigString( CS_SERVERINFO );

	cgs.debugMelee = atoi( Info_ValueForKey( info, "g_debugMelee" ) ); //trap->Cvar_GetHiddenVarValue("g_iknowkungfu");
	cgs.stepSlideFix = atoi( Info_ValueForKey( info, "g_stepSlideFix" ) );

	cgs.noSpecMove = atoi( Info_ValueForKey( info, "g_noSpecMove" ) );

	trap->Cvar_Set("bg_fighterAltControl", Info_ValueForKey( info, "bg_fighterAltControl" ));

	cgs.siegeTeamSwitch = atoi( Info_ValueForKey( info, "g_siegeTeamSwitch" ) );

	cgs.showDuelHealths = atoi( Info_ValueForKey( info, "g_showDuelHealths" ) );

	cgs.gametype = atoi( Info_ValueForKey( info, "g_gametype" ) );
	trap->Cvar_Set("g_gametype", va("%i", cgs.gametype));
	cgs.needpass = atoi( Info_ValueForKey( info, "needpass" ) );
	cgs.jediVmerc = atoi( Info_ValueForKey( info, "g_jediVmerc" ) );
	cgs.wDisable = atoi( Info_ValueForKey( info, "wdisable" ) );
	cgs.fDisable = atoi( Info_ValueForKey( info, "fdisable" ) );
	cgs.dmflags = atoi( Info_ValueForKey( info, "dmflags" ) );
	cgs.duel_fraglimit = atoi( Info_ValueForKey( info, "duel_fraglimit" ) );
	cgs.capturelimit = atoi( Info_ValueForKey( info, "capturelimit" ) );

	// reset fraglimit warnings
	i = atoi( Info_ValueForKey( info, "fraglimit" ) );
	if ( cgs.fraglimit < i )
		cg.fraglimitWarnings &= ~(1|2|4);
	cgs.fraglimit = i;

	// reset timelimit warnings
	i = atoi( Info_ValueForKey( info, "timelimit" ) );
	if ( cgs.timelimit != i )
		cg.timelimitWarnings &= ~(1|2);
	cgs.timelimit = i;

	cgs.maxclients = Com_Clampi( 0, MAX_CLIENTS, atoi( Info_ValueForKey( info, "sv_maxclients" ) ) );

	cgs.japp.jp_cinfo = atoi( Info_ValueForKey( info, "jp_cinfo" ) );
	cgs.japp.overbounce = atoi( Info_ValueForKey( info, "pmove_overbounce" ) );
	
	//Raz: Server support flags
	tinfo = Info_ValueForKey( info, "ssf" );
	if ( !Q_stricmpn( Info_ValueForKey( info, "gamename" ), "JA+ Mod", 7 ) )
		cg.japp.SSF = JAPLUS_SERVER_FLAGS;

#if MAC_PORT
	if ( tinfo[0] && sscanf( tinfo, "%X", &cg.japp.SSF ) != 1 )
#else
	if ( tinfo[0] && sscanf_s( tinfo, "%X", &cg.japp.SSF ) != 1 )
#endif
		CG_SecurityLogPrintf( "CG_ParseServerinfo: serverinfo 'ssf' was found, but invalid.\n"  );
	Com_Printf( "Server support hints: 0x%X\n", cg.japp.SSF );

	mapname = Info_ValueForKey( info, "mapname" );

	//rww - You must do this one here, Info_ValueForKey always uses the same memory pointer.
	trap->Cvar_Set ( "ui_about_mapname", mapname );

	Com_sprintf( cgs.mapname, sizeof( cgs.mapname ), "maps/%s.bsp", mapname );
//	Q_strncpyz( cgs.redTeam, Info_ValueForKey( info, "g_redTeam" ), sizeof(cgs.redTeam) );
//	trap->Cvar_Set("g_redTeam", cgs.redTeam);
//	Q_strncpyz( cgs.blueTeam, Info_ValueForKey( info, "g_blueTeam" ), sizeof(cgs.blueTeam) );
//	trap->Cvar_Set("g_blueTeam", cgs.blueTeam);

	trap->Cvar_Set ( "ui_about_gametype", va("%i", cgs.gametype ) );
	trap->Cvar_Set ( "ui_about_fraglimit", va("%i", cgs.fraglimit ) );
	trap->Cvar_Set ( "ui_about_duellimit", va("%i", cgs.duel_fraglimit ) );
	trap->Cvar_Set ( "ui_about_capturelimit", va("%i", cgs.capturelimit ) );
	trap->Cvar_Set ( "ui_about_timelimit", va("%i", cgs.timelimit ) );
	trap->Cvar_Set ( "ui_about_maxclients", va("%i", cgs.maxclients ) );
	trap->Cvar_Set ( "ui_about_dmflags", va("%i", cgs.dmflags ) );
	trap->Cvar_Set ( "ui_about_hostname", Info_ValueForKey( info, "sv_hostname" ) );
	trap->Cvar_Set ( "ui_about_needpass", Info_ValueForKey( info, "g_needpass" ) );
	trap->Cvar_Set ( "ui_about_botminplayers", Info_ValueForKey ( info, "bot_minplayers" ) );

	//Set the siege teams based on what the server has for overrides.
	trap->Cvar_Set("cg_siegeTeam1", Info_ValueForKey(info, "g_siegeTeam1"));
	trap->Cvar_Set("cg_siegeTeam2", Info_ValueForKey(info, "g_siegeTeam2"));

	tinfo = CG_ConfigString( CS_TERRAINS + 1 );
	if ( !tinfo || !*tinfo )
	{
		cg.mInRMG = qfalse;
	}
	else
	{
		int weather = 0;

		cg.mInRMG = qtrue;
		trap->Cvar_Set("RMG", "1");

		weather = atoi( Info_ValueForKey( info, "RMG_weather" ) );

		trap->Cvar_Set("RMG_weather", va("%i", weather));

		if (weather == 1 || weather == 2)
		{
			cg.mRMGWeather = qtrue;
		}
		else
		{
			cg.mRMGWeather = qfalse;
		}
	}

//	cg.japp.mod = GetMod( info );
	Q_strncpyz( cgs.japp.serverName, Info_ValueForKey( info, "sv_hostname" ), sizeof( cgs.japp.serverName ) );
	CPM_UpdateSettings( !!(cgs.japp.jp_cinfo & CINFO_CPMPHYSICS) );

	//Fix f****d up vote strings =o
	Q_strncpyz( cgs.voteString, CG_ConfigString( CS_VOTE_STRING ), sizeof( cgs.voteString ) );

	//Raz: Synchronise our expected snaps/sec with the server's framerate
	//		OpenJK servers will try to match us to the sv_fps too (sv_client.cpp -> SV_UserinfoChanged)
	i = atoi( Info_ValueForKey( info, "sv_fps" ) );
	if ( i )
		trap->Cvar_Set( "snaps", va( "%i", i ) );
}
Esempio n. 12
0
void G_ReflectMissile( gentity_t *ent, gentity_t *missile, vec3_t forward, qboolean coneBased ) {
	vec3_t		bounce_dir;
	int			i;
	float		speed;
	qboolean	isOwner, breakRng;

#if 0
	vec3_t eyePoint;
	vec3_t viewTestLine;
	VectorCopy( ent->client->ps.origin, eyePoint );
	eyePoint[2] += ent->client->ps.viewheight;
	VectorCopy( forward, viewTestLine );
	VectorNormalize( viewTestLine );
	VectorScale( viewTestLine, 500, viewTestLine );
	VectorAdd( viewTestLine, eyePoint, viewTestLine );
	G_TestLine( eyePoint, viewTestLine, 0x00ff00, 10000 );
#endif

	breakRng = g_breakRNG.integer & BROKEN_RNG_REFLECT;

	//save the original speed
	speed = VectorNormalize( missile->s.pos.trDelta );

	if ( missile->r.ownerNum == ent->s.number ) {
		// since we're giving boost to our own missile by pushing it, up the velocity
		speed *= 1.5;
		isOwner = qtrue;
	}

	if ( coneBased ) {
		// new behavior: the direction is randomized in a cone centered around the player view, so you can roughly aim
		const float coneAngle = DEG2RAD( Com_Clampi( 0, 360, g_coneReflectAngle.integer ) );
		vec3_t coneDir;
		VectorCopy( forward, coneDir );
		VectorNormalize( coneDir );

		// generate a point on the angled spherical cap centered on the Z axis
		const float phi = RandFloat( 0, 1, breakRng ) * 2 * M_PI;
		bounce_dir[2] = RandFloat( 0, 1, breakRng ) * ( 1 - cos( coneAngle ) ) + cos( coneAngle );
		bounce_dir[0] = sqrt( 1 - bounce_dir[2] * bounce_dir[2] ) * cos( phi );
		bounce_dir[1] = sqrt( 1 - bounce_dir[2] * bounce_dir[2] ) * sin( phi );

		// find the rotation axis and rotation angle for the cone direction
		const vec3_t zAxis = { 0.0f, 0.0f, 1.0f };
		vec3_t rotationAxis;
		CrossProduct( zAxis, coneDir, rotationAxis );
		const float rotationAngle = acos( DotProduct( coneDir, zAxis ) );

		if ( rotationAngle ) {
			// rotate that shit
			const float cr = cos( rotationAngle );
			const float sr = sin( rotationAngle );
			vec3_t zCenteredDirection;
			VectorCopy( bounce_dir, zCenteredDirection );

			// my head
			bounce_dir[0] =
				( ( cr + ( rotationAxis[0] * rotationAxis[0] * ( 1 - cr ) ) ) * zCenteredDirection[0] ) +
				( ( ( rotationAxis[0] * rotationAxis[1] * ( 1 - cr ) ) - ( rotationAxis[2] * sr ) ) * zCenteredDirection[1] ) +
				( ( ( rotationAxis[0] * rotationAxis[2] * ( 1 - cr ) ) + ( rotationAxis[1] * sr ) ) * zCenteredDirection[2] );
			bounce_dir[1] =
				( ( ( rotationAxis[1] * rotationAxis[0] * ( 1 - cr ) ) + ( rotationAxis[2] * sr ) ) * zCenteredDirection[0] ) +
				( ( cr + ( rotationAxis[1] * rotationAxis[1] * ( 1 - cr ) ) ) * zCenteredDirection[1] ) +
				( ( ( rotationAxis[1] * rotationAxis[2] * ( 1 - cr ) ) - ( rotationAxis[0] * sr ) ) * zCenteredDirection[2] );
			bounce_dir[2] =
				( ( ( rotationAxis[2] * rotationAxis[0] * ( 1 - cr ) ) - ( rotationAxis[1] * sr ) ) * zCenteredDirection[0] ) +
				( ( ( rotationAxis[2] * rotationAxis[1] * ( 1 - cr ) ) + ( rotationAxis[0] * sr ) ) * zCenteredDirection[1] ) +
				( ( cr + ( rotationAxis[2] * rotationAxis[2] * ( 1 - cr ) ) ) * zCenteredDirection[2] );
		}
	} else {
		// basejka behavior: if owner is present, it's roughly sent back at him
		if ( &g_entities[missile->r.ownerNum] && missile->s.weapon != WP_SABER && missile->s.weapon != G2_MODEL_PART && !isOwner ) {
			// bounce back at them if you can
			VectorSubtract( g_entities[missile->r.ownerNum].r.currentOrigin, missile->r.currentOrigin, bounce_dir );
			VectorNormalize( bounce_dir );
		} else {
			vec3_t missile_dir;

			VectorSubtract( ent->r.currentOrigin, missile->r.currentOrigin, missile_dir );
			VectorCopy( missile->s.pos.trDelta, bounce_dir );
			VectorScale( bounce_dir, DotProduct( forward, missile_dir ), bounce_dir );
			VectorNormalize( bounce_dir );
		}

		for ( i = 0; i < 3; i++ ) {
			bounce_dir[i] += RandFloat( -0.2f, 0.2f, breakRng ); // *CHANGE 10a* bigger deflect angles
		}
	}

	VectorNormalize( bounce_dir );
	VectorScale( bounce_dir, speed, missile->s.pos.trDelta );
	missile->s.pos.trTime = level.time; // move a bit on the very first frame
	VectorCopy( missile->r.currentOrigin, missile->s.pos.trBase );

#if 0
	vec3_t reflectionTestLine;
	VectorCopy( missile->s.pos.trDelta, reflectionTestLine );
	VectorNormalize( reflectionTestLine );
	VectorScale( reflectionTestLine, 500, reflectionTestLine );
	VectorAdd( reflectionTestLine, missile->s.pos.trBase, reflectionTestLine );
	G_TestLine( missile->s.pos.trBase, reflectionTestLine, 0x0000ff, 10000 );
#endif

	if ( missile->s.weapon != WP_SABER && missile->s.weapon != G2_MODEL_PART ) {
		// you are mine, now!
		missile->r.ownerNum = ent->s.number;
		missile->isReflected = qtrue;
	}

	if ( missile->s.weapon == WP_ROCKET_LAUNCHER ) {
		// stop homing
		missile->think = 0;
		missile->nextthink = 0;
	}
}