Weapon Accuracy and Vector Projectiles

From Valve Developer Community
Jump to navigation Jump to search

Weapon Spread Customization

In this tutorial we will discuss some basics of how to effect the spread of projectiles from weapons such as the AR2, SMG1, Pistol, and Shotgun. This will include the effects of recoil parameters on simulating weapon spread as well as shot penalty timers and their effect on base combat weapons throughout your mod. This tutorial is a general overview as many different classes of weapons utilize camera and projectile vector generation differently. To start the tutorial, we need to discuss how the game determines shot angles.

Vector Cones & FOV

The bulk of the combat weapons in HL2 render the "spread" of projectiles based on a fixed "cone" or preset angle defined within a handful of places. These cones are based on the origin or center anchor point of the player's field of view or camera angle in first person. Below is an example from "weapon_smg1.cpp" which is typical for CHLMachineGun and CHLSelectFireMachineGun type weapons.

 virtual const Vector& GetBulletSpread( void )
 {
	 static const Vector cone = VECTOR_CONE_5DEGREES;
 	 return cone;
 }

One way most beginner mods will get the desired spread pattern or cone is to simply change the vector cone value to the closest desired degree value (Ex. "5DEGREES" is replaced with "1DEGREES" etc.) However this can have it's own issues, especially if we want to have several similar classes of weapons in the mod. To optimize certain weapons, we have to define vector cones specifically.

Note.pngNote:For weapons such as the AR2, some data will be contained in header files.

Basecombatweapon_shared.h'

We can find the declaration for "VECTOR_CONE_5DEGREES" as an example in 'basecombatweapon_shared.h':

// NOTE: The way these are calculated is that each component == sin (degrees/2)
#define VECTOR_CONE_PRECALCULATED	vec3_origin
#define VECTOR_CONE_1DEGREES		Vector( 0.00873, 0.00873, 0.00873 )
#define VECTOR_CONE_LRIFLE          Vector( 0.00980, 0.00980, 0.00980 )
#define VECTOR_CONE_SRIFLE    		Vector( 0.01261, 0.01261, 0.01261 )
#define VECTOR_CONE_LPISTOL    		Vector( 0.01474, 0.01474, 0.01474 )
#define VECTOR_CONE_SPISTOL    		Vector( 0.01648, 0.01658, 0.01658 )
#define VECTOR_CONE_2DEGREES		Vector( 0.01745, 0.01745, 0.01745 )
#define VECTOR_CONE_SUBMACHG		Vector( 0.02530, 0.02530, 0.02530 )
#define VECTOR_CONE_3DEGREES		Vector( 0.02618, 0.02618, 0.02618 )
#define VECTOR_CONE_PDW		        Vector( 0.03228, 0.03228, 0.03228 )
#define VECTOR_CONE_4DEGREES		Vector( 0.03490, 0.03490, 0.03490 )
#define VECTOR_CONE_5DEGREES		Vector( 0.04362, 0.04362, 0.04362 )
#define VECTOR_CONE_6DEGREES		Vector( 0.05234, 0.05234, 0.05234 )
#define VECTOR_CONE_7DEGREES		Vector( 0.06105, 0.06105, 0.06105 )
#define VECTOR_CONE_8DEGREES		Vector( 0.06976, 0.06976, 0.06976 )
#define VECTOR_CONE_9DEGREES		Vector( 0.07846, 0.07846, 0.07846 )
#define VECTOR_CONE_10DEGREES		Vector( 0.08716, 0.08716, 0.08716 )
#define VECTOR_CONE_11DEGREES		Vector( 0.09589, 0.09589, 0.09589 )
#define VECTOR_CONE_15DEGREES		Vector( 0.13053, 0.13053, 0.13053 )
#define VECTOR_CONE_20DEGREES		Vector( 0.17365, 0.17365, 0.17365 )

In this example, the data table has been customized to allow for multiple rifles and submachine guns to be used, each with a slightly different base spread pattern.

Movement and Recoil Penalty

Vanilla Half-Life 2 features some advanced recoil effects in first person view which effect the rumble and pitch of the player camera angle. For this example we will discuss how this is accomplished and how to manipulate these effects in-game to produce unique weapon characteristics for a mod using weapon_smg1.cpp. Below is the local recoil definitions specific to just the SMG1

void CWeaponSMG1::AddViewKick( void )
{
	#define	EASY_DAMPEN			1.5f
	#define	MAX_VERTICAL_KICK	17.5f	//Degrees
	#define	SLIDE_LIMIT			0.11f	//Seconds
	
	//Get the view kick
	CBasePlayer *pPlayer = ToBasePlayer( GetOwner() );

	if ( pPlayer == NULL )
		return;

	DoMachineGunKick( pPlayer, EASY_DAMPEN, MAX_VERTICAL_KICK, m_fFireDuration, SLIDE_LIMIT );
}

However the 'DoMachineGunKick' function is what controls the "rumble" effect specically. In this case 'SLIDE_LIMIT' refers to a time variable, expressed in seconds. To understand how the first person rumble effect is carried out, we need to look at 'basehlcombatweapon.cpp'