Half-Life FlatLine Arena is fast paced first person multiplayer action. The mod has been in development for more than 12 years now. With the release always around the corner, but the time always not being sufficient and the jobs to be done piling up. Never the less I decided to create the page for it and to show the world it exists.

Post tutorial Report RSS How to create new bullet type & how to separate the Glock from MP5 ammo usage

Hello there. This is the second tutorial, on separating weapon ammunitions. In part one I showed you how to separate the Egon and the Gauss, not to use the same kind of animation, basically the egon now does not use "uranium". This allows you to run out of gauss ammo, but still to be able to use the egon. In this tutorial, I will show you how to create new bullet type, we'll call it .45 ACP (We'll assume the Glock is now USP) and will separate it from the MP5 ammo.

Posted by on - Advanced Server Side Coding

How to create new bullet type & how to separate the Glock from MP5 ammo usage.

bullet type


In this tutorial, I will show you how to create new bullet type, we'll call it .45 ACP (We'll assume the Glock is now USP) and will separate it from the MP5.


Let the fun begins.

Starting with our new Bullet

Open "ev_hldm.cpp" under:

void EV_HLDM_DecalGunshot( pmtrace_t *pTrace, int iBulletType )

below

case BULLET_PLAYER_357:

add:

case BULLET_PLAYER_45ACP:

Then in the same file find :

case BULLET_PLAYER_357:

EV_HLDM_PlayTextureSound( idx, &tr, vecSrc, vecEnd, iBulletType );
EV_HLDM_DecalGunshot( &tr, iBulletType );

break;


Under it add:

case BULLET_PLAYER_45ACP:

EV_HLDM_PlayTextureSound( idx, &tr, vecSrc, vecEnd, iBulletType );
EV_HLDM_DecalGunshot( &tr, iBulletType );

break;


Lastly, this is important to be added for the weapon you will be modifying to use your new bullet, or the client prediction will not work properly. Since I will be modifying the Glock:

Find:

EV_HLDM_FireBullets( idx, forward, right, up, 1, vecSrc, vecAiming, 8192, BULLET_PLAYER_9MM, 0, &tracerCount[idx-1], args->fparam1, args->fparam2 );

and change it to:

EV_HLDM_FireBullets( idx, forward, right, up, 1, vecSrc, vecAiming, 8192, BULLET_PLAYER_45ACP, 0, &tracerCount[idx-1], args->fparam1, args->fparam2 );

Now, open ev_hldm.h and let's add our new bullet into the enum, below:

BULLET_PLAYER_357, // python


add this:

BULLET_PLAYER_45ACP, // .45 ACP


Let's go to combat.cpp ; under :

Vector CBaseEntity::FireBulletsPlayer..

look for:

case BULLET_PLAYER_357:
pEntity->TraceAttack(pevAttacker, gSkillData.plrDmg357, vecDir, &tr, DMG_BULLET);
break;

after it add:

case BULLET_PLAYER_45ACP:
pEntity->TraceAttack(pevAttacker, gSkillData.plrDmg45ACP, vecDir, &tr, DMG_BULLET);
break;

Note: we need to register: plrDmg45ACP, or any gun using .45 ACP will do 0 dmg... what a gun is that? (we will do this in a later step).

Now, open weapons.cpp look for:

switch( iBulletType )

and under

case BULLET_PLAYER_357:

add:

case BULLET_PLAYER_45ACP:

Then in the same file, look for:

UTIL_PrecacheOther( "ammo_357" );

after it add:

// .45 ACP
UTIL_PrecacheOther( "ammo_45acp" );

Now, do you remember we added enumeration for our new bullet on the client (in ev_hldm.h)?

Well we need to add it on the server too:

Open weapons.h , look for:

// bullet types
typedef enum

and under

BULLET_PLAYER_357, // python

add this :

BULLET_PLAYER_45ACP, // .45 ACP

Ok, we just registered the .45 ACP as bullet. Now we only need to make it ammo as well... and then to add it to a gun.. so it's like 1/3 done...

Open hl_weapons.cpp, look for:

player.ammo_357 = (int)from->client.vuser1[1];

then right after it add:

player.ammo_45acp = (int)from->client.vuser1[3]; // .45 ACP

Then a little below that look for:

to->client.vuser1[1] = player.ammo_357;


Then below it add:

to->client.vuser1[3] = player.ammo_45acp; // .45 ACP


Now, open cbase.h, look for:

int ammo_357;

below it add:

int ammo_45acp;


Go to "client.cpp" and look for:

cd->vuser1.y = pl->ammo_357;

right below it add:

cd->vuser1.y = pl->ammo_45acp; // .45 ACP

Now let's register the dmg CVAR for our new bullet, otherwise it will do 0 dmg.

Open game.cpp and look for:

// 357 Round

After the 1st instance and the declarations for 357 (around line 305) add:

// .45 ACP Round
cvar_t sk_plr_45ACP_bullet1 = {"sk_plr_45ACP_bullet1","0"};
cvar_t sk_plr_45ACP_bullet2 = {"sk_plr_45ACP_bullet2","0"};
cvar_t sk_plr_45ACP_bullet3 = {"sk_plr_45ACP_bullet3","0"};


Then in the CVAR Register (around 747 line) we need to add similar to the rest:

// .45 ACP Round
CVAR_REGISTER ( &sk_plr_45ACP_bullet1 );// {"sk_plr_45ACP_bullet1","0"};
CVAR_REGISTER ( &sk_plr_45ACP_bullet2 );// {"sk_plr_45ACP_bullet2","0"};
CVAR_REGISTER ( &sk_plr_45ACP_bullet3 );// {"sk_plr_45ACP_bullet3","0"};

Now go to "gamerules.cpp" and look for:

// 357 Round

After this definition:

// 357 Round
gSkillData.plrDmg357 = GetSkillCvar( "sk_plr_357_bullet");


add our new entry:

// .45 ACP Round
gSkillData.plrDmg45ACP = GetSkillCvar( "sk_plr_45acp_bullet");


Now, you can count on the cfg file for the damage on the ballet in multiplayer, or add it manually. Let us add it manually, like the normal people:

Open multiplay_gamerules.cpp and look for:

// 357 Round
gSkillData.plrDmg357 = 40;


after it add:

// .45 ACP Round
gSkillData.plrDmg45ACP = 12;

Note: You still have to define it in the cfg, or in singleplayer, you will do 0 dmg.


Now, open "player.cpp" and look for:

void CBasePlayer::TabulateAmmo()

add entry for the new bullet after this line:

ammo_357 = AmmoInventory( GetAmmoIndex( "357" ) );

like this:

ammo_45acp = AmmoInventory( GetAmmoIndex( "45ACP" ) ); // .45 ACP

Now, in the same file look for:

GiveNamedItem( "ammo_357" );

after it add:

GiveNamedItem( "ammo_45acp" ); // .45 ACP


This step is actually optional, and it will add the ammo to impulse 101. You love cheats right?

Now, go to "skill.h" and after:

float plrDmg357;


add:

float plrDmg45ACP; // .45 ACP


Now, go to "stats.cpp" and look for:

float AmmoDamage( const char *pName )

after:

if ( !strcmp( pName, "357" ) )
return gSkillData.plrDmg357;

add:

if ( !strcmp( pName, "45ACP" ) )
return gSkillData.plrDmg45ACP;


Now, go to "weapons.h" and look for:

#define _357_MAX_CARRY 36

after it add:

#define _45ACP_MAX_CARRY 200

then look for:

#define AMMO_357BOX_GIVE PYTHON_MAX_CLIP

and after it add:

#define AMMO_45ACPBOX_GIVE GLOCK_MAX_CLIP

Ok, we're ready with the definitions (2/3 there). Now we only need to modify our Glock to use our new bullets.

Open the folder "wpn_shared" and open "hl_wpn_glock.cpp"

go to:

int CGlock::GetItemInfo(ItemInfo *p)

and change:

p->pszAmmo1 = "9mm";

to:

p->pszAmmo1 = "45ACP";

then:

p->iMaxAmmo1 = _9MM_MAX_CARRY;

to:

p->iMaxAmmo1 = _45ACP_MAX_CARRY;

Go all the way to the bottom and change the class:

class CGlockAmmo : public CBasePlayerAmmo

to point to our new bullet:

this one:

if (pOther->GiveAmmo( AMMO_GLOCKCLIP_GIVE, "9mm", _9MM_MAX_CARRY ) != -1)

to:

if (pOther->GiveAmmo( AMMO_GLOCKCLIP_GIVE, "45ACP", _45ACP_MAX_CARRY ) != -1)

Before I forget, you probably noticed that if you compile now, and you go in the game you will get only 17 bullets in the Glock and nothing more...


This is since if you remember initially we had shared ammo for the MP3 and the Glock... and what you get when you spawn is controlled by a function in multiplay_gamerules.cpp , this one at the moment still uses the old assumption that MP5 and Glock share ammo, so you got ammo for MP5..

We need to fix that, unless you'd like the extra 68 ammo for the MP5.

Look for:

void CHalfLifeMultiplay :: PlayerSpawn( CBasePlayer *pPlayer )

in the function, change the following line from:

pPlayer->GiveAmmo( 68, "9mm", _9MM_MAX_CARRY );// 4 full reloads


to:

pPlayer->GiveAmmo( 68, "45ACP", _45ACP_MAX_CARRY );// 4 full reloads

Compile, there should be no errors.

Now you might want to go and play around with the .fgd file, for completion sake, but I will leave that to you.

So, if everything went well, (I hope it did) you have separated ammo for MP5 and Glock / USP.

Example in game:

20220306181826 1

20220306181837 1

Have fun. Kids.

If you don't like something - Mod it!

Post comment Comments
Blackflame_
Blackflame_ - - 32 comments

Great tutorial thank you

Reply Good karma Bad karma+1 vote
nodninja
nodninja - - 5 comments

This is a great tutorial, I'll definitely be using it for my mod. But is there a way to separate the shell model that comes out of the gun into two? Really bugs me that the m4a1 shoots out 9mm shells...

Reply Good karma Bad karma+1 vote
Post a comment

Your comment will be anonymous unless you join the community. Or sign in with your social account: