Adding a Weapon Drop System
This tutorial will cover on the implementation of a valid 'weapon drop system'. This same tutorial also bears a work around on how to implement new commands that can be edited from the keyboard menu.
Button & Key Definitions
At first, you should manage to go to the Client solution and open up 'in_buttons.h'. In this file, there is a serie of definitions macros that bear numerical identifications such as
#define IN_ATTACK (1 << 0)
#define IN_JUMP (1 << 1)
Under
#define IN_ATTACK3 (1 << 25)
Add the following piece of code:
#define IN_DROP (1 << 26) // Weapon drop system.
When this task is completed, direct yourself to 'in_main.cpp' in the Client repertory.
At the top of the file, there are several other declarations such as:
kbutton_t in_speed;
kbutton_t in_walk;
Around line 146, Under
kbutton_t in_ducktoggle;
Define the main button key of the primary drop system.
kbutton_t in_drop;
The button declaration will need to be implemented with several functions that will calculate the current status of the key events such as if the key was pressed or released.
Scroll down around line 471 and add the following functions:
void IN_DropUp( const CCommand &args ) { KeyUp( &in_drop, args[1] ); }
void IN_DropDown( const CCommand &args ) { KeyDown( &in_drop, args[1] ); }
These two functions will be used to toggle the current state of the key presses.
Go to line 1474 and under the "CalcButtonBits" definitions, after
CalcButtonBits( bits, IN_ATTACK3, s_ClearInputState, &in_attack3, bResetState );
add this asset of code:
CalcButtonBits( bits, IN_DROP, s_ClearInputState, &in_drop, bResetState );
The last implementation in this file are the main console commands that will be accessed throughout the game in order to perform the drop sequence.
Around line 1632, Under
static ConCommand endattack3( "-attack3", IN_Attack3Up );
Put these console commands:
static ConCommand enddrop( "-drop", IN_DropUp );
static ConCommand startdrop( "+drop", IN_DropDown );
The main drop key system is completed. In order for this key to be performed, this will require to be called by a function that will evaluate the main key presses during the game.
Weapon drop function implementation
You shall open up 'hl2_player.cpp' and 'hl2_player.h'.
In 'hl2_player.h', around line 124, add this function declaration:
void DropActiveWeapon( void );
This function will be responsible for performing the main weapon 'drop' occurence.
In 'hl2_player.cpp', add this function:
void CHL2_Player::DropActiveWeapon( void )
{
Vector VecForward;
EyeVectors(&VecForward, NULL, NULL);
VecForward *= 300.0f;
BaseClass::Weapon_Drop( GetActiveWeapon(), NULL, &VecForward );
}
This function evaluates the player's current view direction and applies a velocity of 300 to the active weapon. It as well calls the actual base function that will be handle the drop system from the 'Base' class.
At the top of 'hl2_player.cpp', around line 76, add this ConVar definition:
static ConVar sv_weapon_drop_enabled("sv_weapon_drop_enabled", "1");
To be able to react to key presses, the 'Drop' key will need to be evaluated. In 'hl2_player.cpp', around line 553, find a function named 'void CHL2_Player::PreThink(void)'.
At the end of the function, at line 889, you should implement this structure:
if ( m_afButtonPressed & IN_DROP )
{
if ( IsAlive() &&
!IsInAVehicle() &&
HasWeapons() &&
sv_weapon_drop_enabled.GetBool() )
{
DropActiveWeapon();
}
}
The weapon drop system is enabled and fully implemented, the last adjustment is to make it customizable in the main keyboard bind menu.
In the (modification) folder, ex: "steamapps\sourcemods\mymod", there should be a folder named "scripts". Scroll through this folder until you reach two files named 'kb_act.lst', 'kb_def.lst'
Open up 'kb_act.lst', and at the end of this file, add the following code:
"+drop" "#Valve_Drop_Weapon"
Open up 'kb_def.lst', and at the end of this file, add the following code:
"m" "+drop"
In this case, 'm' can be replaced with the key of your choice.
In order for this command to appear in the main key bind menu, you will be required to extract a particuliar file from the current Source Engine's (GCF) pack. In your Steam folder, find a file named "source 2007 binaries 2.gcf" and in it, head to the resource folder and scroll down until you managed to find a file named "valve_english.txt".
Please, keep in mind that the language of the text file should correspond to your current game language. If you play (Half-Life 2) in German, then you will extract "valve_german.txt".
You shall extract this file to the main 'Resource' folder of the current (modification). In this file, under "Valve_Console_Toggle" , add this following line:
"Valve_Drop_Weapon" "Drop current weapon"
The weapon drop system should now be completed. Launch the (modification) and go to the keyboard customization menu. Find the main line "Drop current weapon" and if it is not already bind, assign a proper key to this new command.
Fix for the 'magically reappearing ammo' bug
(Credit to TheMaster974 for the following fixes) If you fire a weapon and then drop it without reloading, the ammunition will be back in the magazine when you pick it up again.
Open 'player.cpp' and find a function named 'bool CBasePlayer::BumpWeapon' around line 6604, go to the end of the function and comment out this line:
// Always switch to a newly-picked up weapon
if ( !PlayerHasMegaPhysCannon() )
{
// If it uses clips, load it full. (this is the first time you've picked up this type of weapon)
if ( pWeapon->UsesClipsForAmmo1() )
{
// Comment out this:
//pWeapon->m_iClip1 = pWeapon->GetMaxClip1();
}
Weapon_Switch( pWeapon );
}
However, this fix will not affect the Crossbow, RPG, and Frag Grenade, they need extra work to be fixed. Go into your scripts mod folder (...\steamapps\sourcemods\mymod\scripts), open weapon_crossbow.txt and weapon_rpg.txt (if they aren't present just take the one from your Half-Life 2 copy) and change the "default_clip" value to 1 in both files.
"default_clip" "1"
Open 'weapon_frag.cpp' and in your class definition after:
bool ShouldDisplayHUDHint() { return true; }
add:
virtual void Drop( const Vector& vecVelocity );
Go to the end of the file and copy/paste this:
void CWeaponFrag::Drop(const Vector& vecVelocity)
{
DecrementAmmo(GetOwner());
BaseClass::Drop(vecVelocity);
}
Go in 'weapon_rpg.cpp' and in the function 'void CWeaponRPG::Drop' before 'BaseClass::Drop( vecVelocity );' add:
DecrementAmmo(GetOwner());
Issue when dropping a weapon while reloading
(Credit to TheMaster974 for the following fix) If you drop a weapon while reloading it, the reload animation won't play when you pick it back up, and the magazine will be filled instantly.
Open 'basecombatweapon_shared.cpp', go to the 'void CBaseCombatWeapon::Drop' function and at the end before:
// If we're not allowing to spawn due to the gamerules,
// remove myself when I'm dropped by an NPC.
if ( pOwner && pOwner->IsNPC() )
{
if ( g_pGameRules->IsAllowedToSpawn( this ) == false )
{
UTIL_Remove( this );
return;
}
}
add:
m_bInReload = false;