Example #1
0
void FileWeaponInfo_t::Parse( KeyValues *pKeyValuesData, const char *szWeaponName )
{
	// Okay, we tried at least once to look this up...
	bParsedScript = true;

	// Classname
	Q_strncpy( szClassName, szWeaponName, MAX_WEAPON_STRING );
	// Printable name
	Q_strncpy( szPrintName, pKeyValuesData->GetString( "printname", WEAPON_PRINTNAME_MISSING ), MAX_WEAPON_STRING );
	// View model & world model
	Q_strncpy( szViewModel, pKeyValuesData->GetString( "viewmodel" ), MAX_WEAPON_STRING );
	Q_strncpy( szWorldModel, pKeyValuesData->GetString( "playermodel" ), MAX_WEAPON_STRING );
	Q_strncpy( szAnimationPrefix, pKeyValuesData->GetString( "anim_prefix" ), MAX_WEAPON_PREFIX );
	iSlot = pKeyValuesData->GetInt( "bucket", 0 );
	iPosition = pKeyValuesData->GetInt( "bucket_position", 0 );
	
	// Use the console (X360) buckets if hud_fastswitch is set to 2.
#ifdef CLIENT_DLL
	if ( hud_fastswitch.GetInt() == 2 )
#else
	if ( IsX360() )
#endif
	{
		iSlot = pKeyValuesData->GetInt( "bucket_360", iSlot );
		iPosition = pKeyValuesData->GetInt( "bucket_position_360", iPosition );
	}
	iMaxClip1 = pKeyValuesData->GetInt( "clip_size", WEAPON_NOCLIP );					// Max primary clips gun can hold (assume they don't use clips by default)
	iMaxClip2 = pKeyValuesData->GetInt( "clip2_size", WEAPON_NOCLIP );					// Max secondary clips gun can hold (assume they don't use clips by default)
	iDefaultClip1 = pKeyValuesData->GetInt( "default_clip", iMaxClip1 );		// amount of primary ammo placed in the primary clip when it's picked up
	iDefaultClip2 = pKeyValuesData->GetInt( "default_clip2", iMaxClip2 );		// amount of secondary ammo placed in the secondary clip when it's picked up
	iWeight = pKeyValuesData->GetInt( "weight", 0 );

	iRumbleEffect = pKeyValuesData->GetInt( "rumble", -1 );
	
	// LAME old way to specify item flags.
	// Weapon scripts should use the flag names.
	iFlags = pKeyValuesData->GetInt( "item_flags", ITEM_FLAG_LIMITINWORLD );

	for ( int i=0; i < ARRAYSIZE( g_ItemFlags ); i++ )
	{
		int iVal = pKeyValuesData->GetInt( g_ItemFlags[i].m_pFlagName, -1 );
		if ( iVal == 0 )
		{
			iFlags &= ~g_ItemFlags[i].m_iFlagValue;
		}
		else if ( iVal == 1 )
		{
			iFlags |= g_ItemFlags[i].m_iFlagValue;
		}
	}


	bShowUsageHint = pKeyValuesData->GetBool( "showusagehint", false );
	bAutoSwitchTo = pKeyValuesData->GetBool( "autoswitchto", true );
	bAutoSwitchFrom = pKeyValuesData->GetBool( "autoswitchfrom", true );
	m_bBuiltRightHanded = pKeyValuesData->GetBool( "BuiltRightHanded", true );
	m_bAllowFlipping = pKeyValuesData->GetBool( "AllowFlipping", true );
	m_bMeleeWeapon = pKeyValuesData->GetBool( "MeleeWeapon", false );

#if defined(_DEBUG) && defined(HL2_CLIENT_DLL)
	// make sure two weapons aren't in the same slot & position
	if ( iSlot >= MAX_WEAPON_SLOTS ||
		iPosition >= MAX_WEAPON_POSITIONS )
	{
		Warning( "Invalid weapon slot or position [slot %d/%d MAX], pos[%d/%d MAX]\n",
			iSlot, MAX_WEAPON_SLOTS - 1, iPosition, MAX_WEAPON_POSITIONS - 1 );
	}
	else
	{
		if (g_bUsedWeaponSlots[iSlot][iPosition])
		{
			Warning( "Duplicately assigned weapon slots in selection hud:  %s (%d, %d)\n", szPrintName, iSlot, iPosition );
		}
		g_bUsedWeaponSlots[iSlot][iPosition] = true;
	}
#endif

	// Primary ammo used
	const char *pAmmo = pKeyValuesData->GetString( "primary_ammo", "None" );
	if ( strcmp("None", pAmmo) == 0 )
		Q_strncpy( szAmmo1, "", sizeof( szAmmo1 ) );
	else
		Q_strncpy( szAmmo1, pAmmo, sizeof( szAmmo1 )  );
	iAmmoType = GetAmmoDef()->Index( szAmmo1 );
	
	// Secondary ammo used
	pAmmo = pKeyValuesData->GetString( "secondary_ammo", "None" );
	if ( strcmp("None", pAmmo) == 0)
		Q_strncpy( szAmmo2, "", sizeof( szAmmo2 ) );
	else
		Q_strncpy( szAmmo2, pAmmo, sizeof( szAmmo2 )  );
	iAmmo2Type = GetAmmoDef()->Index( szAmmo2 );

	// AI AddOn
	const char *pAIAddOn = pKeyValuesData->GetString( "ai_addon", "ai_addon_basecombatweapon" );
	if ( strcmp("None", pAIAddOn) == 0)
		Q_strncpy( szAIAddOn, "", sizeof( szAIAddOn ) );
	else
		Q_strncpy( szAIAddOn, pAIAddOn, sizeof( szAIAddOn )  );

	// Now read the weapon sounds
	memset( aShootSounds, 0, sizeof( aShootSounds ) );
	KeyValues *pSoundData = pKeyValuesData->FindKey( "SoundData" );
	if ( pSoundData )
	{
		for ( int i = EMPTY; i < NUM_SHOOT_SOUND_TYPES; i++ )
		{
			const char *soundname = pSoundData->GetString( pWeaponSoundCategories[i] );
			if ( soundname && soundname[0] )
			{
				Q_strncpy( aShootSounds[i], soundname, MAX_WEAPON_STRING );
			}
		}
	}
}
//-----------------------------------------------------------------------------
// Purpose: 
//-----------------------------------------------------------------------------
void CItem_AmmoCrate::SetupCrate( void )
{
	SetModelName( AllocPooledString( m_lpzModelNames[m_nAmmoType] ) );
	
	m_nAmmoIndex = GetAmmoDef()->Index( m_lpzAmmoNames[m_nAmmoType] );
}
//-----------------------------------------------------------------------------
// Purpose: 
//-----------------------------------------------------------------------------
void CNPC_GroundTurret::Spawn( void )
{
	Precache();

	UTIL_SetModel( this, "models/combine_turrets/ground_turret.mdl" );

	SetNavType( NAV_FLY );
	SetSolid( SOLID_VPHYSICS );

	SetBloodColor( DONT_BLEED );
	m_iHealth			= 125;
	m_flFieldOfView		= cos( ((GROUNDTURRET_VIEWCONE / 2.0f) * M_PI / 180.0f) );
	m_NPCState			= NPC_STATE_NONE;

	m_vecSpread.x = 0.5;
	m_vecSpread.y = 0.5;
	m_vecSpread.z = 0.5;

	CapabilitiesClear();

	AddEFlags( EFL_NO_DISSOLVE );

	NPCInit();

	CapabilitiesAdd( bits_CAP_SIMPLE_RADIUS_DAMAGE );

	m_iAmmoType = GetAmmoDef()->Index( "PISTOL" );

	m_pSmoke = NULL;

	m_bHasExploded = false;
	m_bEnabled = false;

	if( ai_newgroundturret.GetBool() )
	{
		m_flSensingDist = 384;
		SetDistLook( m_flSensingDist );
	}
	else
	{
		m_flSensingDist = 2048;
	}

	if( !GetParent() )
	{
		DevMsg("ERROR! npc_ground_turret with no parent!\n");
		UTIL_Remove(this);
		return;
	}

	m_flTimeNextShoot = gpGlobals->curtime;
	m_flTimeNextPing = gpGlobals->curtime;

	m_vecClosedPos = GetAbsOrigin();

	StudioFrameAdvance();

	Vector vecPos;

	GetAttachment( "eyes", vecPos );
	SetViewOffset( vecPos - GetAbsOrigin() );

	GetAttachment( "light", vecPos );
	m_vecLightOffset = vecPos - GetAbsOrigin();
}
//-----------------------------------------------------------------------------
// Chooses an item when the player is full
//-----------------------------------------------------------------------------
void CItem_DynamicResupply::SpawnFullItem( CItem_DynamicResupply *pMaster, CBasePlayer *pPlayer, int iDebug )
{
	// Can we not actually spawn the item?
	if ( !HasSpawnFlags(SF_DYNAMICRESUPPLY_ALWAYS_SPAWN) )
		return;

	float flRatio[NUM_AMMO_ITEMS];
	int i;
	float flTotalProb = 0.0f;
	for ( i = 0; i < NUM_AMMO_ITEMS; ++i )
	{
		int iAmmoType = GetAmmoDef()->Index( g_DynamicResupplyAmmoItems[i].sAmmoDef );
		bool bCanSpawn = pPlayer->Weapon_GetWpnForAmmo( iAmmoType ) != NULL;

		if ( bCanSpawn && ( g_DynamicResupplyAmmoItems[i].flFullProbability != 0 ) && ( pMaster->m_flDesiredAmmo[i] != 0.0f ) )
		{
			flTotalProb += g_DynamicResupplyAmmoItems[i].flFullProbability;
			flRatio[i] = flTotalProb;
		}
		else
		{
			flRatio[i] = -1.0f;
		}
	}

	if ( flTotalProb == 0.0f )
	{
		// If we're supposed to fallback to just a health vial, do that and finish.
		if ( pMaster->HasSpawnFlags(SF_DYNAMICRESUPPLY_FALLBACK_TO_VIAL) )
		{
			CBaseEntity::Create( "item_healthvial", GetAbsOrigin(), GetAbsAngles(), this );

			if ( iDebug )
			{
				Msg("Player is full, spawning item_healthvial due to spawnflag.\n", g_DynamicResupplyAmmoItems[i].sEntityName );
			}
			return;
		}

		// Otherwise, spawn the first ammo item in the list
		flRatio[0] = 1.0f;
		flTotalProb = 1.0f;
	}
	
	float flChoice = random->RandomFloat( 0.0f, flTotalProb ); 
	for ( i = 0; i < NUM_AMMO_ITEMS; ++i )
	{
		if ( flChoice <= flRatio[i] )
		{
			CBaseEntity::Create( g_DynamicResupplyAmmoItems[i].sEntityName, GetAbsOrigin(), GetAbsAngles(), this );

			if ( iDebug )
			{
				Msg("Player is full, spawning %s \n", g_DynamicResupplyAmmoItems[i].sEntityName );
			}
			return;
		}
	}

	if ( iDebug )
	{
		Msg("Player is full on all health + ammo, is not spawning.\n" );
	}
}
bool IsAmmoType( int iAmmoType, const char *pAmmoName )
{
	return GetAmmoDef()->Index( pAmmoName ) == iAmmoType;
}
Example #6
0
//-----------------------------------------------------------------------------
// Purpose: Return true if the specified player can carry any more of the ammo type
//-----------------------------------------------------------------------------
bool CGameRules::CanHaveAmmo( CBaseCombatCharacter *pPlayer, const char *szName )
{
	return CanHaveAmmo( pPlayer, GetAmmoDef()->Index(szName) );
}
void CBulletManager::SimulateBullet(CBullet& oBullet, float dt)
{
	Vector vecOriginal = oBullet.m_vecOrigin;

	Assert(oBullet.m_hShooter.Get());
	if (!oBullet.m_hShooter)
		return;

	bool bHasTraveledBefore = false;
	if (oBullet.m_flDistanceTraveled > 0)
		bHasTraveledBefore = true;

	// initialize these before the penetration loop, we'll need them to make our tracer after
	Vector vecTracerSrc = oBullet.m_vecOrigin;
	trace_t tr; // main enter bullet trace

	float flRange = dt;

	if (flRange < 0)
		flRange = 8000;

	bool bFullPenetrationDistance = false;

	Vector vecEnd = oBullet.m_vecOrigin + oBullet.m_vecDirection * flRange;

	int i;
	for (i = oBullet.m_iPenetrations; i < da_bullet_penetrations.GetInt(); i++)
	{
		CTraceFilterSimpleList tf(COLLISION_GROUP_NONE);
		tf.AddEntityToIgnore(oBullet.m_hShooter);

		for (int j = 0; j < oBullet.m_ahObjectsHit.Count(); j++)
			tf.AddEntityToIgnore(oBullet.m_ahObjectsHit[j]);

		UTIL_TraceLine( oBullet.m_vecOrigin, vecEnd, MASK_SOLID|CONTENTS_DEBRIS|CONTENTS_HITBOX, &tf, &tr );

		if (da_bullet_debug.GetBool())
		{
#ifdef CLIENT_DLL
			DebugDrawLine(oBullet.m_vecOrigin + Vector(0, 0, 1), tr.endpos + Vector(0, 0, 1), 0, 255, 255, true, dt<0?10:0.1);
#else
			DebugDrawLine(oBullet.m_vecOrigin + Vector(0, 0, 1), tr.endpos + Vector(0, 0, 1), 255, 255, 0, true, dt<0?10:0.1);
#endif
		}

		Vector vecTraceEnd = tr.endpos;

		bool bBSPModel = tr.DidHitWorld();

		if (tr.allsolid)
		{
			oBullet.m_flDistanceTraveled += (oBullet.m_vecOrigin - vecEnd).Length();
			oBullet.m_vecOrigin = vecEnd;
			break; // We're inside something. Do nothing.
		}

		if ( sv_showimpacts.GetBool() && tr.fraction < 1.0f )
		{
#ifdef CLIENT_DLL
			// draw red client impact markers
			debugoverlay->AddBoxOverlay( tr.endpos, Vector(-2,-2,-2), Vector(2,2,2), QAngle( 0, 0, 0), 255,0,0,127, sv_showimpacts.GetFloat() );

			if ( tr.m_pEnt && tr.m_pEnt->IsPlayer() )
			{
				C_BasePlayer *player = ToBasePlayer( tr.m_pEnt );
				player->DrawClientHitboxes( sv_showimpacts.GetFloat(), true );
			}
#else
			// draw blue server impact markers
			NDebugOverlay::Box( tr.endpos, Vector(-2,-2,-2), Vector(2,2,2), 0,0,255,127, sv_showimpacts.GetFloat() );

			if ( tr.m_pEnt && tr.m_pEnt->IsPlayer() )
			{
				CBasePlayer *player = ToBasePlayer( tr.m_pEnt );
				player->DrawServerHitboxes( sv_showimpacts.GetFloat(), true );
			}
#endif
		}

		Assert(oBullet.m_iBulletType > 0);
		int iDamageType = DMG_BULLET | DMG_NEVERGIB | GetAmmoDef()->DamageType(oBullet.m_iBulletType);

		if (i == 0)
			iDamageType |= DMG_DIRECT;

		if (tr.startsolid)
		{
			trace_t tr2;

			UTIL_TraceLine( tr.endpos - oBullet.m_vecDirection, oBullet.m_vecOrigin, CONTENTS_SOLID|CONTENTS_MOVEABLE, NULL, COLLISION_GROUP_NONE, &tr2 );

			// let's have a bullet exit effect if we penetrated a solid surface
			if (oBullet.m_bDoEffects && tr2.m_pEnt && tr2.m_pEnt->IsBSPModel())
				UTIL_ImpactTrace( &tr2, iDamageType );

			// ignore the entity we just hit for the next trace to avoid weird impact behaviors
			oBullet.m_ahObjectsHit.AddToTail(tr2.m_pEnt);
		}

		if ( tr.fraction == 1.0f )
		{
			oBullet.m_flDistanceTraveled += (oBullet.m_vecOrigin - vecEnd).Length();
			oBullet.m_vecOrigin = vecEnd;
			break; // we didn't hit anything, stop tracing shoot
		}

		weapontype_t eWeaponType = WT_NONE;

		CSDKWeaponInfo *pWeaponInfo = CSDKWeaponInfo::GetWeaponInfo(oBullet.m_eWeaponID);
		Assert(pWeaponInfo);
		if (pWeaponInfo)
			eWeaponType = pWeaponInfo->m_eWeaponType;

		float flDamageMultiplier = 1;
		float flMaxRange = 3000;

		// Power formula works like so:
		// pow( x, distance/y )
		// The damage will be at 1 when the distance is 0 units, and at
		// x% when the distance is y units, with a gradual decay approaching zero
		switch (eWeaponType)
		{
		case WT_RIFLE:
			flDamageMultiplier = 0.75f;
			flMaxRange = 3000;
			break;

		case WT_SHOTGUN:
			flDamageMultiplier = 0.40f;
			flMaxRange = 500;
			break;

		case WT_SMG:
			flDamageMultiplier = 0.50f;
			flMaxRange = 1000;
			break;

		case WT_PISTOL:
		default:
			flDamageMultiplier = 0.55f;
			flMaxRange = 1500;
			break;
		}

		flMaxRange *= oBullet.m_hShooter->m_Shared.ModifySkillValue(1, 0.5f, SKILL_MARKSMAN);

		//calculate the damage based on the distance the bullet travelled.
		oBullet.m_flDistanceTraveled += tr.fraction * flRange;

		float flCurrentDistance = oBullet.m_flDistanceTraveled;

		// First 500 units, no decrease in damage.
		if (eWeaponType == WT_SHOTGUN)
			flCurrentDistance -= 350;
		else
			flCurrentDistance -= 500;

		if (flCurrentDistance < 0)
			flCurrentDistance = 0;

		if (flCurrentDistance > flMaxRange)
			flCurrentDistance = flMaxRange;

		float flDistanceMultiplier = pow(flDamageMultiplier, (flCurrentDistance / flMaxRange));

		if( oBullet.m_bDoEffects )
		{
			// See if the bullet ended up underwater + started out of the water
			if ( enginetrace->GetPointContents( tr.endpos ) & (CONTENTS_WATER|CONTENTS_SLIME) )
			{
				CBaseEntity* pIgnore;
				if (oBullet.m_ahObjectsHit.Count())
					pIgnore = oBullet.m_ahObjectsHit.Tail();
				else
					pIgnore = oBullet.m_hShooter;

				trace_t waterTrace;
				UTIL_TraceLine( oBullet.m_vecOrigin, tr.endpos, (MASK_SHOT|CONTENTS_WATER|CONTENTS_SLIME), pIgnore, COLLISION_GROUP_NONE, &waterTrace );

				if( waterTrace.allsolid != 1 )
				{
					CEffectData	data;
					data.m_vOrigin = waterTrace.endpos;
					data.m_vNormal = waterTrace.plane.normal;
					data.m_flScale = random->RandomFloat( 8, 12 );

					if ( waterTrace.contents & CONTENTS_SLIME )
						data.m_fFlags |= FX_WATER_IN_SLIME;

					DispatchEffect( "gunshotsplash", data );
				}
			}
			else
			{
				//Do Regular hit effects

				// Don't decal nodraw surfaces
				if ( !( tr.surface.flags & (SURF_SKY|SURF_NODRAW|SURF_HINT|SURF_SKIP) ) )
				{
					CBaseEntity *pEntity = tr.m_pEnt;
					//Tony; only while using teams do we check for friendly fire.
					if ( DAGameRules()->IsTeamplay() && pEntity && pEntity->IsPlayer() && (pEntity->GetBaseAnimating() && !pEntity->GetBaseAnimating()->IsRagdoll()) )
					{
						if ( pEntity->GetTeamNumber() != oBullet.m_hShooter->GetTeamNumber() )
							UTIL_ImpactTrace( &tr, iDamageType );
					}
					//Tony; non player, just go nuts,
					else
						UTIL_ImpactTrace( &tr, iDamageType );
				}
			}
		} // bDoEffects

		// add damage to entity that we hit

#ifdef GAME_DLL
		float flBulletDamage = oBullet.m_iBulletDamage * flDistanceMultiplier / (i+1);	// Each iteration the bullet drops in strength
		if (oBullet.m_hShooter->IsStyleSkillActive(SKILL_MARKSMAN))
			flBulletDamage = oBullet.m_iBulletDamage * flDistanceMultiplier / (i/2+1);	// Each iteration the bullet drops in strength but not nearly as much.

		ClearMultiDamage();

		CTakeDamageInfo info( oBullet.m_hShooter, oBullet.m_hShooter, oBullet.m_hWeapon, flBulletDamage, iDamageType );
		CalculateBulletDamageForce( &info, oBullet.m_iBulletType, oBullet.m_vecDirection, tr.endpos );
		tr.m_pEnt->DispatchTraceAttack( info, oBullet.m_vecDirection, &tr );

		oBullet.m_hShooter->TraceAttackToTriggers( info, tr.startpos, tr.endpos, oBullet.m_vecDirection );

		ApplyMultiDamage();
#else
		flDistanceMultiplier = flDistanceMultiplier; // Silence warning.
#endif

		if (tr.m_pEnt && !FStrEq(tr.m_pEnt->GetClassname(), "worldspawn"))
			oBullet.m_ahObjectsHit.AddToTail(tr.m_pEnt);

		float flPenetrationDistance;
		switch (eWeaponType)
		{
		case WT_RIFLE:
			flPenetrationDistance = 25;
			break;

		case WT_SHOTGUN:
			flPenetrationDistance = 5;
			break;

		case WT_SMG:
			flPenetrationDistance = 15;
			break;

		case WT_PISTOL:
		default:
			flPenetrationDistance = 15;
			break;
		}

		flPenetrationDistance = oBullet.m_hShooter->m_Shared.ModifySkillValue(flPenetrationDistance, 1, SKILL_MARKSMAN);

		Vector vecBackwards = tr.endpos + oBullet.m_vecDirection * flPenetrationDistance;
		if (tr.m_pEnt->IsBSPModel())
			UTIL_TraceLine( vecBackwards, tr.endpos, CONTENTS_SOLID|CONTENTS_MOVEABLE, NULL, COLLISION_GROUP_NONE, &tr );
		else
			UTIL_TraceLine( vecBackwards, tr.endpos, CONTENTS_HITBOX, NULL, COLLISION_GROUP_NONE, &tr );

		if (tr.startsolid)
		{
			bFullPenetrationDistance = true;
			break;
		}

		// Set up the next trace. One unit in the direction of fire so that we firmly embed
		// ourselves in whatever solid was hit, to make sure we don't hit it again on next trace.
		if (dt < 0 && bBSPModel)
		{
			UTIL_TraceLine( vecTraceEnd + oBullet.m_vecDirection, vecTraceEnd + oBullet.m_vecDirection * flPenetrationDistance, CONTENTS_SOLID|CONTENTS_MOVEABLE, NULL, COLLISION_GROUP_NONE, &tr );

			if (tr.startsolid)
				oBullet.m_vecOrigin = tr.startpos + oBullet.m_vecDirection;
			else
				oBullet.m_vecOrigin = vecTraceEnd + oBullet.m_vecDirection;
		}
		else
			oBullet.m_vecOrigin = vecTraceEnd + oBullet.m_vecDirection;
	}

	oBullet.m_iPenetrations = i;

	// the bullet's done penetrating, let's spawn our particle system
	if (oBullet.m_bDoEffects && dt < 0)
		oBullet.m_hShooter->MakeTracer( oBullet.m_vecOrigin, tr, TRACER_TYPE_DEFAULT, !bHasTraveledBefore );

#ifdef CLIENT_DLL
	if (oBullet.m_hRenderHandle != INVALID_CLIENT_RENDER_HANDLE)
		ClientLeafSystem()->RenderableChanged( oBullet.m_hRenderHandle );
#endif

	if (bFullPenetrationDistance || oBullet.m_iPenetrations >= da_bullet_penetrations.GetInt())
		oBullet.Deactivate();

	if (dt < 0)
		oBullet.Deactivate();

	if (!bHasTraveledBefore && oBullet.m_flCurrAlpha == 0 && oBullet.m_flGoalAlpha == 0)
		oBullet.m_bActive = false;

	if (da_bullet_debug.GetBool())
	{
#ifdef CLIENT_DLL
		DebugDrawLine(vecOriginal, oBullet.m_vecOrigin, 0, 0, 255, true, dt<0?10:0.1);
#else
		DebugDrawLine(vecOriginal, oBullet.m_vecOrigin, 255, 0, 0, true, dt<0?10:0.1);
#endif
	}
}
//------------------------------------------------------------------------------
// Purpose: Fire a round from the cannon
// Notes:	Only call this if you have an enemy.
//------------------------------------------------------------------------------
void CNPC_CombineDropship::FireCannonRound( void )
{

	Vector vecPenetrate;
	trace_t tr;

	QAngle vecAimAngle;
	Vector vecToEnemy, vecEnemyTarget;
	Vector vecMuzzle;
	Vector vecAimDir;

	// HACKHACK until we actually get a muzzle attachment
//	GetAttachment( "muzzle", vecMuzzle, vecAimAngle );
	vecMuzzle = GetAbsOrigin();
	vecAimAngle = GetAbsAngles();

	Vector shipDir, shipLeft;
	AngleVectors( vecAimAngle, &shipDir );
	vecMuzzle.z += 72;
	vecMuzzle += shipDir * 96;

	vecEnemyTarget = GetEnemy()->BodyTarget( vecMuzzle, false );
	
	// Aim with the muzzle's attachment point.
	VectorSubtract( vecEnemyTarget, vecMuzzle, vecToEnemy );

	QAngle enemyAngles;
	VectorAngles(vecToEnemy, enemyAngles );
	float diff = fabs( UTIL_AngleDiff( enemyAngles.y, vecAimAngle.y ));	

	// only allow 90 degrees of freedom when firing
	if ( diff > 45 )
	{
		StopCannon();
		m_flTimeNextAttack = gpGlobals->curtime + 0.05;
		return;	
	}

	if ( !m_bIsFiring )				// start up sound
	{
		StartCannon();
	}

	VectorNormalize( vecToEnemy );

	// If the gun is wildly off target, stop firing!
	// FIXME  - this should use a vector pointing 
	// to the enemy's location PLUS the stitching 
	// error! (sjb) !!!BUGBUG
//	AngleVectors( vecAimAngle, &vecAimDir );	

/*	if( DotProduct( vecToEnemy, vecAimDir ) < 0.980 )
	{
		StopCannonBurst();
		m_flTimeNextAttack = gpGlobals->curtime + 0.1;
		return;
	}
*/
	//Add a muzzle flash
	g_pEffects->MuzzleFlash( vecMuzzle, vecAimAngle, random->RandomFloat( 5.0f, 7.0f ) , MUZZLEFLASH_TYPE_GUNSHIP );

	m_flTimeNextAttack = gpGlobals->curtime + 0.05;

	// Cheat. Fire directly at the target, plus noise.
	int ammoType = GetAmmoDef()->Index("CombineCannon"); 
	FireBullets( 1, vecMuzzle, vecToEnemy, VECTOR_CONE_2DEGREES, 8192, ammoType, 1, -1, -1, 1 /* override damage */ );
}
Example #9
0
void CNB_Weapon_Detail::UpdateLabels( CASW_WeaponInfo *pWeaponData )
{
	C_ASW_Player *pPlayer = C_ASW_Player::GetLocalASWPlayer();
	if ( !pPlayer )
		return;

	CASW_Marine_Profile *pProfile = Briefing()->GetMarineProfileByProfileIndex( m_nProfileIndex );

	switch( m_nDetailIndex )
	{
		case 0:
		{
			// for the chainsaw (which uses melee damage as a skill modifier), it applies a base value to the specified number in the script file
			// even if the skill is at 0 - because of this, we have to make a special case for the chainsaw and shift those values from the 
			// "bonus" side to the "base" side because the base bonus always exists - confused yet?
			float flBaseSkillDmgShift = 0;
			int nBonusDmg = 0;
			int nPellets = pWeaponData->m_iNumPellets;
			if ( pProfile )
			{
				if ( FStrEq("asw_weapon_prifle", pWeaponData->szClassName) )
					nBonusDmg = MarineSkills()->GetSkillBasedValue(pProfile, ASW_MARINE_SKILL_ACCURACY, ASW_MARINE_SUBSKILL_ACCURACY_PRIFLE_DMG);
				else if ( FStrEq("asw_weapon_shotgun", pWeaponData->szClassName) )
					nBonusDmg = MarineSkills()->GetSkillBasedValue(pProfile, ASW_MARINE_SKILL_ACCURACY, ASW_MARINE_SUBSKILL_ACCURACY_SHOTGUN_DMG);
				else if ( FStrEq("asw_weapon_railgun", pWeaponData->szClassName) )
					nBonusDmg = MarineSkills()->GetSkillBasedValue(pProfile, ASW_MARINE_SKILL_ACCURACY, ASW_MARINE_SUBSKILL_ACCURACY_RAILGUN_DMG);
				else if ( FStrEq("asw_weapon_flamer", pWeaponData->szClassName) || FStrEq("asw_weapon_sentry_flamer", pWeaponData->szClassName) )
					nBonusDmg = MarineSkills()->GetSkillBasedValue(pProfile, ASW_MARINE_SKILL_ACCURACY, ASW_MARINE_SUBSKILL_ACCURACY_FLAMER_DMG);
				else if ( FStrEq("asw_weapon_pistol", pWeaponData->szClassName) )
					nBonusDmg = MarineSkills()->GetSkillBasedValue(pProfile, ASW_MARINE_SKILL_ACCURACY, ASW_MARINE_SUBSKILL_ACCURACY_PISTOL_DMG);
				else if ( FStrEq("asw_weapon_pdw", pWeaponData->szClassName) )
					nBonusDmg = MarineSkills()->GetSkillBasedValue(pProfile, ASW_MARINE_SKILL_ACCURACY, ASW_MARINE_SUBSKILL_ACCURACY_PDW_DMG);
				else if ( FStrEq("asw_weapon_sniper_rifle", pWeaponData->szClassName) )
					nBonusDmg = MarineSkills()->GetSkillBasedValue(pProfile, ASW_MARINE_SKILL_ACCURACY, ASW_MARINE_SUBSKILL_ACCURACY_SNIPER_RIFLE_DMG);
				else if ( FStrEq("asw_weapon_tesla_gun", pWeaponData->szClassName) )
					nBonusDmg = 0.5f + MarineSkills()->GetSkillBasedValue(pProfile, ASW_MARINE_SKILL_ACCURACY, ASW_MARINE_SUBSKILL_ACCURACY_TESLA_CANNON_DMG);
				else if ( FStrEq("asw_weapon_chainsaw", pWeaponData->szClassName) )
				{
					flBaseSkillDmgShift = asw_skill_melee_dmg_base.GetFloat();
					nBonusDmg = MarineSkills()->GetSkillBasedValue(pProfile, ASW_MARINE_SKILL_MELEE, ASW_MARINE_SUBSKILL_MELEE_DMG);
				}
				else if ( FStrEq("asw_weapon_vindicator", pWeaponData->szClassName) )
				{
					nBonusDmg = MarineSkills()->GetSkillBasedValue(pProfile, ASW_MARINE_SKILL_VINDICATOR, ASW_MARINE_SUBSKILL_VINDICATOR_DAMAGE);
					nPellets = MarineSkills()->GetSkillBasedValue(pProfile, ASW_MARINE_SKILL_VINDICATOR, ASW_MARINE_SUBSKILL_VINDICATOR_PELLETS);
				}
				else if ( FStrEq("asw_weapon_autogun", pWeaponData->szClassName) || FStrEq("asw_weapon_minigun", pWeaponData->szClassName) )
					nBonusDmg = MarineSkills()->GetSkillBasedValue(pProfile, ASW_MARINE_SKILL_AUTOGUN, ASW_MARINE_SUBSKILL_AUTOGUN_DMG);
				else if ( FStrEq("asw_weapon_grenade_launcher", pWeaponData->szClassName) || FStrEq("asw_weapon_sentry_cannon", pWeaponData->szClassName) )
					nBonusDmg = MarineSkills()->GetSkillBasedValue(pProfile, ASW_MARINE_SKILL_GRENADES, ASW_MARINE_SUBSKILL_GRENADE_CLUSTER_DMG);
				else
					nBonusDmg = MarineSkills()->GetSkillBasedValue(pProfile, ASW_MARINE_SKILL_ACCURACY, ASW_MARINE_SUBSKILL_ACCURACY_RIFLE_DMG);

			}

			// fire power
			static wchar_t wszPowerLine[32];
			int iDamValue = (pWeaponData->m_flBaseDamage*pWeaponData->m_iNumPellets)+flBaseSkillDmgShift;
			int nTotalBonusDmg = (nBonusDmg*nPellets)-flBaseSkillDmgShift;
			Q_snwprintf( wszPowerLine, sizeof( wszPowerLine ), g_pVGuiLocalize->Find( "#asw_weapon_details_firepower" ) );
			wchar_t wzDamValue[10];
			if ( iDamValue <= 0 )
			{
				Q_snwprintf( wzDamValue, sizeof( wzDamValue ), g_pVGuiLocalize->Find( "#asw_weapon_altfire_NA" ) );
			}
			else if ( nTotalBonusDmg > 0 )
			{
				Q_snwprintf( wzDamValue, sizeof( wzDamValue ), L"%d (+%d)", iDamValue, nTotalBonusDmg );
			}
			else
			{
				Q_snwprintf( wzDamValue, sizeof( wzDamValue ), L"%d", iDamValue );
			}

			m_pTitleLabel->SetText( wszPowerLine );
			m_pTitleLabel->SetVisible( true );
			m_pValueLabel->SetText( wzDamValue );
			m_pValueLabel->SetVisible( true );
			
			float flDamage = iDamValue + nTotalBonusDmg;
			float flCurrent = 0.0f;
			if ( flDamage > 60 )
				flCurrent = 1.0f;
			else if ( iDamValue > 0 )
				flCurrent = MAX( (flDamage-5.0f) / 55.0f, 0.05f );

			if ( flDamage <= 0.0f )
			{
				m_pValueLabel->SetText( L"N/A" );
				m_pStatsBar->SetVisible( false );
			}
			else
			{
				m_pStatsBar->Init( flCurrent, flCurrent, 0.1f, false, false );
				m_pStatsBar->SetVisible( true );
			}

			break;
		}

		case 1:
		{
			// fire rate
			static wchar_t wszRateLine[32];
			Q_snwprintf( wszRateLine, sizeof( wszRateLine ), g_pVGuiLocalize->Find( "#asw_weapon_details_firerate" ) );
			m_pTitleLabel->SetText( wszRateLine );
			m_pTitleLabel->SetVisible( true );

			float flRate = pWeaponData->m_flFireRate;
			wchar_t wzFireValue[32];

			float flCurrent = 0.0f;
			if ( flRate <= 0 )
			{
				Q_snwprintf( wzFireValue, sizeof( wzFireValue ), g_pVGuiLocalize->Find( "#asw_weapon_altfire_NA" ) );
			}
			else
			{
				Q_snwprintf( wzFireValue, sizeof( wzFireValue ), L"%.1f / %s", (1.0f/flRate), g_pVGuiLocalize->Find( "#asw_weapon_details_seconds" ) );
				if ( flRate <= 0.125f )
					flCurrent = 1.0f - MIN( ((pWeaponData->m_flFireRate-0.03f)/0.125f)*0.5f, 0.48f );
				else
					flCurrent = 1.0f - MIN( ((pWeaponData->m_flFireRate-0.5f)/0.65f)+0.5f, 0.98f );
			}

			m_pValueLabel->SetText( wzFireValue );
			m_pValueLabel->SetVisible( true );
			m_pStatsBar->Init( flCurrent, flCurrent, 0.1f, false, false );
			m_pStatsBar->SetVisible( true );

			break;
		}

		case 2:
		{
			// the skill modifies the base reload time by this amount so all of the numbers in the script files are incorrect for displaying base amount
			float flBaseSkillModifier = asw_skill_reloading_base.GetFloat();
			// reload time
			static wchar_t wszReloadLine[32];
			Q_snwprintf( wszReloadLine, sizeof( wszReloadLine ), g_pVGuiLocalize->Find( "#asw_weapon_details_reload" ) );
			float flBaseReload = pWeaponData->flReloadTime;
			if ( pWeaponData->m_flDisplayReloadTime >= 0 )
				flBaseReload = pWeaponData->m_flDisplayReloadTime;

			float flCurrent = flBaseReload;
			float flRealReload = flBaseReload;
			wchar_t wzReloadValue[32];
			if ( flBaseReload <= 0 )
			{
				Q_snwprintf( wzReloadValue, sizeof( wzReloadValue ), g_pVGuiLocalize->Find( "#asw_weapon_altfire_NA" ) );
			}
			else
			{
				float fSpeedScale = 1;
				float flReloadDiff = 0;
				if ( pProfile )
				{
					fSpeedScale = MarineSkills()->GetSkillBasedValue(pProfile, ASW_MARINE_SKILL_RELOADING, ASW_MARINE_SUBSKILL_RELOADING_SPEED_SCALE);
					if ( fSpeedScale != 1 )
					{
						flRealReload = flBaseReload * fSpeedScale;
					
						// to get an accurate difference, we need to multiply the script defined base reload amount by the base modifier that the Skill does
						flReloadDiff = flRealReload - (flBaseReload * flBaseSkillModifier);
					}
				}

				if ( flReloadDiff != 0 )
					Q_snwprintf( wzReloadValue, sizeof( wzReloadValue ), L"%.1f %s (%s%.1f)", (flBaseReload*flBaseSkillModifier), g_pVGuiLocalize->Find( "#asw_weapon_details_seconds" ), (flReloadDiff>0)?L"+":L"", flReloadDiff );
				else
					Q_snwprintf( wzReloadValue, sizeof( wzReloadValue ), L"%.1f %s", (flBaseReload*flBaseSkillModifier), g_pVGuiLocalize->Find( "#asw_weapon_details_seconds" ) );
				flCurrent = 1.0f - MIN( (flRealReload-0.75f)/2.5f, 0.99f );
			}

			m_pTitleLabel->SetText( wszReloadLine );
			m_pTitleLabel->SetVisible( true );
			m_pValueLabel->SetText( wzReloadValue );
			m_pValueLabel->SetVisible( true );
			m_pStatsBar->Init( flCurrent, flCurrent, 0.1f, false, false );
			m_pStatsBar->SetVisible( true );
			break;
		}

		case 3:
		{
			// clip capacity
			static wchar_t wszClipLine[32];
			Q_snwprintf( wszClipLine, sizeof( wszClipLine ), g_pVGuiLocalize->Find( "#asw_weapon_details_clipsize" ) );
			int iClipValue = pWeaponData->iMaxClip1;
			int nMaxBulletsPerGun = GetAmmoDef()->MaxCarry( pWeaponData->iAmmoType, NULL );
			int iNumClips = ( nMaxBulletsPerGun / iClipValue ) + 1;
			if ( pWeaponData->m_bShowClipsDoubled )
			{
				iNumClips *= 2;
			}

			if ( pWeaponData->m_iDisplayClipSize >= 0 )
				iClipValue = pWeaponData->m_iDisplayClipSize;

			wchar_t wzClipValue[10];
			if ( iClipValue == 111 ) // magic number for infinite ammo
			{
				// this displays an "infinity" symbol in the neosans font
				wzClipValue[0] = 0x221E;
				wzClipValue[1] = L'\0';
			}
			else if ( pWeaponData->m_bShowClipsInWeaponDetail )
			{
				Q_snwprintf( wzClipValue, sizeof( wzClipValue ), L"%d x %d", iClipValue, iNumClips );
			}
			else
			{
				Q_snwprintf( wzClipValue, sizeof( wzClipValue ), L"%d", iClipValue );
			}
			float flCurrent = MIN( (float)iClipValue/200.0f, 1.0f );

			m_pTitleLabel->SetText( wszClipLine );
			m_pTitleLabel->SetVisible( true );
			m_pValueLabel->SetText( wzClipValue );
			m_pValueLabel->SetVisible( true );
			m_pStatsBar->Init( flCurrent, flCurrent, 0.1f, false, false );
			m_pStatsBar->SetVisible( true );
			break;
		}

		case 4:
		{
			// alt fire
			static wchar_t wszAltLine[32];
			Q_snwprintf( wszAltLine, sizeof( wszAltLine ), g_pVGuiLocalize->Find( "#asw_weapon_details_altfire" ) );
			wchar_t wzAltValue[64];
			bool bHighlightText = false;
			if ( !Q_stricmp( pWeaponData->szAltFireText, "" ) )
				Q_snwprintf( wzAltValue, sizeof( wzAltValue ), g_pVGuiLocalize->Find( "#asw_weapon_altfire_none" ) );
			else
			{
				int iAltFire = pWeaponData->iDefaultClip2;
				if ( iAltFire > 0 )
					Q_snwprintf( wzAltValue, sizeof( wzAltValue ), L"%d %s", iAltFire, g_pVGuiLocalize->Find( pWeaponData->szAltFireText ) );
				else
					Q_snwprintf( wzAltValue, sizeof( wzAltValue ), g_pVGuiLocalize->Find( pWeaponData->szAltFireText ) );
				bHighlightText = true;
			}

			m_pTitleLabel->SetText( wszAltLine );
			m_pTitleLabel->SetVisible( true );
			m_pValueLabel->SetText( wzAltValue );
			m_pValueLabel->SetVisible( true );
			m_pStatsBar->SetVisible( false );
			break;
		}
		
		case 5:
		{
			// attributes
			static wchar_t wszAttributesLine[32];
			Q_snwprintf( wszAttributesLine, sizeof( wszAttributesLine ), g_pVGuiLocalize->Find( "#asw_weapon_details_notes" ) );
			//wchar_t wszAttributesTempNull[4];
			//wchar_t wszAttributesTempText[64];
			wchar_t wszAttributesValue[64];
			bool bHighlightText = false;
			//Q_snwprintf( wszAttributesTempText, sizeof( wszAttributesTempText ), g_pVGuiLocalize->Find( pWeaponData->szAttributesText ) );
			//Q_snwprintf( wszAttributesTempNull, sizeof( wszAttributesTempNull ), "" );
			if ( !Q_wcscmp( g_pVGuiLocalize->Find( pWeaponData->szAttributesText ), g_pVGuiLocalize->Find( "#asw_weapon_null_line" ) ) )
				//asw_weapon_null_line
			{
			//	Q_snwprintf( wszAttributesValue, sizeof( wszAttributesValue ), g_pVGuiLocalize->Find( "#asw_weapon_altfire_none" ) );
				m_pTitleLabel->SetVisible( false );
				m_pValueLabel->SetVisible( false );
			}
			else
			{
				Q_snwprintf( wszAttributesValue, sizeof( wszAttributesValue ), g_pVGuiLocalize->Find( pWeaponData->szAttributesText ) );
				bHighlightText = true;
				m_pTitleLabel->SetText( wszAttributesLine );
				m_pTitleLabel->SetVisible( true );
				m_pValueLabel->SetText( wszAttributesValue );
				m_pValueLabel->SetVisible( true );
			}

			m_pStatsBar->SetVisible( false );

			break;
		}

		case 6:
		{
			int nRequiredLevel = pPlayer->GetWeaponLevelRequirement( pWeaponData->szClassName );
			if ( nRequiredLevel == -1 )
			{
				m_pTitleLabel->SetVisible( false );
				m_pValueLabel->SetVisible( false );
				m_pStatsBar->SetVisible( false );
				return;
			}

			// required level
			static wchar_t wszAltLine[32];
			Q_snwprintf( wszAltLine, sizeof( wszAltLine ), g_pVGuiLocalize->Find( "#asw_weapon_details_required_level" ) );

			nRequiredLevel++;	// for display it's actually 1 higher (levels start from 0 in code)
			wchar_t wzAltValue[64];
			Q_snwprintf( wzAltValue, sizeof( wzAltValue ), L"%d", nRequiredLevel );

			m_pTitleLabel->SetText( wszAltLine );
			m_pTitleLabel->SetVisible( true );
			m_pValueLabel->SetText( wzAltValue );
			m_pValueLabel->SetVisible( true );
			m_pStatsBar->SetVisible( false );

			break;
		}
	}	
}
Example #10
0
void CASW_Ammo_Drop::ActivateUseIcon( CASW_Marine* pMarine, int nHoldType )
{
    if ( nHoldType == ASW_USE_HOLD_START )
        return;

    CASW_Weapon *pWeapon = GetAmmoUseUnits( pMarine );

    if( pWeapon )
    {
        int iAmmoType = pWeapon->GetPrimaryAmmoType();
        int iGuns = pMarine->GetNumberOfWeaponsUsingAmmo( iAmmoType );
        int iMaxAmmoCount = GetAmmoDef()->MaxCarry( iAmmoType, pMarine ) * iGuns;
        int iBullets = pMarine->GetAmmoCount( iAmmoType );
        int iAmmoCost = GetAmmoUnitCost( iAmmoType );
        int iClipsToGive = CASW_Ammo_Drop_Shared::GetAmmoClipsToGive( iAmmoType );

        pMarine->SetAmmoCount( MIN( iBullets + pWeapon->GetMaxClip1() * iClipsToGive, iMaxAmmoCount ), iAmmoType );
        m_iAmmoUnitsRemaining -= iAmmoCost;

        pMarine->GetMarineSpeech()->Chatter(CHATTER_USE);

        IGameEvent * event = gameeventmanager->CreateEvent( "ammo_pickup" );
        if ( event )
        {
            CASW_Player *pPlayer = pMarine->GetCommander();
            event->SetInt( "userid", ( pPlayer ? pPlayer->GetUserID() : 0 ) );
            event->SetInt( "entindex", pMarine->entindex() );

            gameeventmanager->FireEvent( event );
        }

        if ( m_iAmmoUnitsRemaining <= 0 )
        {
            CTakeDamageInfo info;

            BaseClass::Event_Killed( info );
        }

        CASW_Marine *pDeployer = m_hDeployer.Get();

        if ( pDeployer && pMarine != pDeployer && !m_bSuppliedAmmo )
        {
            m_bSuppliedAmmo = true;
            if ( pDeployer->GetCommander() )
            {
                pDeployer->GetCommander()->AwardAchievement( ACHIEVEMENT_ASW_AMMO_RESUPPLY );
            }
        }
    }
    else
    {
        if ( pMarine->IsInhabited() )
        {
            CASW_Player *pCommander = pMarine->GetCommander();
            if ( pCommander )
            {
                CSingleUserRecipientFilter filter( pCommander );
                EmitSound( filter, pMarine->entindex(), "ASW_Ammobag.Fail", NULL, 0.0f );
            }
        }
    }
}
//-----------------------------------------------------------------------------
// Purpose: Spawn the entity
//-----------------------------------------------------------------------------
void CNPC_CombineCamera::Spawn()
{
	Precache();

	SetModel(COMBINE_CAMERA_MODEL);

	m_pEyeFlash = CSprite::SpriteCreate(COMBINE_CAMERA_FLASH_SPRITE, GetLocalOrigin(), FALSE);
	m_pEyeFlash->SetTransparency(kRenderGlow, 255, 255, 255, 0, kRenderFxNoDissipation);
	m_pEyeFlash->SetAttachment(this, 2);
	m_pEyeFlash->SetBrightness(0);
	m_pEyeFlash->SetScale(1.0);

	BaseClass::Spawn();

	m_HackedGunPos	= Vector(0, 0, 12.75);
	SetViewOffset(EyeOffset(ACT_IDLE));
	m_flFieldOfView	= CAMERA_FOV_WIDE;
	m_takedamage	= DAMAGE_YES;
	m_iHealth		= 50;
	m_bloodColor	= BLOOD_COLOR_MECH;
	
	SetSolid(SOLID_BBOX);
	AddSolidFlags(FSOLID_NOT_STANDABLE);

	SetHeight(COMBINE_CAMERA_RETRACT_HEIGHT);

	AddFlag(FL_AIMTARGET);

	SetPoseParameter(COMBINE_CAMERA_BC_YAW, 0);
	SetPoseParameter(COMBINE_CAMERA_BC_PITCH, 0);

	m_iAmmoType = GetAmmoDef()->Index("Pistol");

	// Create our eye sprite
	m_pEyeGlow = CSprite::SpriteCreate(COMBINE_CAMERA_GLOW_SPRITE, GetLocalOrigin(), false);
	m_pEyeGlow->SetTransparency(kRenderWorldGlow, 255, 0, 0, 128, kRenderFxNoDissipation);
	m_pEyeGlow->SetAttachment(this, 2);

	// Set our enabled state
	m_bEnabled = ((m_spawnflags & SF_COMBINE_CAMERA_STARTINACTIVE) == false);

	// Make sure the radii are sane.
	if (m_nOuterRadius <= 0)
	{
		m_nOuterRadius = 300;
	}

	if (m_nInnerRadius <= 0)
	{
		m_nInnerRadius = 450;
	}

	if (m_nOuterRadius < m_nInnerRadius)
	{
		swap(m_nOuterRadius, m_nInnerRadius);
	}

	// Do we start active?
	if (m_bEnabled)
	{
		Deploy();
	}
	else
	{
		SetEyeState(CAMERA_EYE_DISABLED);
	}

	//Adrian: No shadows on these guys.
	AddEffects( EF_NOSHADOW );

	// Stagger our starting times
	SetNextThink( gpGlobals->curtime + random->RandomFloat(0.1f, 0.3f) );

	// Don't allow us to skip animation setup because our attachments are critical to us!
	SetBoneCacheFlags( BCF_NO_ANIMATION_SKIP );
}
//-----------------------------------------------------------------------------
// Purpose: Returns the amount of ammunition of the specified type the character's carrying
//-----------------------------------------------------------------------------
int	CBaseCombatCharacter::GetAmmoCount( char *szName ) const
{
	return GetAmmoCount( GetAmmoDef()->Index(szName) );
}
void CBaseCombatCharacter::RemoveAmmo( int iCount, const char *szName )
{
	RemoveAmmo( iCount, GetAmmoDef()->Index(szName) );
}