Detailed Guide to Modifying Weapons

Modifying Weapons

What's Covered:

  • Modifying weapon accuracy/bullet spread for players and vital allies[/*:1n5aq4fj]
  • Modifying weapon damage, underwater weapons, max ammo etc. for both primary and secondary fire and for both players and NPC's[/*:1n5aq4fj]
  • Editing weapon ranges for NPC's (So you can have a combine sniping with his pistol)[/*:1n5aq4fj]
  • Anything else I think of on the fly[/*:1n5aq4fj]

I'm mostly posting this because there have been a few questions regarding weapons, and also because I found this sort of thing really hard to find anywhere. I'm just compiling all my knowledge that I've acquired from various places into this one topic. So yeah, have fun. ;d Some changes require code edits, some require mere CFG edits. I'll try to provide screenies, but most of it is self-explanatory and can't really go wrong. I'll throw some in to liven it up though.

This guide assumes the following:

  • You're running Episode Two Single Player code[/*:1n5aq4fj]
  • Editing code using Visual C++ 2005 Express edition[/*:1n5aq4fj]
  • Have 'basic' knowledge of C++ or a relative language.[/*:1n5aq4fj]
  • A positive IQ[/*:1n5aq4fj]

I expect it's easy enough to adapt, but that's your ordeal.

Use the find feature to locate the following values, which will quickly take you to the right place.

#0 - Top

#1 - Weapon Accuracy
#1a - Modifying shotgun accuracy
#1b - If only it was that easy (Variations of the shotgun method)
#1c - NPC accuracy

#2 - Variable Tweaks
#2a - weapon_***.txt
#2b - skill.cfg
#2c - Underwater Weapons

#3 - NPC Weapon Ranges
#3a - Hostile NPC Ranges
#3b - Allied NPC ranges

#4 - Conclusion

Weapon Accuracy #1
This covers how to change and add weapon bullet spread/accuracy vector cones for both the player and vital allies. This is a coded feature.

Editing weapon accuracy cones is actually pretty easy. In this example, we'll be editing the shotgun to perform more like a sniper rifle. This is based on a question asked by jgoodroad.

Modifying shotgun accuracy #1a

-Open your project and then open the Server Episodic soluton, expand the "Source files" folder followed by "HL2 DLL."

news post image

-Open weapon_shotgun.cpp and go to line 46, which should read something like the below code.

virtual const Vector& GetBulletSpread( void )

See the image further down for help finding it.

-This is where the bullet spread vector is set, i.e. how accurate the gun is. If you understand the code even a little, you'll see that what Valve have done is given vital allies (E.g. Alyx) a lot more accuracy and the player less. This is visible by the:

static Vector vitalAllyCone = VECTOR_CONE_3DEGREES;

which sets the vital allies' accuracy vector to 3 degrees. This gives the allies a lot more accuracy, but Valve have also given them a slight decrease in damage to counter this. Remember this, because if you're wanting to change the vital ally accuracy you'll be returning to this vector.

-Look below and you'll see the player vector. This is where the accuracy of the gun for the player is 'set'.

news post image

-The accuracy is defined in vector cones. I'm no mathematician, so I'll give a brief explanation of a vector cone using Google images:

http://mathdl.maa.org/images/upload_lib ... nimate.gif
That's your vector cone, and imagine at the start of that cone is where you fire the gun. What you're going to do is change the static vector defined in the code which is, for example, VECTOR_CONE_3DEGREES; This 'widens' or 'shrinks' the cone, with the lower number doing the shrinking.

-In "basecombatweapon_shared.h" lies the list of predefined vector cones. The start at about line #93 in the file, with a few Valve comments. To open it, go to the top of weapon_shotgun.cpp, find the line #include "basehlcombatweapon_shared.h" and right click the file -> Open Document. Alternatively, scroll up in the explorer.

I'll list the contents here:

// -----------------------------------------
//	Vector cones
// -----------------------------------------
// VECTOR_CONE_PRECALCULATED - this resolves to vec3_origin, but adds some
// context indicating that the person writing the code is not allowing
// FireBullets() to modify the direction of the shot because the shot direction
// being passed into the function has already been modified by another piece of
// code and should be fired as specified. See GetActualShotTrajectory(). 

// NOTE: The way these are calculated is that each component == sin (degrees/2)
#define VECTOR_CONE_1DEGREES		Vector( 0.00873, 0.00873, 0.00873 )
#define VECTOR_CONE_2DEGREES		Vector( 0.01745, 0.01745, 0.01745 )
#define VECTOR_CONE_3DEGREES		Vector( 0.02618, 0.02618, 0.02618 )
#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_15DEGREES		Vector( 0.13053, 0.13053, 0.13053 )
#define VECTOR_CONE_20DEGREES		Vector( 0.17365, 0.17365, 0.17365 )

-Valve added a helpful note (For those of us who suck at maths... *ahem*) as to how to calculate your own vectors using sin. So if you wanted a 25 degree vector cone, it's just sin(25/2). All three components take the same value, since you're creating an equal cone. (You don't want one side randomly spurring off...) Simply change the static vectors we found earlier to whatever accuracy you would like to be or add your own. 10 is the default for the shotgun. 3 is pretty precise, and 2 is good for a rifle whilst 1 would suit a sniper.

-Compile and test.

Congratulations, you now have a sniper shotty for either you or your vital allies.

If only it was that easy #1b

The above principle applies to most other weapons. If you want to, for example, change the SMG vector cone then open up weapon_smg1.cpp and use CTRL + F (The find feature) to find virtual const Vector& GetBulletSpread and it should take you there.

Some guns however, work sligtly differently, such as the 357 and the crossbow. (The crossbow actually fires a projecticle and so is completely different.) The 357 does it's accuracy at line #138 of weapon_357.cpp.

pPlayer->FireBullets( 1, vecSrc, vecAiming, vec3_origin, MAX_TRACE_LENGTH, m_iPrimaryAmmoType, 0 );

Note the 4th paramter, vec3_origin. This basically means "Find the exact trajectory, and plant the bullet there." There's no misses. I assume you could substitute it for any vector definition as defined above, but I haven't tried it. After all, it's a revolver damnit.

NPCs #1c

Open up weapon_smg1.cpp. Head to line #51~ and you'll see the good ol' virtual const Vector& GetBulletSpread( void ) business. Notice that there is a vector cone listed there (VECTOR_CONE_5DEGREES) but not one for vital allies. holyshitwtfbbq happened here. Well, Alyx doesn't wield an SMG. (She has standards you know, she only uses a shotty and a custom pistol.)

NPC accuracy is done somewhere else in the file, at line #177. (It looks like CWeaponSMG1::FireNPCPrimaryAttack...) As the name suggests, this is the bit that's called when an NPC fires his SMG. Various bits of crap fly here, notably sounds, but the bit we're interested in is specifically line #183 which reads:

pOperator->FireBullets( 1, vecShootOrigin, vecShootDir, VECTOR_CONE_PRECALCULATED, MAX_TRACE_LENGTH, m_iPrimaryAmmoType, 2, entindex(), 0 );

news post image

This may look familiar: it's similar to the .357 method. VECTOR_CONE_PRECALCULATED means, (Deriving this from the Valve comment earlier) that bullet spread has already been decided before hand, probably due to a player difficulty setting. Basically, it's saying "Don't you touch mah accuracy boi... I've already done it." Unfortunately, this is beyond the realms of me as to how we edit the NPC accuracy in these situations... If anyone knows, please let me know and I'll add it in with credits. You could put your own vector in, but it could lead to quite a linear effect.

Holy shit that's point one done after about three pages... On to point two.

Variable Tweaks #2
This covers how to change weapon damage, whether you can fire a gun underwater, maximum ammo you can carry and a few other settings. This is mostly a .CFG edit.

weapon_***.txt #2a

-Navigate to your mod folder (the one containing gameinfo.txt) and then go into the scripts folder. In here should be lots of files, and if you scroll down (Assuming you've organised it by name) towards the bottom will be a bunch of weawpon_***.txt files. Let's take a look at weapon_pistol.txt boys and girls.

Take this URL as a reference point for the file: http://developer.valvesoftware.com/wiki/Weapon_scriptI'll do my best to explain it further though.

news post image

-Let's change the clip size, 18 is a bit much for me. clip_size determines how many bullets you can have in a clip at any one time. Once you use up the clip, it's reload time. I'm going to change clip_size to 16, and then I'm going to increase the damage slightly to compensate. (In the later part of this point.) Go ahead and set it to 16.

news post image

-Say we want to change the gun a bit more. Perhaps for our mod we want the pistol to be a main weapon, and so want it to be more important so that if a player has another weaker weapon, when they pick up the pistol it'll switch to it. The "weight" value decides this. A higher weight means a stronger weapon candidate to auto-switch to when you first find it. (Not the physical model weight)

I really won't go into much more detail here, since these files are pretty self-explanatory when coupled with the VDC link provided.

skill.cfg #2b

-Navigate to your mod folder and this time go to the cfg folder. Amongst a few other files you may find the file skill.cfg. If you don't, open up source engine.gcf located in your steamapps folder using GCFScape. Go to hl2/cfg and extract the skill.cfg locataed there to your mod's own CFG folder.

-Let's up the pistol strength a little to compensate for the lower clip size we put in earlier. Look for the key sk_plr_dmg_pistol, around line #140. (I recommend using a program such as Notepad++ for CFG editing, and it has line numbers) This is the damage the player deals with a pistol shot. sk_npc_dmg_pistol is therefore the damage an NPC deals with a pistol shot.

-Set your sk_plr_dmg_pistol up to "6", just for a slightly bigger whack. When I change values anywhere, I like to put a comment to remind myself of the default if I screw it up. Put in a comment by adding a "//". Anything after the // is entirely ignored.

news post image

NB: [NA] is the abbreviation of my modname. I put it next to any code/CFG I edit along with the default value, so I can just run a search for [NA] to find any custom bits I've done.

-Now let's tweak the maximum AR2 ammo. See I really like the AR2, but it just runs out way too fast for me. Note in the screenshot I added another clip to the maximum AR2 ammo. The key sk_max_ar2 defines the maximum number of bullets the gun can have, so I added another 30 which is equal to one clip. Also see how below there is a key called sk_max_ar2_altfire, which simply defines the max number of glowy-ball-disintegrating-thingies you can have. (Technical term for them.) The same exists for the smg (sk_max_smg1_grenade)

-Everything else is obvious. Really, Valve did a good job naming it... Go use it to your advantage.

Underwater Weapons #2c
Note:This is a code change

-Open your project and then open the Server Episodic soluton, expand the "Source files" folder followed by "HL2 DLL."

-Open up weapon_shotgun.cpp and scroll to line #728, which should be the code

CWeaponShotgun::CWeaponShotgun( void )

-This is the constructor, as the comment says. Despite it being at the bottom of the file, (It's a coding preference, it can be anywhere really) the stuff here gets executed first. This is where we tell it to allow underwater fire. By default, all guns can't shoot underwater, so we have to add something to make it let us.

Add the following code to the bottom of the constructor block, but before the }

m_bFiresUnderwater	= true;

news post image
NB: [NA] is the abbreviation of my modname. I put it next to any code/CFG I edit along with the default value, so I can just run a search for [NA] to find any custom bits I've done.

-If you want to stop a gun firing underwater (For example, the pistol) open up weapon_pistol.cpp and use the find feature to find m_bFiresUnderwater within the current document, and set it to false.

-The same applies to alternate weapon fires. For instance, the SMG nade. Open weapon_smg1.cpp and go to line #144 and you should find m_bAltFiresUnderwater = false;. To allow underwater SMG nades, set it to true.

-Compile and have fun. Be aware some guns already have their m_bFiresUnderwater keys set, so don't add one if it already exists.

NPC Weapon Ranges #3
This covers how to change the distance before an NPC will fire, or not fire, their weapon. Useful for allowing NPC's to 'snipe' with an SMG. This is a code feature.

Hostile NPC Ranges #3a
Hostile NPCs, such as the combine, can't shoot as far as allied NPC's, such as the rebels.

-Open your project and then open the Server Episodic soluton, expand the "Source files" folder followed by "HL2 DLL."

-Open up weapon_smg1.cpp and scroll to line #139, which should be the code:

CWeaponSMG1::CWeaponSMG1( )

-A few lines below will be "m_fMinRange1" and "m_fMaxRange1", which should be 0 and 1500 respectively. m_fMinRange1 is how far away you (Or allied NPCs I believe) must be from the hostile NPC before it'll shoot. For instance, there's no point them launching an RPG if you're 3 feet away. m_fMaxRange1 is the "Don't fire until they're closer than <m_fMaxRange1>". Tweak these how you want.

-After that, scroll down to line #160 which should be something like

void CWeaponSMG1::Equip( CBaseCombatCharacter *pOwner )

-Now listen up, this is important. What this bit of code does is, tweak the range for allied NPC's. (Check the next section too.) What it does here is check to see if it's an allied NPC, and if it is extend the range. If not, set it to 1500. Now something stood out to me here. We've already set it to 1500, so is this code really necessary? I comment out everything from else to the } as shown, without any problems so far.

news post image

Do so at your own risk, but as I said, I've had no issues anymore. If you decide not to comment it out, you must change the m_fMaxRange listed there to whatever you set it to in the constructor.

Some weapons also have a m_fMinRange2, such as the shotgun. This is simply the distances for their secondary fire.

Allied NPC Ranges #3b
Allied NPCs can shoot a bit further than hostile NPCs, and as such their ranges are setup somewhere in the not-to-distant code.

Important Not all guns edit ranges for allies, some have just a flat range for everybody. (Such as the shotgun)

-Open your project and then open the Server Episodic soluton, expand the "Source files" folder followed by "HL2 DLL."

-Open up weapon_smg1.cpp and scroll to line #160, which should be the code:

void CWeaponSMG1::Equip( CBaseCombatCharacter *pOwner )

-Find the code:

	if( pOwner->Classify() == CLASS_PLAYER_ALLY )
		m_fMaxRange1 = 3000;

-Change the m_fMaxRange1 to whatever you want.

-Compile and enjoy

Conclusion - #4
This is a detailed guide to various aspects of weapon editing. I myself am by no means an expert at C++, and modding is my only real experience with it. I have however, coded in languages like PAWN for AMXX (Goldsrc anyone?) and such, so I can sort of apply the knowledge, and PAWN is a distant descendant of C apparently. As such, if any experienced C++ gurus can add/tweak anything please let me know and I'll do so with credits.

I may add to this guide if I find anything along the way, which I expect I will. As I said, if anyone else has any knowledge they'd like added please let me know and I'll add it with credits. I am not an expert at the Source engine (Or maths if anyone has an issue with my vector coneage...) and I haven't extensively tested everything in this guide. (But the majority of it I did in my own mod) I see no reason why it all wouldn't work though.

Holy crap my fingers hurt. I started this at 4:39pm, and the time is now 21:22pm. I stopped for about an hour total in between. afk, dying.


View comments ( 0 )

Back to top