Wayback Machine
DEC AUG FEB
Previous capture 8 Next capture
2004 2007 2010
8 captures
29 May 04 - 20 Jun 10
sparklines
Close Help
Welcome, Guest! Login | Register

Drop primary gun instead of weapon box [Print this Article]
Posted by: [NL]Mox
Date posted: Feb 14 2003
User Rating: 4 out of 5.0
Number of views: 3096
Number of comments: 4
Description: When a player dies...
Its a weird sight that when a player dies he drops a weapon box. WTF ? He was carrying a rocket launcher, which never fits in that small box! So we want to change that.

First of all we need the server side project and open player.cpp. There we find PackDeadPlayerItems around line 747.
First of all we declare a new CBasePlayerWeapon to store the current weapon info, we dont need rpgPackWeapons. So we change this:

 CODE  

    int iWeaponRules;
    int iAmmoRules;
    int i;
    CBasePlayerWeapon *rgpPackWeapons[ 20 ];// 20 hardcoded for now. How to determine exactly how many weapons we have?
    int iPackAmmo[ MAX_AMMO_SLOTS + 1];
    int iPW = 0;// index into packweapons array
    int iPA = 0;// index into packammo array

    memset(rgpPackWeapons, NULL, sizeof(rgpPackWeapons) );
    memset(iPackAmmo, -1, sizeof(iPackAmmo) );



into this:

 CODE  

    int iWeaponRules;
    int iAmmoRules;
    int i;
    CBasePlayerWeapon *CurrentWeapon;
//    CBasePlayerWeapon *rgpPackWeapons[ 20 ];// 20 hardcoded for now. How to determine exactly how many weapons we have?
//  int iPackAmmo[ MAX_AMMO_SLOTS + 1];
//  int iPW = 0;// index into packweapons array
//  int iPA = 0;// index into packammo array

//  memset(rgpPackWeapons, NULL, sizeof(rgpPackWeapons) );
//  memset(iPackAmmo, -1, sizeof(iPackAmmo) );


Now we got a place to store what weapon the player has. Now let's look at the next piece of code:

 CODE  

    // get the game rules
    iWeaponRules = g_pGameRules->DeadPlayerWeapons( this );
  iAmmoRules = g_pGameRules->DeadPlayerAmmo( this );

    if ( iWeaponRules == GR_PLR_DROP_GUN_NO && iAmmoRules == GR_PLR_DROP_AMMO_NO )
    {
  // nothing to pack. Remove the weapons and return. Don't call create on the box!
  RemoveAllItems( TRUE );
  return;
    }

// go through all of the weapons and make a list of the ones to pack
    for ( i = 0; i < MAX_ITEM_TYPES; i++ )
    {
  if ( m_rgpPlayerItems[ i ] )
  {
   // there's a weapon here. Should I pack it?
   CBasePlayerItem *pPlayerItem = m_rgpPlayerItems[ i ];

   while ( pPlayerItem )
   {
    switch( iWeaponRules )
    {
    case GR_PLR_DROP_GUN_ACTIVE:
      if ( m_pActiveItem && pPlayerItem == m_pActiveItem )
      {
      // this is the active item. Pack it.
      rgpPackWeapons[ iPW++ ] = (CBasePlayerWeapon *)pPlayerItem;
      }
      break;

    case GR_PLR_DROP_GUN_ALL:
      rgpPackWeapons[ iPW++ ] = (CBasePlayerWeapon *)pPlayerItem;
      break;

    default:
      break;
    }

    pPlayerItem = pPlayerItem->m_pNext;
   }
  }
    }


As you can see this code looks at all items and adds them to the array of weapons to pack inside the box. We can easily use this code to check which weapon is the Primary Gun of the player and then use CurrentWeapon to create a copy of this weapon.

So actually instead of really dropping the weapon itself, we create a copy which we can drop and delete the actual weapon.

 CODE  

    if ( iWeaponRules == GR_PLR_DROP_GUN_NO && iAmmoRules == GR_PLR_DROP_AMMO_NO )
    {
  // nothing to pack. Remove the weapons and return. Don't call create on the box!
  RemoveAllItems( TRUE );
  return;
    }

    // go through all of the weapons and make a list of the ones to pack
    for ( i = 0; i < MAX_ITEM_TYPES; i++ )
    {
  if ( m_rgpPlayerItems[ i ] )
  {
   // there's a weapon here. Should I pack it?
   CBasePlayerItem *pPlayerItem = m_rgpPlayerItems[ i ];

   while ( pPlayerItem )
   {
    if ( m_pActiveItem && pPlayerItem == m_pActiveItem )
    {
      // this is the active item. Drop it
      CurrentWeapon = (CBasePlayerWeapon *)pPlayerItem; //create a copy of the active item
      CurrentWeapon->m_iDefaultAmmo = m_rgAmmo[m_pActiveItem->PrimaryAmmoIndex()];// set default ammo when picked up to the amount the dieing player still has left.
      break; //we don't need more..
    }
   pPlayerItem = pPlayerItem->m_pNext;
   }
  }
    }


As you can see I set m_iDefaultAmmo of our copy to the value of the ammo still left in the actual weapon. This way when the copy is picked up again it will have the ammo which was still left in the weapon.
Since we don't need any other ammo we can comment out the following piece about packing the ammo. You can comment all the code from here since it only handles about creating the box with a gun and ammo.

For your convenience, comment out this piece of code:
/*
 CODE  

// now go through ammo and make a list of which types to pack.
    if ( iAmmoRules != GR_PLR_DROP_AMMO_NO )
    {
  for ( i = 0; i < MAX_AMMO_SLOTS; i++ )
  {
   if ( m_rgAmmo[ i ] > 0 )
   {
    // player has some ammo of this type.
    switch ( iAmmoRules )
    {
    case GR_PLR_DROP_AMMO_ALL:
      iPackAmmo[ iPA++ ] = i;
      break;

    case GR_PLR_DROP_AMMO_ACTIVE:
      if ( m_pActiveItem && i == m_pActiveItem->PrimaryAmmoIndex() )
      {
      // this is the primary ammo type for the active weapon
      iPackAmmo[ iPA++ ] = i;
      }
      else if ( m_pActiveItem && i == m_pActiveItem->SecondaryAmmoIndex() )
      {
      // this is the secondary ammo type for the active weapon
      iPackAmmo[ iPA++ ] = i;
      }
      break;

    default:
      break;
    }
   }
  }
    }

// create a box to pack the stuff into.
    CWeaponBox *pWeaponBox = (CWeaponBox *)CBaseEntity::Create( "weaponbox", pev->origin, pev->angles, edict() );

    pWeaponBox->pev->angles.x = 0;// don't let weaponbox tilt.
    pWeaponBox->pev->angles.z = 0;

    pWeaponBox->SetThink( CWeaponBox::Kill );
    pWeaponBox->pev->nextthink = gpGlobals->time + 120;

// back these two lists up to their first elements
    iPA = 0;
    iPW = 0;

// pack the ammo
    while ( iPackAmmo[ iPA ] != -1 )
    {
  pWeaponBox->PackAmmo( MAKE_STRING( CBasePlayerItem::AmmoInfoArray[ iPackAmmo[ iPA ] ].pszName ), m_rgAmmo[ iPackAmmo[ iPA ] ] );
  iPA++;
    }

// now pack all of the items in the lists
    while ( rgpPackWeapons[ iPW ] )
    {
  // weapon unhooked from the player. Pack it into der box.
  pWeaponBox->PackWeapon( rgpPackWeapons[ iPW ] );

  iPW++;
    }

    pWeaponBox->pev->velocity = pev->velocity * 1.2;// weaponbox has player's velocity, then some.

*/

Make sure to leave the last line (RemoveAllItems( TRUE )) because we want the dead player to be itemless.

Ok, so before the last line with RemoveAllItems we need the player to drop our copy of his primary weapon. So we create a new entity CBasePlayerWeapon at the origin of the player, like this:

 CODE  

CBasePlayerWeapon *pDropWeapon = (CBasePlayerWeapon *)CBaseEntity::Create((char *)STRING(CurrentWeapon->pev->classname), pev->origin, pev->angles, edict() ); //create dropweapon


Now we need to give this weapon (pDropweapon) the values of our copy, like this:

 CODE  

    pDropWeapon->m_iClip = CurrentWeapon->m_iClip; //copy clip contence of the original weapon.
    pDropWeapon->m_iDefaultAmmo = CurrentWeapon->m_iDefaultAmmo; //set default ammo to the ammo that the original player had.


And we also need to make sure that our newly created entity will not tilt (this code was also used in the box-code)

 CODE  

    pDropWeapon->pev->angles.x = 0;// don't let weapon tilt.
    pDropWeapon->pev->angles.z = 0;


One important thing I found out while testing my code was that the newly created weapon will respawn by default. I don't think you want to have those weapons respawned again and again so we add this line:

 CODE  

pDropWeapon->pev->spawnflags |= SF_NORESPAWN;// never respawn


If you want this weapon to be removed after a sertain amount of time (why? I don't know, I'd remove the following code if you want your mod to be realistic) you can add this piece of code (like the weaponbox code):

 CODE  

pDropWeapon->SetThink( CBasePlayerWeapon::Kill ); //make dropweapon kill itself after 120 seconds.
pDropWeapon->pev->nextthink = gpGlobals->time + 120;


Last but not least we want our weapon to fly... (fly?, yeah fly) If a player dies his weapon flies out of his hands, you can choose to make it fly further than the player (multiply players speed with 1.2 or so) or make it fly less far than the players body (multiply players speed with 0.8 ). I used this (like the weaponbox again):

 CODE  

pDropWeapon->pev->velocity = pev->velocity * 1.2;


And that's it. Now the player will drop his last active item when he dies. If you want you can let the player drop all weapons he has (although that will give a mess when you have alot of weapons). You just make an array of 'CurrentWeapon' and you loop at the creation of DropWeapon.

I hope this tutorial helped you on your way to create your ultimate mod or just gave you some experience about creation of entities.

If you have any comments, you can send me a PM. This was my first tut, so don't be hard on me k? user posted image

[NL]Mox


---
shit happens

Rate This Article
This article is currently rated: 4 out of 5.0 (4 Votes)

You have to register to rate this article.
User Comments Showing comments 1-4

Posted By: Put Put Cars on Jan 24 2004 at 12:41:52
Nice tut, but I seem to be getting a wierd problem. Once i drop my gun, I cant pick it up lol

Posted By: kameli on Feb 25 2004 at 04:19:26
Dunno what went wrong, but i still drop a weaponbox....

Posted By: Lord_Draco on Sep 20 2004 at 01:20:57
how do you make the player drop all guns? I tried to "...just make an array of 'CurrentWeapon' and you loop at the creation of DropWeapon..." but i couldn't get it to work. could someone tell me how you'd do that?

Posted By: [NL]Mox on Sep 24 2004 at 09:49:43
The original code makes an array of all weapons (rgpPackWeapons) and loops through it as well..
So just create a new weapon from that and drop it.


You must register to post a comment. If you have already registered, you must login.
Donate
Any money that is donated will go towards the server costs that I incur for running our server. Don't feel you HAVE to donate, but the link is there if you want to help us out a little. Thanks :)

Latest Articles
3rd person View in Multiplayer
Half-Life 2 | Coding | Client Side Tutorials
How to enable it in HL2DM

By: cct | Nov 13 2006

Making a Camera
Half-Life 2 | Level Design
This camera is good for when you join a map, it gives you a view of the map before you join a team

By: slackiller | Mar 04 2006

Making a camera , Part 2
Half-Life 2 | Level Design
these cameras are working monitors that turn on when a button is pushed.

By: slackiller | Mar 04 2006

Storing weapons on ladder
Half-Life 2 | Coding | Snippets
like Raven Sheild or BF2

By: British_Bomber | Dec 24 2005

Implementation of a string lookup table
Half-Life 2 | Coding | Snippets
A string lookup table is a set of functions that is used to convert strings to pre-defined values

By: deathz0rz | Nov 13 2005


Latest Comments
3 State Zoom For Any Weapon
Half-Life 2 | Coding | Server Side Tutorials
By: Ennuified | Oct 18 2007
 
Storing weapons on ladder
Half-Life 2 | Coding | Snippets
By: cct | Sep 07 2007
 
CTF Gameplay Part 1
Half-Life | Coding | Shared Tutorials
By: DarkNight | Aug 28 2007
 
CTF Gameplay Part 1
Half-Life | Coding | Shared Tutorials
By: deedok | Aug 20 2007
 
Debugging your half-life 2 mod
Half-Life 2 | Coding | Articles
By: blackshark | Aug 17 2007
 
How to add Ammocrates for missing ammo type and/or create new ammo types
Half-Life 2 | Coding | Server Side Tutorials
By: EoD | Aug 15 2007
 
GameUI
Half-Life 2 | Coding | Client Side Tutorials
By: G.I. Jimbo | May 19 2007
 
Reading and Writing Entire Structures
General | General Coding
By: monokrome | Jan 27 2007
 
VGUI Scope
Half-Life | Coding | Client Side Tutorials
By: Pongles | Jan 19 2007
 
Where do we go from here
General | News
By: SilentSounD | Jan 18 2007
 

Site Info
296 Approved Articless
3 Pending Articles
3940 Registered Members
0 People Online (13 guests)
About - Credits - Contact Us

Wavelength version: 3.0.0.9
Valid XHTML 1.0! Valid CSS!