Contents

Getting Started

Firstly, you will need to make a copy of the file "weapon_pistol.cpp", renaming the copy to "weapon_dualies.cpp". You can find the file in either the <src\game_shared\hl2mp> directory (for 2006 multiplayer), <src\game\shared\hl2mp> (for 2007 multiplayer) or <src\game\server\hl2> (for singleplayer).

Note: Feel free to name your dual pistols something else ("dualies" is just an example).

Now open the newly created file in your IDE of choice and do a search for the word "Pistol", replacing all instances with "Dualies" instead. Unfortunately, there is one part of the code we didn't actually want changed in this way - so find the section that looks like the snippet below and change all instances of the word "Dualies" back to "PISTOL" (as shown).

Note: The above is a representation of multiplayer code. Singleplayer modders can still make use of it - they just can't copy and paste it directly into their work.

One further thing to make sure of when modding multiplayer is that you include "weapon_dualies.cpp" in both the client and server projects of your solution. The correct location is <Client HL2MP\Source Files\HL2MP\Weapons> (replacing "Client" with "Server" for the server project location).

The Stub and the Flip

Now we need to add it as a stub. So now, go to "c_weapon__stubs_hl2.cpp" in the Client project and add:

STUB_WEAPON_CLASS(weapon_dualies,WeaponDualies,C_BaseHLCombatWeapon);

Where the pistol is located.

Now the gun is its own gun and works in game.

Now we must code the flip.

Add this method after CWeaponDualies::PrimaryAttack():

//-----------------------------------------------------------------------------// Purpose: Dualies Firing//-----------------------------------------------------------------------------voidCWeaponDualies::LeftGunAttack(){// If my clip is empty (and I use clips) start reloadif(UsesClipsForAmmo1()&&!m_iClip1){Reload();return;}// Only the player fires this way so we can castCBasePlayer*pPlayer=ToBasePlayer(GetOwner());if(!pPlayer){return;}// MUST call sound before removing a round from the clip of a CMachineGunWeaponSound(SINGLE);pPlayer->DoMuzzleFlash();SendWeaponAnim(GetSecondaryAttackActivity());// player "shoot" animationpPlayer->SetAnimation(PLAYER_ATTACK1);FireBulletsInfo_tinfo;info.m_vecSrc=pPlayer->Weapon_ShootPosition();info.m_vecDirShooting=pPlayer->GetAutoaimVector(AUTOAIM_SCALE_DEFAULT);// To make the firing framerate independent, we may have to fire more than one bullet here on low-framerate systems, // especially if the weapon we're firing has a really fast rate of fire.info.m_iShots=0;floatfireRate=GetFireRate();while(m_flNextPrimaryAttack<=gpGlobals->curtime){m_flNextPrimaryAttack=m_flNextPrimaryAttack+fireRate;info.m_iShots++;if(!fireRate)break;}// Make sure we don't fire more than the amount in the clipif(UsesClipsForAmmo1()){info.m_iShots=min(info.m_iShots,m_iClip1);m_iClip1-=info.m_iShots;}else{info.m_iShots=min(info.m_iShots,pPlayer->GetAmmoCount(m_iPrimaryAmmoType));pPlayer->RemoveAmmo(info.m_iShots,m_iPrimaryAmmoType);}info.m_flDistance=MAX_TRACE_LENGTH;info.m_iAmmoType=m_iPrimaryAmmoType;info.m_iTracerFreq=2;#if !defined( CLIENT_DLL )// Fire the bulletsinfo.m_vecSpread=pPlayer->GetAttackSpread(this);#else//!!!HACKHACK - what does the client want this function for? info.m_vecSpread=GetActiveWeapon()->GetBulletSpread();#endif // CLIENT_DLLpPlayer->FireBullets(info);if(!m_iClip1&&pPlayer->GetAmmoCount(m_iPrimaryAmmoType)<=0){// HEV suit - indicate out of ammo conditionpPlayer->SetSuitUpdate("!HEV_AMO0",FALSE,0);}//Add our view kick inAddViewKick();}

Weapon View Model and World Model

If you were to play your mod right now, and give yourself dual pistols, then it would just be a single pistol, but fire as two. To fix this, me must use new models. There may be a way to make it so there are dual HL2 pistols, and two view models, but this way is much, much easier. First go into Steam/Steamapps/Sourcemods/*Mod Name Here*/. Make a new folder called models. Make a new folder in models called weapons. Now, you have a few choices here. If you own Counter Strike: Source, then you can just extract the Elite models. You can also just download a skin from FPS Banana. If you download one from FPS Banana then you should get permission from the author and include him in the credits of your readme file. You can also make new models. Just make sure that all of the files are in models/weapons.

Now, you will probably see that the hands are texture-less (purple and black checkerboard). The way to fix this is to get a hand model from Counter Strike: Source. Again, you can download from FPS Banana, extract them from your CS:S directory, or make your own. Either way, you need a hands folder, with the hand materials in them. To make them work in-game, go to your mod folder in Steam/Steamapps/Sourcemods/*YOUR MOD NAME*. Make a new folder called materials. In that make a new folder called models. In that make a new folder called weapons. In that make a new folder called v_models. Extract the hands directory here.

Weapon Script File

Now that the coding is complete, a script file for the new weapon needs to be created (see here for more on weapon script files).

The easy way to do this is to make a copy of the file "weapon_pistol.txt", renaming the copy to "weapon_dualies.txt" (sound familiar?). You can find the file in the "Steam\steamapps\SourceMods\<yourmod>\scripts" directory. Set the View model to "models/weapons/v_pist_elite.mdl" (whatever the model name is, and make sure you include the quotes!)
and set the player model to "models/weapons/w_pist_elite.mdl" (again, whatever the model name is and include the quotes).

Conclusion

Now when you next play your mod you should have a working pair of dual pistols!