[Tutorial Draft] NPCs & Player weapon drop input

Grab your favourite IDE and tinker with the innards of game engines

[Tutorial Draft] NPCs & Player weapon drop input

Postby Gary on Fri Jun 29, 2012 5:39 am

[Please, to those who are better programmers, point out any errors you see! Also note; this is supposed to be for those just getting into Source code modding. I've had a few people ask for this specifically. After a few days and all the errors are found, and people think it's decent enough, I'll throw it into the tutorial bin.]

This is a super simple tutorial, perfect for beginners. It will allow all weapon-wielding NPCs, including the player, to drop their weapon(in the case of the player; the current primary).

Prerequisites:
  • At least the most basic understanding of how code works(formatting, brackets, args, etc.)
  • Source 2007 HL2 SP code(should work on others though)
  • Can build/compile the project and load custom bins

We will be working in src\game\server\basecombatcharacter.cpp. This might work other places with modifications, but I have only tested it here.

Lets get started by:
  1. Defining a new I/O input. Which allows us to use the Inputs_and_Outputs system which can be done through Hammer or console to force an NPC(or player) to drop his weapon. Here is the actual code to do so:
    Code: Select all
    DEFINE_INPUTFUNC( FIELD_VOID, "DropWeapon", InputDropWeapon ),

    We are defining a input( DEFINE_INPUTFUNC ), which is a function which returns no value(FIELD_VOID), named DropWeapon. And the function name is InputDropWeapon. This has to be done between BEGIN_DATADESC( CBaseCombatCharacter ) and END_DATADESC(). Which is roughly line 70 through 100.


  2. Now for the function, which is a void(returns no value), and part of CBaseCombatCharacter, named InputDropWeapon. It also accepts the usually inputdata, which allows you to pass text or numbers, or find the entity that fired the input. But we won't be using inputdata here...
    Code: Select all
    void CBaseCombatCharacter::InputDropWeapon( inputdata_t &inputdata )
    {
    //The magic happens here. Everything beyond this step is done between these brackets.
    }



  3. Now that we got a function to do all of our work in, lets start writing the code that really does stuff. We start out by checking if m_hActiveWeapon is valid. The handle m_hActiveWeapon is available to us because it's a member variable of the CBaseCombatCharacter class. We can check it by saying "if not m_hActiveWeapon then stop". By putting an explanation point(!), we are saying "not". And to stop the function, we use return. which, if this wasn't a void, could be used to return a value.
    Code: Select all
       if(!m_hActiveWeapon)
          return;   

    This is very important! If you don't do this, and try accessing the handle while it's pointing to an invalid location(in this case, if the NPC/player doesn't have a weapon), the game will crash. Because instead of accessing a weapon, we would be accessing NULL(nothing).


  4. Because we want the weapon to be tossed away from us, away from the camera, in the direction we are aiming. We need to get our forward vector. We start by declaring a vector named vforward(though you can name it what ever you want, you must also adapt the next part), which will be empty until we write our direction to it:
    Code: Select all
    Vector vforward;



  5. Now we use GetLocalAngles() function, which all entities have access to, to get our NPCs/player's angles. But we need it to be a vector, so we use AngleVectors(in, out) to convert GetLocalAngles() into a vector, and write it to our previously defined vector named vforward:
    Code: Select all
    AngleVectors( GetLocalAngles(), &vforward );



  6. Here, we are declaring and defining a new forward vector, which is our old one multiplied by a number representing the force in which we want to weapon to be tossed away with. If we don't toss it away with enough force, it will fall too close to the player and the game will automatically pick it right back up. 250 was enough to get it far enough for me:
    Code: Select all
    Vector throwforce = vforward * 250;

    (new vector named throwforce, which is defined as out forward vector(vforward) multiplied(*) by 250)

  7. Finally, for the actual weapon dropping code: Weapon_Drop()! Which is another function of CBaseCombatCharacter, which, after the tutorial, you can find by searching in the same file.
    You need to give it our weapon(m_hActiveWeapon), target(we don't have one, so give it nothing/NULL), and velocity/direction(throwforce):
    Code: Select all
    Weapon_Drop( m_hActiveWeapon, NULL, &throwforce );


In the end, it should look like this:
Code: Select all
void CBaseCombatCharacter::InputDropWeapon( inputdata_t &inputdata )
{
   if(!m_hActiveWeapon)
      return;         
   
   Vector vforward;      
   AngleVectors( GetLocalAngles(), &vforward );


   Vector throwforce = vforward * 250;

   Weapon_Drop( m_hActiveWeapon, NULL, &throwforce );
}



  • Use: You can test it through console by aiming at an NPC and typing "ent_fire !picker dropweapon". You can also drop your own weapon with "ent_fire !self dropweapon". And if you want, you can bind it to a key by typing: " bind X "ent_fire !self dropweapon" ".

    It will also work in Hammer, but it will show up in red, because it's only understood by the game. Hammer will still work with it, just doesn't auto-complete it and think it's wrong, though you can add it to Hammer's FGD. This is because Hammer doesn't use the mod's custom code, or even the stock code to understand what you can do with it, it only sees entities and their options through FGDs. But that's outside the scope of this tutorial.



I hoped you found this tutorial useful. And that it helped you understand the code at least little more.

As always, if you have a problem with this, or any Source modding related problem, you can contact me via PersonalMessage or Steam.


-Gary
Have a question related to modding or something I posted? Something that needs staff attention? I haven't been active lately, but feel free to PM me or message me on Steam(link below)

User avatar
Gary
Interlopers Staff
Interlopers Staff
 
Joined: Wed Dec 16, 2009 12:40 am
Location: USA, FL

Return to Programming

Who is online

Users browsing this forum: No registered users