Posted by: [NL]Mox
Date posted: Feb 14 2003 User Rating: 4 out of 5.0 | Number of views: 6983 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:
| | 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:
| | 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:
| | // 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.
| | 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: /*
| | // 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:
| | 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:
| | 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)
| | 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:
| | 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):
| | 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):
| | 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?
[NL]Mox
--- shit happens |
|
User Comments
Showing comments 1-4
Nice tut, but I seem to be getting a wierd problem. Once i drop my gun, I cant pick it up lol |
|
Dunno what went wrong, but i still drop a weaponbox.... |
|
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? |
|
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.
|
297 Approved Articless
8 Pending Articles
3940 Registered Members
0 People Online (9 guests)
|
|