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: 6593
Number of comments: 4
Description: When a player dies...
Itís 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 donít 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 18: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 10:19:26
Dunno what went wrong, but i still drop a weaponbox....

Posted By: Lord_Draco on Sep 20 2004 at 07: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 15: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.

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 05 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
knock knock
General | News
By: MIFUNE | Dec 31 2017
 
knock knock
General | News
By: omega | Dec 22 2016
 
knock knock
General | News
By: MIFUNE | Oct 10 2015
 
New HL HUD Message System
Half-Life | Coding | Shared Tutorials
By: chbrules | Dec 31 2011
 
knock knock
General | News
By: Whistler | Nov 05 2011
 
Particle Engine tutorial part 4
Half-Life | Coding | Client Side Tutorials
By: darkPhoenix | Feb 18 2010
 
Particle Engine tutorial part 2
Half-Life | Coding | Client Side Tutorials
By: darkPhoenix | Feb 11 2010
 
Particle Engine tutorial part 3
Half-Life | Coding | Client Side Tutorials
By: darkPhoenix | Feb 11 2010
 
Game Movement Series #2: Analog Jumping and Floating
Half-Life 2 | Coding | Shared Tutorials
By: mars3554 | Oct 26 2009
 
Particle Engine tutorial part 5
Half-Life | Coding | Client Side Tutorials
By: Deadpool | Aug 02 2009
 

Site Info
297 Approved Articless
8 Pending Articles
3940 Registered Members
0 People Online (7 guests)
About - Credits - Contact Us

Wavelength version: 3.0.0.9
Valid XHTML 1.0! Valid CSS!