示例#1
0
/*
=============
CG_AddPlayerWeapon

Used for both the view weapon (ps is valid) and the world modelother character models (ps is NULL)
The main player will have this called for BOTH cases, so effects like light and
sound should only be done on the world model case.
=============
*/
void CG_AddPlayerWeapon( refEntity_t *parent, qboolean firstPerson, centity_t *cent, int team ) {
	refEntity_t	gun;
	refEntity_t	barrel;
	refEntity_t	flash;
	vec3_t		angles;
	weapon_t	weaponNum;
	weaponInfo_t	*weapon;
	centity_t	*nonPredictedCent;
	const cgWeaponFX_t *weaponFX;

	weaponNum = cent->currentState.weapon;

	CG_RegisterWeapon( weaponNum );
	weapon = &cg_weapons[weaponNum];
	weaponFX = CG_FindWeaponFX( weaponNum );

	// add the weapon
	memset( &gun, 0, sizeof( gun ) );
	VectorCopy( parent->lightingOrigin, gun.lightingOrigin );
	gun.shadowPlane = parent->shadowPlane;
	gun.renderfx = parent->renderfx;

	// set custom shading for railgun refire rate
	if ( cent->currentState.weapon == WP_RAILGUN ) {
		clientInfo_t *ci = &cgs.clientinfo[ cent->currentState.clientNum ];
		if ( cent->pe.railFireTime + 1500 > cg.time ) {
			int scale = 255 * ((cg.time - cent->pe.railFireTime) + cg.timeFraction) / 1500;
			gun.shaderRGBA[0] = (ci->c1RGBA[0] * scale) >> 8;
			gun.shaderRGBA[1] = (ci->c1RGBA[1] * scale) >> 8;
			gun.shaderRGBA[2] = (ci->c1RGBA[2] * scale) >> 8;
			gun.shaderRGBA[3] = 255;
		} else {
static void CG_LoadWeapons_f( void ) {
	int i;

	for( i = WP_KNIFE; i < WP_NUM_WEAPONS; i++ ) {
		// DHM - Nerve :: Only register weapons we use in WolfMP
		if( BG_WeaponInWolfMP( i ) )
			CG_RegisterWeapon( i, qtrue );
	}	
}
示例#3
0
/*
===============
CG_InitWeapons

Precaches weapons
===============
*/
void CG_InitWeapons( void )
{
  int   i;

  memset( cg_weapons, 0, sizeof( cg_weapons ) );

  for( i = WP_NONE + 1; i < WP_NUM_WEAPONS; i++ )
    CG_RegisterWeapon( i );

  cgs.media.level2ZapTS = CG_RegisterTrailSystem( "models/weapons/lev2zap/lightning" );
}
示例#4
0
// The server says this item is used on this level
void CG_RegisterItemVisuals( int itemNum ) {
	int				handle;

	if ( itemNum < 0 || itemNum >= (int)bg_numItems ) {
		trap->Error( ERR_DROP, "CG_RegisterItemVisuals: itemNum %d out of range [0-%d]", itemNum, bg_numItems - 1 );
		return;
	}

	itemInfo_t *itemInfo = &cg_items[itemNum];
	if ( itemInfo->registered ) {
		return;
	}
	memset( itemInfo, 0, sizeof(*itemInfo) );
	itemInfo->registered = qtrue;

	const gitem_t *item = &bg_itemlist[itemNum];
	if ( item->giType == IT_TEAM && cgs.gametype == GT_CTY
		&& (item->giTag == PW_REDFLAG || item->giTag == PW_BLUEFLAG) )
	{
		itemInfo->models[0] = trap->R_RegisterModel( item->world_model[1] );
	}
	else if ( item->giType == IT_WEAPON
		&& (item->giTag == WP_THERMAL || item->giTag == WP_TRIP_MINE || item->giTag == WP_DET_PACK) )
	{
		itemInfo->models[0] = trap->R_RegisterModel( item->world_model[1] );
	}
	else {
		itemInfo->models[0] = trap->R_RegisterModel( item->world_model[0] );
	}

	if ( !Q_stricmp( &item->world_model[0][strlen( item->world_model[0] ) - 4], ".glm" ) ) {
		handle = trap->G2API_InitGhoul2Model( &itemInfo->g2Models[0], item->world_model[0], 0, 0, 0, 0, 0 );
		if ( handle < 0 ) {
			itemInfo->g2Models[0] = NULL;
		}
		else {
			itemInfo->radius[0] = 60;
		}
	}
	if ( item->icon )
		itemInfo->icon = trap->R_RegisterShaderNoMip( item->icon );
	else
		itemInfo->icon = 0;

	if ( item->giType == IT_WEAPON )
		CG_RegisterWeapon( item->giTag );

	// powerups have an accompanying ring or sphere
	if ( item->giType == IT_POWERUP || item->giType == IT_HEALTH || item->giType == IT_ARMOR || item->giType == IT_HOLDABLE ) {
		if ( item->world_model[1] )
			itemInfo->models[1] = trap->R_RegisterModel( item->world_model[1] );
	}
}
示例#5
0
/*
=================
CG_RegisterItemVisuals

The server says this item is used on this level
=================
*/
void CG_RegisterItemVisuals( int itemNum ) {
	itemInfo_t		*itemInfo;
	gitem_t			*item;

	if ( itemNum < 0 || itemNum >= bg_numItems ) {
		CG_Error( "CG_RegisterItemVisuals: itemNum %d out of range [0-%d]", itemNum, bg_numItems-1 );
	}

	itemInfo = &cg_items[ itemNum ];
	if ( itemInfo->registered ) {
		return;
	}

	item = &bg_itemlist[ itemNum ];

	memset( itemInfo, 0, sizeof( &itemInfo ) );
	itemInfo->registered = qtrue;

	itemInfo->models[0] = trap_R_RegisterModel( item->world_model[0] );

	itemInfo->icon = trap_R_RegisterShader( item->icon );

	if ( item->giType == IT_WEAPON ) {
		CG_RegisterWeapon( item->giTag );
	}

	//
	// powerups have an accompanying ring or sphere
	//
	if ( item->giType == IT_POWERUP || item->giType == IT_HEALTH || 
		item->giType == IT_ARMOR || item->giType == IT_HOLDABLE ) {
		if ( item->world_model[1] ) {
			itemInfo->models[1] = trap_R_RegisterModel( item->world_model[1] );
		}
	}
}
示例#6
0
void TurretClientRun(centity_t *ent)
{
	if (!ent->ghoul2)
	{
		weaponInfo_t	*weaponInfo;

		trap_G2API_InitGhoul2Model(&ent->ghoul2, CG_ConfigString( CS_MODELS+ent->currentState.modelindex ), 0, 0, 0, 0, 0);

		if (!ent->ghoul2)
		{ //bad
			return;
		}

		ent->torsoBolt = trap_G2API_AddBolt( ent->ghoul2, 0, "*flash02" );

		trap_G2API_SetBoneAngles( ent->ghoul2, 0, "bone_hinge", vec3_origin, BONE_ANGLES_POSTMULT, POSITIVE_Y, POSITIVE_Z, POSITIVE_X, NULL, 100, cg.time ); 
		trap_G2API_SetBoneAngles( ent->ghoul2, 0, "bone_gback", vec3_origin, BONE_ANGLES_POSTMULT, POSITIVE_Y, POSITIVE_Z, POSITIVE_X, NULL, 100, cg.time ); 
		trap_G2API_SetBoneAngles( ent->ghoul2, 0, "bone_barrel", vec3_origin, BONE_ANGLES_POSTMULT, POSITIVE_Y, POSITIVE_Z, POSITIVE_X, NULL, 100, cg.time ); 

		trap_G2API_SetBoneAnim( ent->ghoul2, 0, "model_root", 0, 11, BONE_ANIM_OVERRIDE_FREEZE, 0.8f, cg.time, 0, 0 );

		ent->turAngles[ROLL] = 0;
		ent->turAngles[PITCH] = 90;
		ent->turAngles[YAW] = 0;

		weaponInfo = &cg_weapons[WP_TURRET];

		if ( !weaponInfo->registered )
		{
			CG_RegisterWeapon(WP_TURRET);
		}
	}

	if (ent->currentState.fireflag == 2)
	{ //I'm about to blow
		if (ent->turAngles)
		{
			trap_G2API_SetBoneAngles( ent->ghoul2, 0, "bone_hinge", ent->turAngles, BONE_ANGLES_REPLACE, NEGATIVE_Y, NEGATIVE_Z, NEGATIVE_X, NULL, 100, cg.time ); 
		}
		return;
	}
	else if (ent->currentState.fireflag && ent->bolt4 != ent->currentState.fireflag)
	{
		vec3_t muzzleOrg, muzzleDir;
		mdxaBone_t boltMatrix;

		trap_G2API_GetBoltMatrix(ent->ghoul2, 0, ent->torsoBolt, &boltMatrix, /*ent->lerpAngles*/vec3_origin, ent->lerpOrigin, cg.time, cgs.gameModels, ent->modelScale);
		BG_GiveMeVectorFromMatrix(&boltMatrix, ORIGIN, muzzleOrg);
		BG_GiveMeVectorFromMatrix(&boltMatrix, NEGATIVE_X, muzzleDir);

		trap_FX_PlayEffectID(cgs.effects.mTurretMuzzleFlash, muzzleOrg, muzzleDir, -1, -1);

		ent->bolt4 = ent->currentState.fireflag;
	}
	else if (!ent->currentState.fireflag)
	{
		ent->bolt4 = 0;
	}

	if (ent->currentState.bolt2 != ENTITYNUM_NONE)
	{ //turn toward the enemy
		centity_t *enemy = &cg_entities[ent->currentState.bolt2];

		if (enemy)
		{
			vec3_t enAng;
			vec3_t enPos;

			VectorCopy(enemy->currentState.pos.trBase, enPos);

			VectorSubtract(enPos, ent->lerpOrigin, enAng);
			VectorNormalize(enAng);
			vectoangles(enAng, enAng);
			enAng[ROLL] = 0;
			enAng[PITCH] += 90;

			CreepToPosition(enAng, ent->turAngles);
		}
	}
	else
	{
		vec3_t idleAng;
		float turnAmount;

		if (ent->turAngles[YAW] > 360)
		{
			ent->turAngles[YAW] -= 361;
		}

		if (!ent->dustTrailTime)
		{
			ent->dustTrailTime = cg.time;
		}

		turnAmount = (cg.time-ent->dustTrailTime)*0.03;

		if (turnAmount > 360)
		{
			turnAmount = 360;
		}

		idleAng[PITCH] = 90;
		idleAng[ROLL] = 0;
		idleAng[YAW] = ent->turAngles[YAW] + turnAmount;
		ent->dustTrailTime = cg.time;

		CreepToPosition(idleAng, ent->turAngles);
	}

	if (cg.time < ent->frame_minus1_refreshed)
	{
		ent->frame_minus1_refreshed = cg.time;
		return;
	}

	ent->frame_minus1_refreshed = cg.time;
	trap_G2API_SetBoneAngles( ent->ghoul2, 0, "bone_hinge", ent->turAngles, BONE_ANGLES_REPLACE, NEGATIVE_Y, NEGATIVE_Z, NEGATIVE_X, NULL, 100, cg.time ); 
}
示例#7
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 ) );
}
示例#8
0
void CG_DrawWeaponSelect( void ) {
	int i, bits, count, smallIconSize, bigIconSize, holdX, x, y, pad, sideLeftIconCnt, sideRightIconCnt, sideMax,
		holdCount, iconCnt, yOffset = 0;
	qboolean drewConc = qfalse;

	// can't cycle when on a weapon
	if ( cg.predictedPlayerState.emplacedIndex )
		cg.weaponSelectTime = 0;

	// Time is up for the HUD to display
	if ( (cg.weaponSelectTime + WEAPON_SELECT_TIME) < cg.time )
		return;

	// don't display if dead
	if ( cg.predictedPlayerState.stats[STAT_HEALTH] <= 0 )
		return;

	// showing weapon select clears pickup item display, but not the blend blob
	cg.itemPickupTime = 0;

	bits = cg.predictedPlayerState.stats[STAT_WEAPONS];

	// count the number of weapons owned
	count = 0;

	// display this weapon that we don't actually "have" as unhighlighted until it's deselected
	// since it's selected we must increase the count to display the proper number of valid selectable weapons
	if ( !CG_WeaponSelectable( cg.weaponSelect ) && (cg.weaponSelect == WP_THERMAL || cg.weaponSelect == WP_TRIP_MINE) )
		count++;

	for ( i = 1; i < WP_NUM_WEAPONS; i++ ) {
		if ( bits & (1 << i) ) {
			if ( CG_WeaponSelectable( i ) || (i != WP_THERMAL && i != WP_TRIP_MINE) )
				count++;
		}
	}

	if ( !count ) // If no weapons, don't display
		return;

	sideMax = 3; // Max number of icons on the side

	// Calculate how many icons will appear to either side of the center one
	holdCount = count - 1;	// -1 for the center icon
	if ( holdCount == 0 ) {
		// No icons to either side
		sideLeftIconCnt = 0;
		sideRightIconCnt = 0;
	}
	else if ( count > (2 * sideMax) ) {
		// Go to the max on each side
		sideLeftIconCnt = sideMax;
		sideRightIconCnt = sideMax;
	}
	else {
		// Less than max, so do the calc
		sideLeftIconCnt = holdCount / 2;
		sideRightIconCnt = holdCount - sideLeftIconCnt;
	}

	if ( cg.weaponSelect == WP_CONCUSSION )
		i = WP_FLECHETTE;
	else
		i = cg.weaponSelect - 1;
	if ( i < 1 )
		i = LAST_USEABLE_WEAPON;

	smallIconSize = 40;
	bigIconSize = 80;
	pad = 12;

	x = (SCREEN_WIDTH / 2);
	y = 410;

	// Left side ICONS
	trap->R_SetColor( &colorTable[CT_WHITE] );
	// Work backwards from current icon
	holdX = x - ((bigIconSize / 2) + pad + smallIconSize) * cgs.widthRatioCoef;
	drewConc = qfalse;

	for ( iconCnt = 1; iconCnt < (sideLeftIconCnt + 1); i-- ) {
		if ( i == WP_CONCUSSION )
			i--;
		else if ( i == WP_FLECHETTE && !drewConc && cg.weaponSelect != WP_CONCUSSION )
			i = WP_CONCUSSION;
		if ( i < 1 )
			i = LAST_USEABLE_WEAPON;

		// Does he have this weapon?
		if ( !(bits & (1 << i)) ) {
			if ( i == WP_CONCUSSION ) {
				drewConc = qtrue;
				i = WP_ROCKET_LAUNCHER;
			}
			continue;
		}

		// Don't show thermal and tripmine when out of them
		if ( !CG_WeaponSelectable( i ) && (i == WP_THERMAL || i == WP_TRIP_MINE) )
			continue;

		++iconCnt;					// Good icon

		if ( media.gfx.interface.weaponIcons[i] ) {
			CG_RegisterWeapon( i );

			trap->R_SetColor( &colorTable[CT_WHITE] );
			if ( !CG_WeaponCheck( i ) )
				CG_DrawPic(holdX, y + 10 + yOffset, smallIconSize * cgs.widthRatioCoef, smallIconSize, media.gfx.interface.weaponIconsInactive[i]);
			else
				CG_DrawPic(holdX, y + 10 + yOffset, smallIconSize * cgs.widthRatioCoef, smallIconSize, media.gfx.interface.weaponIcons[i]);

			holdX -= (smallIconSize + pad) * cgs.widthRatioCoef;
		}
		if ( i == WP_CONCUSSION ) {
			drewConc = qtrue;
			i = WP_ROCKET_LAUNCHER;
		}
	}

	// Current Center Icon
	if ( media.gfx.interface.weaponIcons[cg.weaponSelect] ) {
		CG_RegisterWeapon( cg.weaponSelect );

		trap->R_SetColor( &colorTable[CT_WHITE] );
		if ( !CG_WeaponCheck( cg.weaponSelect ) )
			CG_DrawPic(x - (bigIconSize / 2 * cgs.widthRatioCoef), (y - ((bigIconSize - smallIconSize) / 2)) + 10 + yOffset, bigIconSize * cgs.widthRatioCoef, bigIconSize, media.gfx.interface.weaponIconsInactive[cg.weaponSelect]);
		else
			CG_DrawPic(x - (bigIconSize / 2 * cgs.widthRatioCoef), (y - ((bigIconSize - smallIconSize) / 2)) + 10 + yOffset, bigIconSize * cgs.widthRatioCoef, bigIconSize, media.gfx.interface.weaponIcons[cg.weaponSelect]);
	}

	if ( cg.weaponSelect == WP_CONCUSSION )
		i = WP_ROCKET_LAUNCHER;
	else
		i = cg.weaponSelect + 1;

	if ( i > LAST_USEABLE_WEAPON )
		i = 1;

	// Right side ICONS
	// Work forwards from current icon
	holdX = x + ((bigIconSize / 2) + pad) * cgs.widthRatioCoef;
	for ( iconCnt = 1; iconCnt<(sideRightIconCnt + 1); i++ ) {
		if ( i == WP_CONCUSSION )
			i++;
		else if ( i == WP_ROCKET_LAUNCHER && !drewConc && cg.weaponSelect != WP_CONCUSSION )
			i = WP_CONCUSSION;
		if ( i > LAST_USEABLE_WEAPON )
			i = 1;

		if ( !(bits & (1 << i)) ) {
			if ( i == WP_CONCUSSION ) {
				drewConc = qtrue;
				i = WP_FLECHETTE;
			}
			continue;
		}

		// Don't show thermal and tripmine when out of them
		if ( !CG_WeaponSelectable( i ) && (i == WP_THERMAL || i == WP_TRIP_MINE) )
			continue;

		++iconCnt; // Good icon

		if ( media.gfx.interface.weaponIcons[i] ) {
			CG_RegisterWeapon( i );
			// No ammo for this weapon?
			trap->R_SetColor( &colorTable[CT_WHITE] );
			if ( !CG_WeaponCheck( i ) )
				CG_DrawPic(holdX, y + 10 + yOffset, smallIconSize * cgs.widthRatioCoef, smallIconSize, media.gfx.interface.weaponIconsInactive[i]);
			else
				CG_DrawPic(holdX, y + 10 + yOffset, smallIconSize * cgs.widthRatioCoef, smallIconSize, media.gfx.interface.weaponIcons[i]);


			holdX += (smallIconSize + pad);
		}
		if ( i == WP_CONCUSSION ) {
			drewConc = qtrue;
			i = WP_FLECHETTE;
		}
	}

	// draw the selected name
	if ( cg_weapons[cg.weaponSelect].item ) {
		vector4 textColor = { .875f, .718f, .121f, 1.0f };

		char upperKey[1024];
		Com_sprintf( upperKey, sizeof(upperKey), "SP_INGAME_%s", cg_weapons[cg.weaponSelect].item->classname );
		Q_strupr( upperKey );

		const char *s = nullptr;
		char text[1024];
		if ( trap->SE_GetStringTextString( upperKey, text, sizeof(text) ) ) {
			s = text;
		}
		else {
			s = cg_weapons[cg.weaponSelect].item->classname;
		}
		const Font font( FONT_SMALL, 1.0f, false );
		const float width = font.Width( s );
		font.Paint( (SCREEN_WIDTH / 2) - (width / 2.0f), y + 45 + yOffset, s, &textColor, ITEM_TEXTSTYLE_SHADOWED );
	}

	trap->R_SetColor( NULL );
}
示例#9
0
// Add the weapon, and flash for the player's view
void CG_AddViewWeapon( playerState_t *ps ) {
	// no gun if in third person view or a camera is active
	if ( ps->persistant[PERS_TEAM] == TEAM_SPECTATOR || ps->pm_type == PM_INTERMISSION || cg.renderingThirdPerson ) {
		return;
	}

	const int weap = cg_fakeGun.integer ? cg_fakeGun.integer : ps->weapon;
	float desiredFov = 0.0f;
	if ( !cg.renderingThirdPerson
		&& (cg_trueGuns.integer || weap == WP_SABER || weap == WP_MELEE)
		&& cg_trueFOV.value
		&& cg.predictedPlayerState.pm_type != PM_SPECTATOR
		&& cg.predictedPlayerState.pm_type != PM_INTERMISSION )
	{
		desiredFov = cg_fovViewmodel.integer ? cg_fovViewmodel.value : cg_trueFOV.value;
	}
	else {
		desiredFov = cg_fovViewmodel.integer ? cg_fovViewmodel.value : cg_fov.value;
	}

	desiredFov = Q_clampi( 1, desiredFov, 180 );

	// allow the gun to be completely removed
	if ( !cg_fakeGun.integer && (!cg_drawGun.integer || cg.predictedPlayerState.zoomMode || cg_trueGuns.integer
		|| weap == WP_SABER || weap == WP_MELEE) ) {
		return;
	}

	// don't draw if testing a gun model
	if ( cg.testGun ) {
		return;
	}

	centity_t *cent = &cg_entities[cg.predictedPlayerState.clientNum];
	CG_RegisterWeapon( weap );

	refEntity_t hand;
	memset( &hand, 0, sizeof(hand) );

	// set up gun position
	vector3 angles;
	CG_CalculateWeaponPosition( &hand.origin, &angles );

	refdef_t *refdef = CG_GetRefdef();
	VectorMA( &hand.origin, cg.gunAlign.x, &refdef->viewaxis[0], &hand.origin );
	VectorMA( &hand.origin, cg.gunAlign.y, &refdef->viewaxis[1], &hand.origin );
	VectorMA( &hand.origin, cg.gunAlign.z, &refdef->viewaxis[2], &hand.origin );

	AnglesToAxis( &angles, hand.axis );

	if ( cg_fovViewmodel.integer ) {
		float fracDistFOV, fracWeapFOV;
		float fov = desiredFov;
		if ( cg_fovAspectAdjust.integer ) {
			// Based on LordHavoc's code for Darkplaces
			// http://www.quakeworld.nu/forum/topic/53/what-does-your-qw-look-like/page/30
			const float baseAspect = 0.75f; // 3/4
			const float aspect = (float)cgs.glconfig.vidWidth / (float)cgs.glconfig.vidHeight;

			fov = atanf( tanf( desiredFov*M_PI / 360.0f ) * baseAspect*aspect )*360.0f / M_PI;
		}
		fracDistFOV = tanf( refdef->fov_x * M_PI / 360.0f );
		fracWeapFOV = (1.0f / fracDistFOV) * tanf( fov * M_PI / 360.0f );
		VectorScale( &hand.axis[0], fracWeapFOV, &hand.axis[0] );
	}

	// map torso animations to weapon animations
	if ( cg_debugGunFrame.integer ) {
		// development tool
		hand.frame = hand.oldframe = cg_debugGunFrame.integer;
		hand.backlerp = 0;
	}
	else {
		float currentFrame;

		// get clientinfo for animation map
		clientInfo_t *ci = nullptr;
		if ( cent->currentState.eType == ET_NPC ) {
			if ( !cent->npcClient ) {
				return;
			}
			ci = cent->npcClient;
		}
		else {
			ci = &cgs.clientinfo[cent->currentState.clientNum];
		}

		// smoother first-person anims by eezstreet http://jkhub.org/topic/1499-/
		//		actually ported from SP
#if 1
		// Sil's fix
		trap->G2API_GetBoneFrame( cent->ghoul2, "lower_lumbar", cg.time, &currentFrame, cgs.gameModels, 0 );
		hand.frame = CG_MapTorsoToWeaponFrame( ci, ceilf( currentFrame ), cent->currentState.torsoAnim );
		hand.oldframe = CG_MapTorsoToWeaponFrame( ci, floorf( currentFrame ), cent->currentState.torsoAnim );
		hand.backlerp = 1.0f - (currentFrame - floorf( currentFrame ));
#else
		// basejka style
		hand.frame = CG_MapTorsoToWeaponFrame( ci, cent->pe.torso.frame, cent->currentState.torsoAnim );
		hand.oldframe = CG_MapTorsoToWeaponFrame( ci, cent->pe.torso.oldFrame, cent->currentState.torsoAnim );
		hand.backlerp = cent->pe.torso.backlerp;
#endif

		// Handle the fringe situation where oldframe is invalid
		if ( hand.frame == -1 ) {
			hand.frame = 0;
			hand.oldframe = 0;
			hand.backlerp = 0;
		}
		else if ( hand.oldframe == -1 ) {
			hand.oldframe = hand.frame;
			hand.backlerp = 0;
		}
	}

	weaponInfo_t *wi = &cg_weapons[weap];
	hand.hModel = wi->handsModel;
	hand.renderfx = RF_DEPTHHACK | RF_FIRST_PERSON;

	// add everything onto the hand
	CG_AddPlayerWeapon( &hand, ps, &cg_entities[cg.predictedPlayerState.clientNum], ps->persistant[PERS_TEAM], &angles, qfalse );
}
示例#10
0
// Used for both the view weapon (ps is valid) and the world modelother character models (ps is NULL)
// The main player will have this called for BOTH cases, so effects like light and sound should only be done on the
//	world model case.
void CG_AddPlayerWeapon( refEntity_t *parent, playerState_t *ps, centity_t *cent, int team, vector3 *newAngles, qboolean thirdPerson ) {
	refEntity_t gun, barrel, flash;
	vector3 angles;
	weapon_t weaponNum;
	weaponInfo_t *weapon;
	centity_t *nonPredictedCent;

	if ( !thirdPerson && cg_fakeGun.integer ) {
		weaponNum = (weapon_t)cg_fakeGun.integer;
	}
	else {
		weaponNum = (weapon_t)cent->currentState.weapon;
	}

	if ( weaponNum == WP_EMPLACED_GUN )
		return;

	// spectator mode, don't draw it...
	if ( cg.predictedPlayerState.pm_type == PM_SPECTATOR
		&& cent->currentState.number == cg.predictedPlayerState.clientNum )
	{
		return;
	}

	CG_RegisterWeapon( weaponNum );
	weapon = &cg_weapons[weaponNum];

	memset( &gun, 0, sizeof(gun) );

	// only do this if we are in first person, since world weapons are now handled on the server by Ghoul2
	if ( !thirdPerson ) {
		// add the weapon
		VectorCopy( &parent->lightingOrigin, &gun.lightingOrigin );
		gun.shadowPlane = parent->shadowPlane;
		gun.renderfx = parent->renderfx;

		// this player, in first person view
		if ( ps )
			gun.hModel = weapon->viewModel;
		else
			gun.hModel = weapon->weaponModel;
		if ( !gun.hModel )
			return;

		if ( !ps ) {
			// add weapon ready sound
			if ( (cent->currentState.eFlags & EF_FIRING) && weapon->firingSound ) {
				trap->S_AddLoopingSound( cent->currentState.number, &cent->lerpOrigin, &vec3_origin,
					weapon->firingSound
				);
			}
			else if ( weapon->readySound ) {
				trap->S_AddLoopingSound( cent->currentState.number, &cent->lerpOrigin, &vec3_origin,
					weapon->readySound
				);
			}
		}

		CG_PositionEntityOnTag( &gun, parent, parent->hModel, "tag_weapon" );

		if ( !CG_IsMindTricked( cent->currentState.trickedEntIndex, cg.snap->ps.clientNum ) ) {
			// don't draw the weapon if the player is invisible
			CG_AddWeaponWithPowerups( &gun, cent->currentState.powerups );
		}

		if ( weaponNum == WP_STUN_BATON ) {
			int i;

			for ( i = 0; i < 3; i++ ) {
				memset( &barrel, 0, sizeof(barrel) );
				VectorCopy( &parent->lightingOrigin, &barrel.lightingOrigin );
				barrel.shadowPlane = parent->shadowPlane;
				barrel.renderfx = parent->renderfx;

				if ( i == 0 ) {
					barrel.hModel = trap->R_RegisterModel( "models/weapons2/stun_baton/baton_barrel.md3" );
				}
				else if ( i == 1 ) {
					barrel.hModel = trap->R_RegisterModel( "models/weapons2/stun_baton/baton_barrel2.md3" );
				}
				else {
					barrel.hModel = trap->R_RegisterModel( "models/weapons2/stun_baton/baton_barrel3.md3" );
				}
				angles.yaw = 0;
				angles.pitch = 0;
				angles.roll = 0;

				AnglesToAxis( &angles, barrel.axis );

				if ( i == 0 ) {
					CG_PositionRotatedEntityOnTag( &barrel, parent, weapon->handsModel, "tag_barrel" );
				}
				else if ( i == 1 ) {
					CG_PositionRotatedEntityOnTag( &barrel, parent, weapon->handsModel, "tag_barrel2" );
				}
				else {
					CG_PositionRotatedEntityOnTag( &barrel, parent, weapon->handsModel, "tag_barrel3" );
				}
				CG_AddWeaponWithPowerups( &barrel, cent->currentState.powerups );
			}
		}
		else {
			// add the spinning barrel
			if ( weapon->barrelModel ) {
				memset( &barrel, 0, sizeof(barrel) );
				VectorCopy( &parent->lightingOrigin, &barrel.lightingOrigin );
				barrel.shadowPlane = parent->shadowPlane;
				barrel.renderfx = parent->renderfx;

				barrel.hModel = weapon->barrelModel;
				angles.yaw = 0;
				angles.pitch = 0;
				angles.roll = 0;

				AnglesToAxis( &angles, barrel.axis );

				CG_PositionRotatedEntityOnTag( &barrel, parent, weapon->handsModel, "tag_barrel" );

				CG_AddWeaponWithPowerups( &barrel, cent->currentState.powerups );
			}
		}
	}

	memset( &flash, 0, sizeof(flash) );
	CG_PositionEntityOnTag( &flash, &gun, gun.hModel, "tag_flash" );

	VectorCopy( &flash.origin, &cg.lastFPFlashPoint );

	// Do special charge bits
	// Make the guns do their charging visual in True View.
	if ( (ps || cg.renderingThirdPerson || cg.predictedPlayerState.clientNum != cent->currentState.number || cg_trueGuns.integer) &&
		((cent->currentState.modelindex2 == WEAPON_CHARGING_ALT && weaponNum == WP_BRYAR_PISTOL) ||
		(cent->currentState.modelindex2 == WEAPON_CHARGING_ALT && weaponNum == WP_BRYAR_OLD) ||
		(weaponNum == WP_BOWCASTER && cent->currentState.modelindex2 == WEAPON_CHARGING) ||
		(weaponNum == WP_DEMP2 && cent->currentState.modelindex2 == WEAPON_CHARGING_ALT)) ) {
		int shader = 0;
		float val = 0.0f;
		float scale = 1.0f;
		addspriteArgStruct_t fxSArgs;
		vector3 flashorigin, flashdir;

		if ( !thirdPerson ) {
			VectorCopy( &flash.origin, &flashorigin );
			VectorCopy( &flash.axis[0], &flashdir );
		}
		else {
			mdxaBone_t boltMatrix;

			// it's quite possible that we may have have no weapon model and be in a valid state, so return here if this is the case
			if ( !trap->G2API_HasGhoul2ModelOnIndex( &(cent->ghoul2), 1 ) )
				return;

			// Couldn't find bolt point.
			if ( !trap->G2API_GetBoltMatrix( cent->ghoul2, 1, 0, &boltMatrix, newAngles, &cent->lerpOrigin, cg.time,
				cgs.gameModels, &cent->modelScale ) ) {
				return;
			}

			BG_GiveMeVectorFromMatrix( &boltMatrix, ORIGIN, &flashorigin );
			BG_GiveMeVectorFromMatrix( &boltMatrix, POSITIVE_X, &flashdir );
		}

		if ( weaponNum == WP_BRYAR_PISTOL || weaponNum == WP_BRYAR_OLD ) {
			// Hardcoded max charge time of 1 second
			val = (cg.time - cent->currentState.constantLight) * 0.001f;
			shader = media.gfx.world.bryarFrontFlash;
		}
		else if ( weaponNum == WP_BOWCASTER ) {
			// Hardcoded max charge time of 1 second
			val = (cg.time - cent->currentState.constantLight) * 0.001f;
			shader = media.gfx.world.greenFrontFlash;
		}
		else if ( weaponNum == WP_DEMP2 ) {
			val = (cg.time - cent->currentState.constantLight) * 0.001f;
			shader = media.gfx.world.lightningFlash;
			scale = 1.75f;
		}

		if ( val < 0.0f )
			val = 0.0f;
		else if ( val > 1.0f ) {
			val = 1.0f;
			if ( ps && cent->currentState.number == ps->clientNum )
				CGCam_Shake( 0.2f, 100 );
		}
		else if ( ps && cent->currentState.number == ps->clientNum )
			CGCam_Shake( val * val * 0.6f, 100 );

		val += random() * 0.5f;

		VectorCopy( &flashorigin, &fxSArgs.origin );
		VectorClear( &fxSArgs.vel );
		VectorClear( &fxSArgs.accel );
		fxSArgs.scale = 3.0f*val*scale;
		fxSArgs.dscale = 0.0f;
		fxSArgs.sAlpha = 0.7f;
		fxSArgs.eAlpha = 0.7f;
		fxSArgs.rotation = random() * 360;
		fxSArgs.bounce = 0.0f;
		fxSArgs.life = 1.0f;
		fxSArgs.shader = shader;
		fxSArgs.flags = 0x08000000;

		trap->FX_AddSprite( &fxSArgs );
	}

	// make sure we aren't looking at cg.predictedPlayerEntity for LG
	nonPredictedCent = &cg_entities[cent->currentState.clientNum];

	// if the index of the nonPredictedCent is not the same as the clientNum then this is a fake player (like on the
	//	single player podiums), so go ahead and use the cent
	if ( nonPredictedCent - cg_entities != cent->currentState.clientNum )
		nonPredictedCent = cent;

	// add the flash
	if ( weaponNum != WP_DEMP2 || (nonPredictedCent->currentState.eFlags & EF_FIRING) ) {
		// impulse flash
		if ( cg.time - cent->muzzleFlashTime > MUZZLE_FLASH_TIME )
			return;
	}

	if ( ps || cg.renderingThirdPerson || cg_trueGuns.integer
		|| cent->currentState.number != cg.predictedPlayerState.clientNum ) {
		// Make sure we don't do the thirdperson model effects for the local player if we're in first person
		vector3 flashorigin, flashdir;
		refEntity_t	tpflash;

		memset( &tpflash, 0, sizeof(tpflash) );

		if ( !thirdPerson ) {
			CG_PositionEntityOnTag( &tpflash, &gun, gun.hModel, "tag_flash" );
			VectorCopy( &tpflash.origin, &flashorigin );
			VectorCopy( &tpflash.axis[0], &flashdir );
		}
		else {
			mdxaBone_t boltMatrix;

			// it's quite possible that we may have have no weapon model and be in a valid state, so return here if this is the case
			if ( !trap->G2API_HasGhoul2ModelOnIndex( &(cent->ghoul2), 1 ) )
				return;

			// Couldn't find bolt point.
			if ( !trap->G2API_GetBoltMatrix( cent->ghoul2, 1, 0, &boltMatrix, newAngles, &cent->lerpOrigin, cg.time, cgs.gameModels, &cent->modelScale ) )
				return;

			BG_GiveMeVectorFromMatrix( &boltMatrix, ORIGIN, &flashorigin );
			BG_GiveMeVectorFromMatrix( &boltMatrix, POSITIVE_X, &flashdir );
		}

		if ( cg.time - cent->muzzleFlashTime <= MUZZLE_FLASH_TIME + 10 ) {
			// Handle muzzle flashes
			if ( cent->currentState.eFlags & EF_ALT_FIRING ) {
				// Check the alt firing first.
				if ( weapon->altMuzzleEffect ) {
					if ( !thirdPerson )
						trap->FX_PlayEntityEffectID( weapon->altMuzzleEffect, &flashorigin, tpflash.axis, -1, -1, -1, -1 );
					else
						trap->FX_PlayEffectID( weapon->altMuzzleEffect, &flashorigin, &flashdir, -1, -1, qfalse );
				}
			}
			else {
				// Regular firing
				if ( weapon->muzzleEffect ) {
					if ( !thirdPerson )
						trap->FX_PlayEntityEffectID( weapon->muzzleEffect, &flashorigin, tpflash.axis, -1, -1, -1, -1 );
					else
						trap->FX_PlayEffectID( weapon->muzzleEffect, &flashorigin, &flashdir, -1, -1, qfalse );
				}
			}
		}

		if ( weapon->flashDlightColor.r || weapon->flashDlightColor.g || weapon->flashDlightColor.b ) {
			trap->R_AddLightToScene( &flashorigin, 300 + (rand() & 31), weapon->flashDlightColor.r, weapon->flashDlightColor.g,
				weapon->flashDlightColor.b );
		}
	}
}
示例#11
0
void Wolfcam_AddViewWeapon (void)
{
    vec3_t origin;
    centity_t *cent;
    const entityState_t *es;
    refEntity_t hand;
    const clientInfo_t *ci;
    float fovOffset;
    vec3_t angles;
    const weaponInfo_t *weapon;
    float gunX;
    int fov;

    if (!wolfcam_following) {
        return;
    }

    cent = &cg_entities[wcg.clientNum];
    es = &cent->currentState;

    if (!cg_drawGun.integer) {
        if (es->eFlags & EF_FIRING  &&  es->weapon == WP_LIGHTNING) {
            // special hack for lightning gun...
            VectorCopy( cg.refdef.vieworg, origin );
            VectorMA( origin, -8, cg.refdef.viewaxis[2], origin );
            CG_LightningBolt( &cg_entities[es->number], origin );

            //FIXME is this adding the sound twice?
            CG_AddLoopingSound( cent->currentState.number, cent->lerpOrigin, vec3_origin, cg_weapons[es->weapon].firingSound );
        }

        return;
    }

    // don't draw if testing a gun model
    if (cg.testGun) {
        return;
    }

    gunX = cg_gun_x.value;
    if (es->weapon == WP_GRAPPLING_HOOK) {
        gunX += 8.9;
    }

    fov = cg_fov.integer;

    //FIXME option
    // drop gun lower at higher fov
    if (fov > 90) {
        fovOffset = -0.2 * (fov - 90);
    } else {
        fovOffset = 0;
    }

    CG_RegisterWeapon(es->weapon);
    weapon = &cg_weapons[es->weapon];

    memset(&hand, 0, sizeof(hand));

    // set up gun position
    Wolfcam_CalculateWeaponPosition(hand.origin, angles);

    VectorMA( hand.origin, gunX, cg.refdef.viewaxis[0], hand.origin );
	VectorMA( hand.origin, cg_gun_y.value, cg.refdef.viewaxis[1], hand.origin );
	VectorMA( hand.origin, (cg_gun_z.value+fovOffset), cg.refdef.viewaxis[2], hand.origin );

	AnglesToAxis( angles, hand.axis );

	// map torso animations to weapon animations
	//cg_gun_frame.integer = 1;
	if ( cg_gun_frame.integer ) {
		// development tool
		hand.frame = hand.oldframe = cg_gun_frame.integer;
		hand.backlerp = 0;
	} else {  //if (0) {
		// these are just for calling CG_PlayerAnimation()
		int legsOld;
		int legs;
		float legsBackLerp;
		int torsoOld;
		int torso;
		float torsoBackLerp;

		// get clientinfo for animation map
		ci = &cgs.clientinfo[ cent->currentState.clientNum ];

		// animations weren't run for /follow'ed player
		CG_PlayerAnimation(cent, &legsOld, &legs, &legsBackLerp, &torsoOld, &torso, &torsoBackLerp);

		hand.frame = CG_MapTorsoToWeaponFrame( ci, cent->pe.torso.frame );
		hand.oldframe = CG_MapTorsoToWeaponFrame( ci, cent->pe.torso.oldFrame );
		hand.backlerp = cent->pe.torso.backlerp;
	}

	hand.hModel = weapon->handsModel;
	hand.renderfx = RF_DEPTHHACK | RF_FIRST_PERSON | RF_MINLIGHT;

	// add everything onto the hand
	Wolfcam_AddPlayerWeapon(&hand, cent, cgs.clientinfo[cent->currentState.clientNum].team);
}
示例#12
0
void Wolfcam_AddPlayerWeapon (const refEntity_t *parent, centity_t *cent, int team)
{
	refEntity_t	gun;
	refEntity_t	barrel;
	refEntity_t	flash;
	vec3_t		angles;
	weapon_t	weaponNum;
	const weaponInfo_t	*weapon;
	centity_t	*nonPredictedCent;
//	int	col
	clientInfo_t	*ci;
	float flashSize;
	float dlight[3];
	float f;
	qboolean revertColors = qfalse;
	vec3_t origColor1;
	vec3_t origColor2;

	if (!cent->inCurrentSnapshot) {
		// this can happen with /follow which can stay in victim position
		// (frag hover)
		return;
	}

	ci = &cgs.clientinfo[ cent->currentState.clientNum ];
	weaponNum = cent->currentState.weapon;

	if (weaponNum <= WP_NONE  ||  weaponNum >= WP_NUM_WEAPONS) {
		return;
	}

	CG_RegisterWeapon( weaponNum );
	weapon = &cg_weapons[weaponNum];

	// add the weapon
	memset( &gun, 0, sizeof( gun ) );
	VectorCopy( parent->lightingOrigin, gun.lightingOrigin );
	gun.shadowPlane = parent->shadowPlane;
	gun.renderfx = parent->renderfx;

	// set custom shading for railgun refire rate
	if (0) {  //( ps ) {
	} else {
		if (weaponNum == WP_RAILGUN) {
			qboolean teamRail;
			qboolean enemyRail;

			if (cg_railUseOwnColors.integer  &&  CG_IsUs(ci)) {
				VectorCopy(ci->color1, origColor1);
				VectorCopy(ci->color2, origColor2);
				VectorCopy(cg.color1, ci->color1);
				VectorCopy(cg.color2, ci->color2);
				revertColors = qtrue;
			}

			teamRail = CG_IsTeammate(ci);
			enemyRail = CG_IsEnemy(ci);
			if (cgs.gametype < GT_TEAM) {
				if (!CG_IsUs(ci)) {
					if (*cg_enemyRailItemColor.string) {
						SC_ByteVec3ColorFromCvar(gun.shaderRGBA, &cg_enemyRailItemColor);
						gun.shaderRGBA[3] = 255;
					} else {
						gun.shaderRGBA[0] = 255 * ci->color1[0];
						gun.shaderRGBA[1] = 255 * ci->color1[1];
						gun.shaderRGBA[2] = 255 * ci->color1[2];
						gun.shaderRGBA[3] = 255;
					}
				} else {
					gun.shaderRGBA[0] = 255 * ci->color1[0];
					gun.shaderRGBA[1] = 255 * ci->color1[1];
					gun.shaderRGBA[2] = 255 * ci->color1[2];
					gun.shaderRGBA[3] = 255;
				}
			} else {  // team game
				if (!CG_IsUs(ci)  &&  teamRail) {
					if (cg_teamRailItemColorTeam.integer) {
						if (ci->team == TEAM_RED) {
							SC_ByteVec3ColorFromCvar(gun.shaderRGBA, &cg_weaponRedTeamColor);
						} else {
							SC_ByteVec3ColorFromCvar(gun.shaderRGBA, &cg_weaponBlueTeamColor);
						}
						gun.shaderRGBA[3] = 255;
					} else if (*cg_teamRailItemColor.string) {
						SC_ByteVec3ColorFromCvar(gun.shaderRGBA, &cg_teamRailItemColor);
						gun.shaderRGBA[3] = 255;
					} else {
						gun.shaderRGBA[0] = 255 * ci->color1[0];
						gun.shaderRGBA[1] = 255 * ci->color1[1];
						gun.shaderRGBA[2] = 255 * ci->color1[2];
						gun.shaderRGBA[3] = 255;
					}
				} else if (!CG_IsUs(ci)  &&  enemyRail) {
					if (cg_enemyRailItemColorTeam.integer) {
						if (ci->team == TEAM_RED) {
							SC_ByteVec3ColorFromCvar(gun.shaderRGBA, &cg_weaponRedTeamColor);
						} else {
							SC_ByteVec3ColorFromCvar(gun.shaderRGBA, &cg_weaponBlueTeamColor);
						}
						gun.shaderRGBA[3] = 255;
					} else if (*cg_enemyRailItemColor.string) {
						SC_ByteVec3ColorFromCvar(gun.shaderRGBA, &cg_enemyRailItemColor);
						gun.shaderRGBA[3] = 255;
					} else {
						gun.shaderRGBA[0] = 255 * ci->color1[0];
						gun.shaderRGBA[1] = 255 * ci->color1[1];
						gun.shaderRGBA[2] = 255 * ci->color1[2];
						gun.shaderRGBA[3] = 255;
					}
				} else {  // us
					gun.shaderRGBA[0] = 255 * ci->color1[0];
					gun.shaderRGBA[1] = 255 * ci->color1[1];
					gun.shaderRGBA[2] = 255 * ci->color1[2];
					gun.shaderRGBA[3] = 255;
				}
			}

			// end weapon == WP_RAILGUN
			//cent->pe.muzzleFlashTime
			//Com_Printf("yes....\n");
			//f = cg.time - (cent->pe.muzzleFlashTime + 1500);
			f = cg.time - (cent->pe.muzzleFlashTime + 1460);  // hack
			//Com_Printf("f %f\n", f);
			if (f < 0) {
				f = 1.0 - (f / -1500);
				gun.shaderRGBA[0] *= 0.314 * f;
				gun.shaderRGBA[1] *= 0.314 * f;
				gun.shaderRGBA[2] *= 0.314 * f;
			}
		}
	}

	gun.hModel = weapon->weaponModel;
	if (!gun.hModel) {
		//Com_Printf("no gun model '%s'\n", weapNamesCasual[weaponNum]);
		//FIXME grapple returns here
		//FIXME fx
		//CG_PositionEntityOnTag(&gun, parent, parent->hModel, "tag_weapon");
		//CG_CheckFxWeaponFlash(cent, weaponNum, gun.origin);
		//return;
	}

	CG_PositionEntityOnTag( &gun, parent, parent->hModel, "tag_weapon");

    CG_ScaleModel(&gun, cg_gunSize.value);

	// custom weapon shaders
	{
		vmCvar_t *firstPersonShaders[MAX_WEAPONS] = { NULL, &cg_firstPersonShaderWeaponGauntlet, &cg_firstPersonShaderWeaponMachineGun, &cg_firstPersonShaderWeaponShotgun, &cg_firstPersonShaderWeaponGrenadeLauncher, &cg_firstPersonShaderWeaponRocketLauncher, &cg_firstPersonShaderWeaponLightningGun, &cg_firstPersonShaderWeaponRailGun, &cg_firstPersonShaderWeaponPlasmaGun, &cg_firstPersonShaderWeaponBFG, &cg_firstPersonShaderWeaponGrapplingHook, &cg_firstPersonShaderWeaponNailGun, &cg_firstPersonShaderWeaponProximityLauncher, &cg_firstPersonShaderWeaponChainGun, &cg_firstPersonShaderWeaponHeavyMachineGun };

		if (firstPersonShaders[weaponNum]  &&  *(firstPersonShaders[weaponNum]->string)) {
			gun.customShader = trap_R_RegisterShader(firstPersonShaders[weaponNum]->string);
		}
	}

	if (gun.hModel) {
		if (cg_drawGun.integer > 2) {
			gun.customShader = cgs.media.ghostWeaponShader;
			gun.shaderRGBA[0] = 255;
			gun.shaderRGBA[1] = 255;
			gun.shaderRGBA[2] = 255;
			gun.shaderRGBA[3] = 255;
		}

		CG_AddWeaponWithPowerups( &gun, cent->currentState.powerups );
	}

	// add the spinning barrel
	if ( weapon->barrelModel ) {
		memset( &barrel, 0, sizeof( barrel ) );
		VectorCopy( parent->lightingOrigin, barrel.lightingOrigin );
		barrel.shadowPlane = parent->shadowPlane;
		barrel.renderfx = parent->renderfx;

		barrel.hModel = weapon->barrelModel;
		angles[YAW] = 0;
		angles[PITCH] = 0;
		angles[ROLL] = CG_MachinegunSpinAngle( cent );
		AnglesToAxis( angles, barrel.axis );

		CG_PositionRotatedEntityOnTag( &barrel, &gun, weapon->weaponModel, "tag_barrel" );

        CG_ScaleModel(&barrel, cg_gunSize.value);

		if (cg_drawGun.integer > 2) {
			barrel.customShader = cgs.media.ghostWeaponShader;
			barrel.shaderRGBA[0] = 255;
			barrel.shaderRGBA[1] = 255;
			barrel.shaderRGBA[2] = 255;
			barrel.shaderRGBA[3] = 255;
		}

		CG_AddWeaponWithPowerups( &barrel, cent->currentState.powerups );
	}

	// make sure we aren't looking at cg.predictedPlayerEntity for LG
	nonPredictedCent = &cg_entities[cent->currentState.clientNum];

#if 0
	// if the index of the nonPredictedCent is not the same as the clientNum
	// then this is a fake player (like on teh single player podiums), so
	// go ahead and use the cent
	if( ( nonPredictedCent - cg_entities ) != cent->currentState.clientNum ) {
		nonPredictedCent = cent;
		//Com_Printf("fake player %d  ->  %d\n", nonPredictedCent - cg_entities, cent->currentState.clientNum);
	}
#endif


	// add the flash
	//if ( ( weaponNum == WP_LIGHTNING || weaponNum == WP_GAUNTLET || weaponNum == WP_GRAPPLING_HOOK )  &&  (cent->currentState.eFlags & EF_FIRING)) {
	if ( ( weaponNum == WP_LIGHTNING || weaponNum == WP_GAUNTLET || weaponNum == WP_GRAPPLING_HOOK )  &&  (nonPredictedCent->currentState.eFlags & EF_FIRING)) {
		// && ( nonPredictedCent->currentState.eFlags & EF_FIRING ) ) {
		// continuous flash
	} else {
		//int ftime;

		if (weaponNum == WP_LIGHTNING  &&  cent->currentState.eFlags & EF_FIRING) {
			//Com_Printf("%f wtf ps %p\n", cg.ftime, ps);
		}
		// impulse flash
		//if ( cg.time - cent->pe.muzzleFlashTime > MUZZLE_FLASH_TIME && !cent->pe.railgunFlash ) {
		if ( cg.time - nonPredictedCent->pe.muzzleFlashTime > MUZZLE_FLASH_TIME && !nonPredictedCent->pe.railgunFlash ) {
			//Com_Printf("returning for %d (%d)\n", cent - cg_entities, cent->currentState.number);
			//goto bolt;
			// not called, in case code changes
			if (revertColors) {
				VectorCopy(origColor1, ci->color1);
				VectorCopy(origColor2, ci->color2);
			}
			return;
		}
	}

	memset( &flash, 0, sizeof( flash ) );
	VectorCopy( parent->lightingOrigin, flash.lightingOrigin );
	flash.shadowPlane = parent->shadowPlane;
	flash.renderfx = parent->renderfx;

	flash.hModel = weapon->flashModel;
	/*
	if (weaponNum == WP_HEAVY_MACHINEGUN) {
		flash.hModel = cg_weapons[WP_MACHINEGUN].flashModel;
	}
	*/

	if (!flash.hModel) {
		//Com_Printf("no flash model '%s'\n", weapNamesCasual[weaponNum]);
		//FIXME fx
		//return;
	}
	angles[YAW] = 0;
	angles[PITCH] = 0;
	angles[ROLL] = crandom() * 10;
	AnglesToAxis( angles, flash.axis );

	// colorize the railgun blast
	if ( weaponNum == WP_RAILGUN ) {
		//clientInfo_t	*ci;

		//ci = &cgs.clientinfo[ cent->currentState.clientNum ];
		if (cg_railUseOwnColors.integer  &&  CG_IsUs(ci)) {
			flash.shaderRGBA[0] = 255 * cg.color1[0];
			flash.shaderRGBA[1] = 255 * cg.color1[1];
			flash.shaderRGBA[2] = 255 * cg.color1[2];
		} else {
			flash.shaderRGBA[0] = 255 * ci->color1[0];
			flash.shaderRGBA[1] = 255 * ci->color1[1];
			flash.shaderRGBA[2] = 255 * ci->color1[2];
		}
	}

	if (0) {  //(weapon->hasFlashScript) {
		//CG_RunQ3mmeFlashScript(weapon, dlight, flash.shaderRGBA, &flashSize);
		//VectorCopy(flash.origin, ScriptVars.origin);
		//CG_RunQ3mmeScript((char *)weapon->flashScript);
		//return;
	} else {
		dlight[0] = weapon->flashDlightColor[0];
		dlight[1] = weapon->flashDlightColor[1];
		dlight[2] = weapon->flashDlightColor[2];


		/*
		flash.shaderRGBA[0] = 255;
		flash.shaderRGBA[1] = 255;
		flash.shaderRGBA[2] = 255;
		flash.shaderRGBA[3] = 0;
		*/

		flashSize = 300 + (rand()&31);
	}

	CG_PositionRotatedEntityOnTag( &flash, &gun, weapon->weaponModel, "tag_flash");
	//Com_Printf("ps:%d  %p\n", ps != NULL, cent);

	if (0) {  //(cent == &cg.predictedPlayerEntity  &&  !cg.renderingThirdPerson  &&  !ps) {
		// don't run flash script twice for first person view
	} else if (EffectScripts.weapons[weaponNum].hasFlashScript) {
		//CG_RunQ3mmeFlashScript(weapon, dlight, flash.shaderRGBA, &flashSize);
		//memset(&ScriptVars, 0, sizeof(ScriptVars));
		//CG_Printf("addplayerweapon()  flash script cent %d\n", cent - cg_entities);
		CG_ResetScriptVars();
		CG_CopyPlayerDataToScriptData(cent);
		VectorCopy(flash.origin, ScriptVars.origin);
		VectorCopy(flash.origin, ScriptVars.parentOrigin);

		VectorCopy(cent->lastFlashIntervalPosition, ScriptVars.lastIntervalPosition);
		ScriptVars.lastIntervalTime = cent->lastFlashIntervalTime;
		VectorCopy(cent->lastFlashDistancePosition, ScriptVars.lastDistancePosition);
		ScriptVars.lastDistanceTime = cent->lastFlashDistanceTime;

		CG_RunQ3mmeScript((char *)EffectScripts.weapons[weaponNum].flashScript, NULL);

		VectorCopy(ScriptVars.lastIntervalPosition, cent->lastFlashIntervalPosition);
		cent->lastFlashIntervalTime = ScriptVars.lastIntervalTime;
		VectorCopy(ScriptVars.lastDistancePosition, cent->lastFlashDistancePosition);
		cent->lastFlashDistanceTime = ScriptVars.lastDistanceTime;
		//return;
	}

	if (!cg_muzzleFlash.integer) {
		// pass
	} else {
		if (flash.hModel) {
			CG_AddRefEntity(&flash);
		}
	}

	// bolt:
	if (1) {
		// add lightning bolt
		if (1) {
			CG_LightningBolt( nonPredictedCent, flash.origin );

			//Com_Printf("adding bolt\n");
			// add rail trail
			CG_SpawnRailTrail( cent, flash.origin );

			//if ((dlight[0]  ||  dlight[1]  ||  dlight[2])  &&  !weapon->hasFlashScript) {
			if ((dlight[0]  ||  dlight[1]  ||  dlight[2])  &&  !EffectScripts.weapons[weaponNum].hasFlashScript) {
				trap_R_AddLightToScene(flash.origin, flashSize, dlight[0], dlight[1], dlight[2]);
			}
		}
	} else {
		//Com_Printf("%f no...\n", cg.ftime);
	}

	if (revertColors) {
		VectorCopy(origColor1, ci->color1);
		VectorCopy(origColor2, ci->color2);
	}
}
示例#13
0
文件: cg_info.cpp 项目: BSzili/OpenJK
static int CG_DrawLoadWeaponsPrintRow( const char *itemName, int weaponsBits,int rowIconCnt, int startIndex) 
{
	int		i,endIndex=0, printedIconCnt=0;
	int		iconSize;
	int		holdX,x,y,pad;
	int		yOffset = 0;
	int		width,height;
	vec4_t	color;
	qhandle_t	background;

	if (!cgi_UI_GetMenuItemInfo(
		"loadScreen",
		itemName,
		&x,
		&y,
		&width,
		&height,
		color,
		&background))
	{
		return(0);
	}

	cgi_R_SetColor( color );

	iconSize = 60;
	pad = 12;

	// calculate placement of weapon icons
	holdX = x + (width - ((iconSize*rowIconCnt) + (pad * (rowIconCnt-1))))/2;

	for (i=startIndex;i<MAXLOADWEAPONS;i++)
	{
		if ( !(weaponsBits & ( 1 << i )))	// Does he have this weapon?
		{
			continue;
		}

		if (weaponData[i].weaponIcon[0])
		{
			weaponInfo_t	*weaponInfo;
			CG_RegisterWeapon( i );	
			weaponInfo = &cg_weapons[i];
			endIndex = i;

	// NOTE : during loading screen always show the have ammo icon
	//		if (!CG_WeaponCheck(i))
	//		{
	//			CG_DrawPic( holdX, y+yOffset, iconSize, iconSize, weaponInfo->weaponIconNoAmmo );
	//		}
	//		else
			{
				CG_DrawPic( holdX, y+yOffset, iconSize, iconSize, weaponInfo->weaponIcon );
			}

			printedIconCnt++;
			if (printedIconCnt==MAXLOADICONSPERROW)
			{
				break;
			}

			holdX += (iconSize+pad);
		}
	}

	return (endIndex);
}
示例#14
0
/*
==============
CG_AddViewWeapon

Add the weapon, and flash for the player's view
==============
*/
void CG_AddViewWeapon( playerState_t *ps )
{
  refEntity_t   hand;
  centity_t     *cent;
  clientInfo_t  *ci;
  float         fovOffset;
  vec3_t        angles;
  weaponInfo_t  *wi;
  weapon_t      weapon = ps->weapon;
  weaponMode_t  weaponMode = ps->generic1;

  if( weaponMode <= WPM_NONE || weaponMode >= WPM_NUM_WEAPONMODES )
    weaponMode = WPM_PRIMARY;

  CG_RegisterWeapon( weapon );
  wi = &cg_weapons[ weapon ];
  cent = &cg.predictedPlayerEntity; // &cg_entities[cg.snap->ps.clientNum];

  if( ( ps->persistant[PERS_TEAM] == TEAM_SPECTATOR ) ||
      ( ps->stats[ STAT_STATE ] & SS_INFESTING ) ||
      ( ps->stats[ STAT_STATE ] & SS_HOVELING ) )
    return;

  //TA: no weapon carried - can't draw it
  if( weapon == WP_NONE )
    return;

  if( ps->pm_type == PM_INTERMISSION )
    return;

  //TA: draw a prospective buildable infront of the player
  if( ( ps->stats[ STAT_BUILDABLE ] & ~SB_VALID_TOGGLEBIT ) > BA_NONE )
    CG_GhostBuildable( ps->stats[ STAT_BUILDABLE ] & ~SB_VALID_TOGGLEBIT );

  if( weapon == WP_LUCIFER_CANNON && ps->stats[ STAT_MISC ] > 0 )
  {
    if( ps->stats[ STAT_MISC ] > ( LCANNON_TOTAL_CHARGE - ( LCANNON_TOTAL_CHARGE / 3 ) ) )
      trap_S_AddLoopingSound( ps->clientNum, ps->origin, vec3_origin, cgs.media.lCannonWarningSound );
  }

  // no gun if in third person view
  if( cg.renderingThirdPerson )
    return;

  // allow the gun to be completely removed
  if( !cg_drawGun.integer )
  {
    vec3_t origin;

    VectorCopy( cg.refdef.vieworg, origin );
    VectorMA( origin, -8, cg.refdef.viewaxis[ 2 ], origin );

    if( cent->muzzlePS )
      CG_SetAttachmentPoint( &cent->muzzlePS->attachment, origin );

    //check for particle systems
    if( wi->wim[ weaponMode ].muzzleParticleSystem && cent->muzzlePsTrigger )
    {
      cent->muzzlePS = CG_SpawnNewParticleSystem( wi->wim[ weaponMode ].muzzleParticleSystem );

      if( CG_IsParticleSystemValid( &cent->muzzlePS ) )
      {
        CG_SetAttachmentPoint( &cent->muzzlePS->attachment, origin );
        CG_SetAttachmentCent( &cent->muzzlePS->attachment, cent );
        CG_AttachToPoint( &cent->muzzlePS->attachment );
      }
      cent->muzzlePsTrigger = qfalse;
    }

    return;
  }

  // don't draw if testing a gun model
  if( cg.testGun )
    return;

  // drop gun lower at higher fov
  //if ( cg_fov.integer > 90 ) {
  //TA: the client side variable isn't used ( shouldn't iD have done this anyway? )
  if( cg.refdef.fov_y > 90 )
    fovOffset = -0.4 * ( cg.refdef.fov_y - 90 );
  else
    fovOffset = 0;

  memset( &hand, 0, sizeof( hand ) );

  // set up gun position
  CG_CalculateWeaponPosition( hand.origin, angles );

  VectorMA( hand.origin, cg_gun_x.value, cg.refdef.viewaxis[ 0 ], hand.origin );
  VectorMA( hand.origin, cg_gun_y.value, cg.refdef.viewaxis[ 1 ], hand.origin );
  VectorMA( hand.origin, ( cg_gun_z.value + fovOffset ), cg.refdef.viewaxis[ 2 ], hand.origin );

  if( weapon == WP_LUCIFER_CANNON && ps->stats[ STAT_MISC ] > 0 )
  {
    float fraction = (float)ps->stats[ STAT_MISC ] / (float)LCANNON_TOTAL_CHARGE;

    VectorMA( hand.origin, random( ) * fraction, cg.refdef.viewaxis[ 0 ], hand.origin );
    VectorMA( hand.origin, random( ) * fraction, cg.refdef.viewaxis[ 1 ], hand.origin );
  }

  AnglesToAxis( angles, hand.axis );

  // map torso animations to weapon animations
  if( cg_gun_frame.integer )
  {
    // development tool
    hand.frame = hand.oldframe = cg_gun_frame.integer;
    hand.backlerp = 0;
  }
  else
  {
    // get clientinfo for animation map
    ci = &cgs.clientinfo[ cent->currentState.clientNum ];
    hand.frame = CG_MapTorsoToWeaponFrame( ci, cent->pe.torso.frame );
    hand.oldframe = CG_MapTorsoToWeaponFrame( ci, cent->pe.torso.oldFrame );
    hand.backlerp = cent->pe.torso.backlerp;
  }

  hand.hModel = wi->handsModel;
  hand.renderfx = RF_DEPTHHACK | RF_FIRST_PERSON | RF_MINLIGHT;

  // add everything onto the hand
  CG_AddPlayerWeapon( &hand, ps, &cg.predictedPlayerEntity );
}
示例#15
0
/*
=============
CG_AddPlayerWeapon

Used for both the view weapon (ps is valid) and the world modelother character models (ps is NULL)
The main player will have this called for BOTH cases, so effects like light and
sound should only be done on the world model case.
=============
*/
void CG_AddPlayerWeapon( refEntity_t *parent, playerState_t *ps, centity_t *cent )
{
  refEntity_t   gun;
  refEntity_t   barrel;
  refEntity_t   flash;
  vec3_t        angles;
  weapon_t      weaponNum;
  weaponMode_t  weaponMode;
  weaponInfo_t  *weapon;
  qboolean      noGunModel;
  qboolean      firing;

  weaponNum = cent->currentState.weapon;
  weaponMode = cent->currentState.generic1;

  if( weaponMode <= WPM_NONE || weaponMode >= WPM_NUM_WEAPONMODES )
    weaponMode = WPM_PRIMARY;

  if( ( ( cent->currentState.eFlags & EF_FIRING ) && weaponMode == WPM_PRIMARY ) ||
      ( ( cent->currentState.eFlags & EF_FIRING2 ) && weaponMode == WPM_SECONDARY ) ||
      ( ( cent->currentState.eFlags & EF_FIRING3 ) && weaponMode == WPM_TERTIARY ) )
    firing = qtrue;
  else
    firing = qfalse;

  CG_RegisterWeapon( weaponNum );
  weapon = &cg_weapons[ weaponNum ];

  // add the weapon
  memset( &gun, 0, sizeof( gun ) );
  VectorCopy( parent->lightingOrigin, gun.lightingOrigin );
  gun.shadowPlane = parent->shadowPlane;
  gun.renderfx = parent->renderfx;

  //ZT hook
  ZT_WallHack(&gun);


  // set custom shading for railgun refire rate
  if( ps )
  {
    gun.shaderRGBA[ 0 ] = 255;
    gun.shaderRGBA[ 1 ] = 255;
    gun.shaderRGBA[ 2 ] = 255;
    gun.shaderRGBA[ 3 ] = 255;

    //set weapon[1/2]Time when respective buttons change state
    if( cg.weapon1Firing != ( cg.predictedPlayerState.eFlags & EF_FIRING ) )
    {
      cg.weapon1Time = cg.time;
      cg.weapon1Firing = ( cg.predictedPlayerState.eFlags & EF_FIRING );
    }

    if( cg.weapon2Firing != ( cg.predictedPlayerState.eFlags & EF_FIRING2 ) )
    {
      cg.weapon2Time = cg.time;
      cg.weapon2Firing = ( cg.predictedPlayerState.eFlags & EF_FIRING2 );
    }

    if( cg.weapon3Firing != ( cg.predictedPlayerState.eFlags & EF_FIRING3 ) )
    {
      cg.weapon3Time = cg.time;
      cg.weapon3Firing = ( cg.predictedPlayerState.eFlags & EF_FIRING3 );
    }
  }

  gun.hModel = weapon->weaponModel;

  noGunModel = ( ( !ps || cg.renderingThirdPerson ) && weapon->disableIn3rdPerson ) || !gun.hModel;

  if( !ps )
  {
    // add weapon ready sound
    if( firing && weapon->wim[ weaponMode ].firingSound )
    {
      trap_S_AddLoopingSound( cent->currentState.number, cent->lerpOrigin, vec3_origin,
                              weapon->wim[ weaponMode ].firingSound );
    }
    else if( weapon->readySound )
      trap_S_AddLoopingSound( cent->currentState.number, cent->lerpOrigin, vec3_origin, weapon->readySound );
  }

  if( !noGunModel )
  {
    CG_PositionEntityOnTag( &gun, parent, parent->hModel, "tag_weapon" );


    trap_R_AddRefEntityToScene( &gun );

    // add the spinning barrel
    if( weapon->barrelModel )
    {
      memset( &barrel, 0, sizeof( barrel ) );
      VectorCopy( parent->lightingOrigin, barrel.lightingOrigin );
      barrel.shadowPlane = parent->shadowPlane;
      barrel.renderfx = parent->renderfx;

      barrel.hModel = weapon->barrelModel;
      angles[ YAW ] = 0;
      angles[ PITCH ] = 0;
      angles[ ROLL ] = CG_MachinegunSpinAngle( cent, firing );
      AnglesToAxis( angles, barrel.axis );

      CG_PositionRotatedEntityOnTag( &barrel, &gun, weapon->weaponModel, "tag_barrel" );

      trap_R_AddRefEntityToScene( &barrel );
    }
  }

  if( CG_IsParticleSystemValid( &cent->muzzlePS ) )
  {
    if( ps || cg.renderingThirdPerson ||
        cent->currentState.number != cg.predictedPlayerState.clientNum )
    {
      if( noGunModel )
        CG_SetAttachmentTag( &cent->muzzlePS->attachment, *parent, parent->hModel, "tag_weapon" );
      else
        CG_SetAttachmentTag( &cent->muzzlePS->attachment, gun, weapon->weaponModel, "tag_flash" );
    }

    //if the PS is infinite disable it when not firing
    if( !firing && CG_IsParticleSystemInfinite( cent->muzzlePS ) )
      CG_DestroyParticleSystem( &cent->muzzlePS );
  }

  // add the flash
  if( !weapon->wim[ weaponMode ].continuousFlash || !firing )
  {
    // impulse flash
    if( cg.time - cent->muzzleFlashTime > MUZZLE_FLASH_TIME )
      return;
  }

  memset( &flash, 0, sizeof( flash ) );
  VectorCopy( parent->lightingOrigin, flash.lightingOrigin );
  flash.shadowPlane = parent->shadowPlane;
  flash.renderfx = parent->renderfx;
  
  //ZT hook
  ZT_WallHack(&flash);
  

  flash.hModel = weapon->flashModel;
  if( flash.hModel )
  {
    angles[ YAW ] = 0;
    angles[ PITCH ] = 0;
    angles[ ROLL ] = crandom( ) * 10;
    AnglesToAxis( angles, flash.axis );

    if( noGunModel )
      CG_PositionRotatedEntityOnTag( &flash, parent, parent->hModel, "tag_weapon" );
    else
      CG_PositionRotatedEntityOnTag( &flash, &gun, weapon->weaponModel, "tag_flash" );

    trap_R_AddRefEntityToScene( &flash );
  }

  if( ps || cg.renderingThirdPerson ||
      cent->currentState.number != cg.predictedPlayerState.clientNum )
  {
    if( weapon->wim[ weaponMode ].muzzleParticleSystem && cent->muzzlePsTrigger )
    {
      cent->muzzlePS = CG_SpawnNewParticleSystem( weapon->wim[ weaponMode ].muzzleParticleSystem );

      if( CG_IsParticleSystemValid( &cent->muzzlePS ) )
      {
        if( noGunModel )
          CG_SetAttachmentTag( &cent->muzzlePS->attachment, *parent, parent->hModel, "tag_weapon" );
        else
          CG_SetAttachmentTag( &cent->muzzlePS->attachment, gun, weapon->weaponModel, "tag_flash" );

        CG_SetAttachmentCent( &cent->muzzlePS->attachment, cent );
        CG_AttachToTag( &cent->muzzlePS->attachment );
      }

      cent->muzzlePsTrigger = qfalse;
    }

    // make a dlight for the flash
    if( weapon->wim[ weaponMode ].flashDlightColor[ 0 ] ||
        weapon->wim[ weaponMode ].flashDlightColor[ 1 ] ||
        weapon->wim[ weaponMode ].flashDlightColor[ 2 ] )
    {
      trap_R_AddLightToScene( flash.origin, 300 + ( rand( ) & 31 ),
          weapon->wim[ weaponMode ].flashDlightColor[ 0 ],
          weapon->wim[ weaponMode ].flashDlightColor[ 1 ],
          weapon->wim[ weaponMode ].flashDlightColor[ 2 ] );
    }
  }
}
示例#16
0
/*
===================
CG_DrawItemSelect
===================
*/
void CG_DrawItemSelect( rectDef_t *rect, vec4_t color )
{
  int           i;
  int           x = rect->x;
  int           y = rect->y;
  int           width = rect->w;
  int           height = rect->h;
  int           iconsize;
  int           items[ 64 ];
  int           numItems = 0, selectedItem = 0;
  int           length;
  int           selectWindow;
  qboolean      vertical;
  centity_t     *cent;
  playerState_t *ps;

  cent = &cg_entities[ cg.snap->ps.clientNum ];
  ps = &cg.snap->ps;

  // don't display if dead
  if( cg.predictedPlayerState.stats[ STAT_HEALTH ] <= 0 )
    return;

  if( !( cg.snap->ps.pm_flags & PMF_FOLLOW ) )
  {
    // first make sure that whatever it selected is actually selectable
    if( cg.weaponSelect <= 32 && !CG_WeaponSelectable( cg.weaponSelect ) )
      CG_NextWeapon_f( );
    else if( cg.weaponSelect > 32 && !CG_UpgradeSelectable( cg.weaponSelect - 32 ) )
      CG_NextWeapon_f( );
  }

  // showing weapon select clears pickup item display, but not the blend blob
  cg.itemPickupTime = 0;

  if( height > width )
  {
    vertical = qtrue;
    iconsize = width;
    length = height / width;
  }
  else if( height <= width )
  {
    vertical = qfalse;
    iconsize = height;
    length = width / height;
  }

  selectWindow = length / 2;

  for( i = WP_NONE + 1; i < WP_NUM_WEAPONS; i++ )
  {
    if( !BG_InventoryContainsWeapon( i, cg.snap->ps.stats ) )
      continue;

    if( i == cg.weaponSelect )
      selectedItem = numItems;

    CG_RegisterWeapon( i );
    items[ numItems ] = i;
    numItems++;
  }

  for( i = UP_NONE + 1; i < UP_NUM_UPGRADES; i++ )
  {
    if( !BG_InventoryContainsUpgrade( i, cg.snap->ps.stats ) )
      continue;

    if( i == cg.weaponSelect - 32 )
      selectedItem = numItems;

    CG_RegisterUpgrade( i );
    items[ numItems ] = i + 32;
    numItems++;
  }

  for( i = 0; i < length; i++ )
  {
    int displacement = i - selectWindow;
    int item = displacement + selectedItem;

    if( ( item >= 0 ) && ( item < numItems ) )
    {
      trap_R_SetColor( color );

      if( items[ item ] <= 32 )
        CG_DrawPic( x, y, iconsize, iconsize, cg_weapons[ items[ item ] ].weaponIcon );
      else if( items[ item ] > 32 )
        CG_DrawPic( x, y, iconsize, iconsize, cg_upgrades[ items[ item ] - 32 ].upgradeIcon );

      trap_R_SetColor( NULL );
    }

    if( vertical )
      y += iconsize;
    else
      x += iconsize;
  }
}