Difference between revisions of "Authoring your first weapon entity"

From Valve Developer Community
Jump to: navigation, search
Line 3: Line 3:
 
== Overview ==
 
== Overview ==
 
It should not come as a surprise that the Source engine has a very robust weapon system. This article will cover creating a weapon entity from scratch.
 
It should not come as a surprise that the Source engine has a very robust weapon system. This article will cover creating a weapon entity from scratch.
Various topics on creating a weapon will be discussed.
+
There are many other tutorials at [[Weapons programming]].
  
 
== Getting Started ==
 
== Getting Started ==
To get started, create a new .cpp file in the server project and call it weapon_myfirstweapon.
+
To get started, create a new .cpp file in the server project and call it weapon_myfirstweapon.cpp.
 
Type this into your newly created file
 
Type this into your newly created file
 
<pre>
 
<pre>
Line 25: Line 25:
 
#endif
 
#endif
 
</pre>
 
</pre>
Just to note something here, this tutorial expects the reader is using the Source SDK Multiplayer, but if the reader wanted to make the weapon singleplayer, it should be an easy fix.
+
Also to note is this tutorial expects the reader is using the Source SDK Multiplayer, but if the reader wanted to make the weapon for singleplayer, it should be an easy fix. Just adjust the includes.
  
== Creating The Class ==
+
== Creating The Weapon ==
 
Now we will create the class that contains all the functions, so we can put the code in later.
 
Now we will create the class that contains all the functions, so we can put the code in later.
 
To start, make a new class, and define it like this
 
To start, make a new class, and define it like this
Line 83: Line 83:
 
     CWeaponMyFirstWeapon(const CWeaponMyFirstWeapon &);
 
     CWeaponMyFirstWeapon(const CWeaponMyFirstWeapon &);
 
</pre>
 
</pre>
Basically, this just creates a variable, with the type of a int, called <code>m_iTest</code>, and then this code creates an alternate constructor. How we will change the value of <code>m_iTest</code> will be discussed later. If your getting an error right at the C, just ignore that.  
+
Basically, this just creates a variable, with the type of a int, called <code>m_iTest</code>, and then this code creates an alternate constructor. How we will change the value of <code>m_iTest</code> will be discussed later. If your getting an error now just ignore that.  
 
You can also create this same variable at the top, with a <code>#define</code>.
 
You can also create this same variable at the top, with a <code>#define</code>.
 
<pre>
 
<pre>

Revision as of 21:40, 19 October 2017

Template:Toc-top

Overview

It should not come as a surprise that the Source engine has a very robust weapon system. This article will cover creating a weapon entity from scratch. There are many other tutorials at Weapons programming.

Getting Started

To get started, create a new .cpp file in the server project and call it weapon_myfirstweapon.cpp. Type this into your newly created file

#include "cbase.h"
#include "npcevent.h"
#include "in_buttons.h"

#ifdef CLIENT_DLL
#include "c_hl2mp_player.h"
#else
#include "hl2mp_player.h"
#endif

#include "weapon_hl2mpbasehlmpcombatweapon.h"

#ifndef CLIENT_DLL
#define CWeaponMyFirstWeapon C_WeaponMyFirstWeapon
#endif

Also to note is this tutorial expects the reader is using the Source SDK Multiplayer, but if the reader wanted to make the weapon for singleplayer, it should be an easy fix. Just adjust the includes.

Creating The Weapon

Now we will create the class that contains all the functions, so we can put the code in later. To start, make a new class, and define it like this

class CWeaponMyFirstWeapon : public CBaseHL2MPCombatWeapon

Now, open it up with some curly braces, and type this

public:
  DECLARE_CLASS(CWeaponMyFirstWeapon, CBaseHL2MPCombatWeapon);

  CWeaponMyFirstWeapon(void);

  DECLARE_NETWORKCLASS();
  DECLARE_PREDICTABLE();

The code above just starts off the file, makes so it works with the server, and creates the base for the constructor.

Creating The Functions

After the line that says DEALRE_PREDICTABLE, type these functions in

void Precache(void);
void ItemPreFrame(void);
void ItemBusyFrame(void);
void ItemPostFrame(void);
void PrimaryAttack(void);
void AddViewKick(void);

Activity GetPrimaryAttackActivity(void);

virtual bool Reload(void);

virtual const Vector& GetBulletSpread(void)
{
    static Vector cone = VECTOR_CONE_1DEGREES;
    return cone;
}

#ifndef CLIENT_DLL
    DECLARE_ACTTABLE();
#endif

All this does is create stubs for the functions we will define later, with the exception of GetBulletSpread. To understand all of the functions, see Authoring a weapon entity, but the same things will be described later.

Creating Private Code

In this section, the reader will learn how to create variables, so they can be networked. To start off the private section, type

private:
    CNetworkVar(int, m_iTest);

private:
    CWeaponMyFirstWeapon(const CWeaponMyFirstWeapon &);

Basically, this just creates a variable, with the type of a int, called m_iTest, and then this code creates an alternate constructor. How we will change the value of m_iTest will be discussed later. If your getting an error now just ignore that. You can also create this same variable at the top, with a #define.

#define m_iTest 1

Just make sure to delete this instance under the private:

Defining The Functions

Now, go out of the braces for the CWeaponMyFirstWeapon class. Next, type

IMPLEMENT_NETWORKCLASS_ALIASED(WeaponMyFirstWeapon, DT_WeaponMyFirstWeapon)

BEGIN_NETWORK_TABLE(CWeaponMyFirstWeapon, DT_WeaponMyFirstWeapon)
#ifndef CLIENT_DLL
RecvPropFloat(RECVINFO(m_flRateOfFire)),
#else
SendPropFloat(SENDINFO(m_flRateOfFire)),
#endif

This code just defines how things will be networked, and what things will be networked. Moving on, to create the weapons entity, type

LINK_ENTITY_TO_CLASS(weapon_myfirstweapon, CWeaponMyFirstWeapon);
PRECACHE_WEAPON_REGISTER(weapon_myfirstweapon); //This defines what the weapon script we make later will be called

Now, to declare the acttable. This is not very important, it just defines what animations to use, and in this case we are using the pistol animations. For more information, check out the docs on the acttable.

#ifndef CLIENT_DLL
acttable_t CWeaponMyFirstWeapon::m_acttable[] =
{
	{ ACT_HL2MP_IDLE, ACT_HL2MP_IDLE_PISTOL, false },
	{ ACT_HL2MP_RUN, ACT_HL2MP_RUN_PISTOL, false },
	{ ACT_HL2MP_IDLE_CROUCH, ACT_HL2MP_IDLE_CROUCH_PISTOL, false },
	{ ACT_HL2MP_WALK_CROUCH, ACT_HL2MP_WALK_CROUCH_PISTOL, false },
	{ ACT_HL2MP_GESTURE_RANGE_ATTACK, ACT_HL2MP_GESTURE_RANGE_ATTACK_PISTOL, false },
	{ ACT_HL2MP_GESTURE_RELOAD, ACT_HL2MP_GESTURE_RELOAD_PISTOL, false },
	{ ACT_HL2MP_JUMP, ACT_HL2MP_JUMP_PISTOL, false },
	{ ACT_RANGE_ATTACK1, ACT_RANGE_ATTACK_PISTOL, false },
};

IMPLEMENT_ACTTABLE(CWeaponMyFirstWeapon);

#endif

And now, the moment you've all been waiting for, the functions!

CWeaponMyFirstWeapon::CWeaponMyFirstWeapon(void)
{
    m_fMinRange1 = 24;
    m_fMaxRange1 = 1500;
    m_fMinRange2 = 24;
    m_fMaxRange2 = 200;

    m_bFiresUnderwater = true;

    m_iTest = 1;
}

This is the constructor. This is called whenever the weapon is first created. As you can see here, it just defines the minimum range, and the maximum range for the weapon. Then, it just says the weapon can be fired underwater, and finally, the value of the m_iTest is set to 1. Moving on, now we will create the precache function.

void CWeaponMyFirstWeapon::Precache(void)
{
	BaseClass::Precache();
}

So, this is called even before the item is created. Basically, it just caches all the needed resources. Now, on to the next function!

void CWeaponMyFirstWeapon::ItemPreFrame(void) {
	BaseClass::ItemPreFrame();
}

This is called before the has moved, or in other words it is executed before the player movement function.