Adding Weapon Inspect: Difference between revisions

From Valve Developer Community
Jump to navigation Jump to search
m (Added this tutorial to the "tutorials" and "weapons programming" categories + minor spelling fixes)
Line 8: Line 8:
== In_Buttons.h==
== In_Buttons.h==


define IN_INSPECT in the in_buttons.h
Define IN_INSPECT in the in_buttons.h
increment up or down the number on the right side of the bitwise operation.
increment up or down the number on the right side of the bitwise operation.


Line 15: Line 15:
</source>
</source>


The final should be something like this.
The result should be something like this.


<source lang=cpp>
<source lang=cpp>
Line 60: Line 60:
== IN_MAIN.CPP==
== IN_MAIN.CPP==


Next Open in_main.cpp
Next, Open in_main.cpp and find:


<source lang=cpp>
<source lang=cpp>
static    kbutton_t   in_inspect;
kbutton_t in_ducktoggle;
</source>
</source>


put the above below this line in in_main.cpp
And put this below it
 
<source lang=cpp>
<source lang=cpp>
 
static    kbutton_t   in_inspect;
kbutton_t in_ducktoggle;
</source>
</source>


Line 77: Line 77:
</source>
</source>


and put this after it
And put this after it


<source lang=cpp>
<source lang=cpp>
Line 89: Line 89:
</source>
</source>


and put below it:
And put below it:
<source lang=cpp>
<source lang=cpp>
CalcButtonBits(bits, IN_INSPECT, s_ClearInputState, &in_inspect, bResetState);
CalcButtonBits(bits, IN_INSPECT, s_ClearInputState, &in_inspect, bResetState);
Line 99: Line 99:
</source>
</source>


Now put the follow below that line.
Now put the following below that line.
<source lang-cpp>
<source lang=cpp>
static ConCommand startinspect("+inspect", IN_InspectDown);
static ConCommand startinspect("+inspect", IN_InspectDown);
static ConCommand endinspect("-inspect", IN_InspectUp);
static ConCommand endinspect("-inspect", IN_InspectUp);
Line 111: Line 111:
Open ai_activity.h
Open ai_activity.h


Find the follow:
Find the following:
<source lang=cpp>
<source lang=cpp>
// Inspect
// Inspect
Line 128: Line 128:


If you do not find them go to
If you do not find them go to
<source lang=cpp>
<source lang=cpp>
ACT_VM_DRAW_DEPLOYED
ACT_VM_DRAW_DEPLOYED
</source>
</source>


and put them under it.
And put them under it.


==ai_activity.cpp==
==ai_activity.cpp==
Line 138: Line 139:
Go to InitDefaultActivitySR
Go to InitDefaultActivitySR


try to find:
Try to find:
<source lang=cpp>
<source lang=cpp>
ACT_PRIMARY_VM_INSPECT_START
ACT_PRIMARY_VM_INSPECT_START
</source>
</source>


if you do not have them already add the following:
If you do not have them already add the following:
<source lang=cpp>
<source lang=cpp>


Line 189: Line 190:


==hl2mp_player.h==
==hl2mp_player.h==
open hl2mp_player.h and add the following in CHL2MP_Player under the public area of the class.
Open hl2mp_player.h and add the following in CHL2MP_Player under the public area of the class.
<source lang=cpp>
<source lang=cpp>
void InspectButtonPressed(void);
void InspectButtonPressed(void);
Line 227: Line 228:
</source>
</source>


then somewhere in the function(doesn't matter I don't think) add the following:
Then somewhere in the function (doesn't matter I don't think) add the following:
<source lang=cpp>
<source lang=cpp>
if (m_afButtonPressed & IN_INSPECT)
if (m_afButtonPressed & IN_INSPECT)
Line 239: Line 240:


==weapon_hl2mpbase.h==
==weapon_hl2mpbase.h==
open weapon_hl2mpbase.h and in the class CWeaponHL2MPBase under public add:
Open weapon_hl2mpbase.h and in the class CWeaponHL2MPBase under public add:
<source lang=cpp>
<source lang=cpp>
CNetworkVar(int, m_nInspectStage);
CNetworkVar(int, m_nInspectStage);
Line 256: Line 257:


Now open weapon_hl2mpbase.cpp.
Now open weapon_hl2mpbase.cpp.
After  
After:
<source lang=cpp>
<source lang=cpp>
#include "weapon_hl2mpbase.h"
#include "weapon_hl2mpbase.h"
</source>
</source>


add the following:
Add the following:
<source lang=cpp>
<source lang=cpp>
#ifndef CLIENT_DLL
#ifndef CLIENT_DLL
Line 290: Line 291:
</source>
</source>


add the following after DT_LocalActiveWeaponData
Add the following after DT_LocalActiveWeaponData
<source lang=cpp>
<source lang=cpp>
SendPropInt(SENDINFO(m_nInspectStage), 3, SPROP_UNSIGNED),
SendPropInt(SENDINFO(m_nInspectStage), 3, SPROP_UNSIGNED),
</source>
</source>


under #ifdef CLIENT_DLL Add the following:
Under #ifdef CLIENT_DLL Add the following:
<source lang=cpp>
<source lang=cpp>
RecvPropInt(RECVINFO(m_nInspectStage)),
RecvPropInt(RECVINFO(m_nInspectStage)),
Line 430: Line 431:
==Adding the ability for a weapon to use inspect==
==Adding the ability for a weapon to use inspect==


open all the weapons to add Inspect too.
Open all the weapons you want to add an Inspect to.


If weapon has a ItemPostFrame
If the weapon has an ItemPostFrame


Add this near the top of the function:
Add this near the top of the function:
Line 454: Line 455:
</source>
</source>


If you do not have a ItemPostFrame for the weapon you will need to make a override function add the above and call the Baseclass::ItemPostFrame
If you do not have an ItemPostFrame for the weapon you will need to make an override function, add the above, and call the Baseclass::ItemPostFrame
 
You should now have Weapon Inspecting.


You now should have Weapon Inspecting.
[[Category:Weapons programming]]
[[Category:Tutorials]]

Revision as of 13:41, 2 October 2023

Adding Weapon Inspect

  • This will cover specifically adding weapon inspecting to the source 2013 MP code
  • What this wont cover is implementing weapon type enumerations for weapons that was ported from the 2007 SDK.
  • Adding enumerations for weapons, and adding new activities in the QC file of a weapons model is out of scope in this tutorial.

In_Buttons.h

Define IN_INSPECT in the in_buttons.h increment up or down the number on the right side of the bitwise operation.

#define    IN_INSPECT        (1 << 26)

The result should be something like this.

#ifndef IN_BUTTONS_H
#define IN_BUTTONS_H
#ifdef _WIN32
#pragma once
#endif

#define IN_ATTACK		(1 << 0)
#define IN_JUMP			(1 << 1)
#define IN_DUCK			(1 << 2)
#define IN_FORWARD		(1 << 3)
#define IN_BACK			(1 << 4)
#define IN_USE			(1 << 5)
#define IN_CANCEL		(1 << 6)
#define IN_LEFT			(1 << 7)
#define IN_RIGHT		(1 << 8)
#define IN_MOVELEFT		(1 << 9)
#define IN_MOVERIGHT	(1 << 10)
#define IN_ATTACK2		(1 << 11)
#define IN_RUN			(1 << 12)
#define IN_RELOAD		(1 << 13)
#define IN_ALT1			(1 << 14)
#define IN_ALT2			(1 << 15)
#define IN_SCORE		(1 << 16)   // Used by client.dll for when scoreboard is held down
#define IN_SPEED		(1 << 17)	// Player is holding the speed key
#define IN_WALK			(1 << 18)	// Player holding walk key
#define IN_ZOOM			(1 << 19)	// Zoom key for HUD zoom
#define IN_WEAPON1		(1 << 20)	// weapon defines these bits
#define IN_WEAPON2		(1 << 21)	// weapon defines these bits
#define IN_BULLRUSH		(1 << 22)
#define IN_GRENADE1		(1 << 23)	// grenade 1
#define IN_GRENADE2		(1 << 24)	// grenade 2
#define	IN_ATTACK3		(1 << 25)
#define	IN_INSPECT		(1 << 26)

#endif // IN_BUTTONS_H


IN_MAIN.CPP

Next, Open in_main.cpp and find:

kbutton_t	in_ducktoggle;

And put this below it

static    kbutton_t    in_inspect;

Next go to

void IN_Attack3Up( const CCommand &args ) { KeyUp(&in_attack3, args[1] );}

And put this after it

void IN_InspectDown(const CCommand& args) { KeyDown(&in_inspect, args[1]); }
void IN_InspectUp(const CCommand& args) { KeyUp(&in_inspect, args[1]); }

Next find

CalcButtonBits( bits, IN_ATTACK3, s_ClearInputState, &in_attack3, bResetState );

And put below it:

CalcButtonBits(bits, IN_INSPECT, s_ClearInputState, &in_inspect, bResetState);

Next find:

static ConCommand endattack3("-attack3", IN_Attack3Up);

Now put the following below that line.

static ConCommand startinspect("+inspect", IN_InspectDown);
static ConCommand endinspect("-inspect", IN_InspectUp);

That is all for in_main.cpp.

Implementing the activities.

Open ai_activity.h

Find the following:

// Inspect
ACT_PRIMARY_VM_INSPECT_START,
ACT_PRIMARY_VM_INSPECT_IDLE,
ACT_PRIMARY_VM_INSPECT_END,

ACT_SECONDARY_VM_INSPECT_START,
ACT_SECONDARY_VM_INSPECT_IDLE,
ACT_SECONDARY_VM_INSPECT_END,

ACT_MELEE_VM_INSPECT_START,
ACT_MELEE_VM_INSPECT_IDLE,
ACT_MELEE_VM_INSPECT_END,

If you do not find them go to

ACT_VM_DRAW_DEPLOYED

And put them under it.

ai_activity.cpp

Go to InitDefaultActivitySR

Try to find:

ACT_PRIMARY_VM_INSPECT_START

If you do not have them already add the following:

ADD_ACTIVITY_TO_SR( ACT_PRIMARY_VM_INSPECT_START );
ADD_ACTIVITY_TO_SR( ACT_PRIMARY_VM_INSPECT_IDLE );
ADD_ACTIVITY_TO_SR( ACT_PRIMARY_VM_INSPECT_END );

ADD_ACTIVITY_TO_SR( ACT_SECONDARY_VM_INSPECT_START );
ADD_ACTIVITY_TO_SR( ACT_SECONDARY_VM_INSPECT_IDLE );
ADD_ACTIVITY_TO_SR( ACT_SECONDARY_VM_INSPECT_END );

ADD_ACTIVITY_TO_SR( ACT_MELEE_VM_INSPECT_START );
ADD_ACTIVITY_TO_SR( ACT_MELEE_VM_INSPECT_IDLE );
ADD_ACTIVITY_TO_SR( ACT_MELEE_VM_INSPECT_END );

activitylist.cpp

open activitylist.cpp and find:

ActivityList_RegisterSharedActivities

Then inside that function find:

ACT_PRIMARY_VM_INSPECT_START

If not already there add the following:

REGISTER_SHARED_ACTIVITY( ACT_PRIMARY_VM_INSPECT_START );
REGISTER_SHARED_ACTIVITY( ACT_PRIMARY_VM_INSPECT_IDLE );
REGISTER_SHARED_ACTIVITY( ACT_PRIMARY_VM_INSPECT_END );

REGISTER_SHARED_ACTIVITY( ACT_SECONDARY_VM_INSPECT_START );
REGISTER_SHARED_ACTIVITY( ACT_SECONDARY_VM_INSPECT_IDLE );
REGISTER_SHARED_ACTIVITY( ACT_SECONDARY_VM_INSPECT_END );

REGISTER_SHARED_ACTIVITY( ACT_MELEE_VM_INSPECT_START );
REGISTER_SHARED_ACTIVITY( ACT_MELEE_VM_INSPECT_IDLE );
REGISTER_SHARED_ACTIVITY( ACT_MELEE_VM_INSPECT_END );

That is all for the activities. Note: these should be there already in 2013 mp.

hl2mp_player.h

Open hl2mp_player.h and add the following in CHL2MP_Player under the public area of the class.

void			InspectButtonPressed(void);
void			InspectButtonReleased(void);

bool			IsInspecting(void) const;

hl2mp_player.cpp

Now open hl2mp_player.cpp and add:

bool  CHL2MP_Player::IsInspecting(void) const
{
	if (m_nButtons & IN_INSPECT)
		return true;

	return false;
}

void CHL2MP_Player::InspectButtonPressed(void)
{
	if (!FlashlightIsOn())
		FlashlightTurnOn();
	else
		FlashlightTurnOff();
}

void CHL2MP_Player::InspectButtonReleased(void)
{
}

Now find:

CHL2MP_Player::PreThink

Then somewhere in the function (doesn't matter I don't think) add the following:

if (m_afButtonPressed & IN_INSPECT)
	InspectButtonPressed();

if (m_afButtonReleased & IN_INSPECT)
	 InspectButtonReleased();

That should be all for hl2mp_player.

weapon_hl2mpbase.h

Open weapon_hl2mpbase.h and in the class CWeaponHL2MPBase under public add:

CNetworkVar(int, m_nInspectStage);
CNetworkVar(float, m_flInspectAnimEndTime);

virtual bool		CanInspect(void) const { return true; }

virtual void HandleInspect(void);

int GetInspectActivity(void);

int GetActivityWeaponRole(void);

weapon_hl2mpbase.cpp

Now open weapon_hl2mpbase.cpp. After:

#include "weapon_hl2mpbase.h"

Add the following:

#ifndef CLIENT_DLL
#include "hl2mp_player.h"
#endif

In this section:

// ----------------------------------------------------------------------------- //
// CWeaponHL2MPBase tables.
// ----------------------------------------------------------------------------- //

IMPLEMENT_NETWORKCLASS_ALIASED( WeaponHL2MPBase, DT_WeaponHL2MPBase )

BEGIN_NETWORK_TABLE( CWeaponHL2MPBase, DT_WeaponHL2MPBase )

#ifdef CLIENT_DLL
  
#else
	// world weapon models have no aminations
  //	SendPropExclude( "DT_AnimTimeMustBeFirst", "m_flAnimTime" ),
//	SendPropExclude( "DT_BaseAnimating", "m_nSequence" ),
//	SendPropExclude( "DT_LocalActiveWeaponData", "m_flTimeWeaponIdle" ),
#endif
	
END_NETWORK_TABLE()

Add the following after DT_LocalActiveWeaponData

SendPropInt(SENDINFO(m_nInspectStage), 3, SPROP_UNSIGNED),

Under #ifdef CLIENT_DLL Add the following:

RecvPropInt(RECVINFO(m_nInspectStage)),

Now in the contructor CWeaponHL2MPBase() Add the following:

m_nInspectStage = 0;
m_flInspectAnimEndTime = 0;

Add the following functions to the code:

/-----------------------------------------------------------------------------
// Purpose: 
//-----------------------------------------------------------------------------
void CWeaponHL2MPBase::HandleInspect(void)
{
	CHL2MP_Player* pOwner = ToHL2MPPlayer(GetOwner());
	if (!pOwner)
		return;

	if (m_nInspectStage >= 3)
	{
		m_nInspectStage = 0;
		return;
	}

	if (m_nInspectStage == 0)
	{
		SendWeaponAnim(GetInspectActivity());
		m_flInspectAnimEndTime = SequenceDuration();
	}
	else if (m_nInspectStage == 1)
	{
		SendWeaponAnim(GetInspectActivity());
		m_flInspectAnimEndTime = SequenceDuration();
	}
	else if (m_nInspectStage == 2)
	{
		SendWeaponAnim(GetInspectActivity());
	}

	if (m_flInspectAnimEndTime > gpGlobals->curtime)
	{
		if (m_nInspectStage == 0)
			m_nInspectStage = 1;
		else if (m_nInspectStage == 1)
			m_nInspectStage = 1;
	}
}

// -----------------------------------------------------------------------------
// Purpose:
// -----------------------------------------------------------------------------
int CWeaponHL2MPBase::GetActivityWeaponRole(void)
{
	int iWeaponRole = GetWeaponID();

	return iWeaponRole;
}

// -----------------------------------------------------------------------------
// Purpose:
// -----------------------------------------------------------------------------
int CWeaponHL2MPBase::GetInspectActivity(void)
{
	CHL2MP_Player* pOwner = ToHL2MPPlayer(GetOwner());
	if (!pOwner)
		return ACT_PRIMARY_VM_INSPECT_START;

	int iActivity = ACT_PRIMARY_VM_INSPECT_START;

	switch (GetActivityWeaponRole())
	{
	case WEAPON_SHOTGUN:
	default:
		if (m_nInspectStage == 1)
			iActivity = ACT_PRIMARY_VM_INSPECT_START;
		else if (m_nInspectStage == 2)
			iActivity = ACT_PRIMARY_VM_INSPECT_END;
		else
			iActivity = ACT_PRIMARY_VM_INSPECT_IDLE;
		break;
	case WEAPON_CROSSBOW:
		if (m_nInspectStage == 1)
			iActivity = ACT_SECONDARY_VM_INSPECT_START;
		else if (m_nInspectStage == 2)
			iActivity = ACT_SECONDARY_VM_INSPECT_END;
		else
			iActivity = ACT_SECONDARY_VM_INSPECT_IDLE;
		break;
	case WEAPON_CROWBAR:
		if (m_nInspectStage == 1)
			iActivity = ACT_MELEE_VM_INSPECT_START;
		else if (m_nInspectStage == 2)
			iActivity = ACT_MELEE_VM_INSPECT_END;
		else
			iActivity = ACT_MELEE_VM_INSPECT_IDLE;
		break;
	case WEAPON_PHYSCANNON:
		if (m_nInspectStage == 1)
			iActivity = ACT_PRIMARY_VM_INSPECT_START;
		else if (m_nInspectStage == 2)
			iActivity = ACT_PRIMARY_VM_INSPECT_END;
		else
			iActivity = ACT_PRIMARY_VM_INSPECT_IDLE;
		break;
	case WEAPON_PYTHON357:
		if (m_nInspectStage == 1)
			iActivity = ACT_SECONDARY_VM_INSPECT_START;
		else if (m_nInspectStage == 2)
			iActivity = ACT_SECONDARY_VM_INSPECT_END;
		else
			iActivity = ACT_SECONDARY_VM_INSPECT_IDLE;
		break;

	case WEAPON_RPG:
		if (m_nInspectStage == 1)
			iActivity = ACT_PRIMARY_VM_INSPECT_START;
		else if (m_nInspectStage == 2)
			iActivity = ACT_PRIMARY_VM_INSPECT_END;
		else
			iActivity = ACT_PRIMARY_VM_INSPECT_IDLE;
		break;
	}

	return iActivity;
}

Note: for each weapon you will need to have a case for it, and its own enum weapon type it returns.

Adding the ability for a weapon to use inspect

Open all the weapons you want to add an Inspect to.

If the weapon has an ItemPostFrame

Add this near the top of the function:

//Note: you do not need this pOwner if you have it already.
CBasePlayer *pOwner = ToBasePlayer( GetOwner() );
	if (!pOwner)
	{
		return;
	}
	

if (CanInspect())
{
	if (pOwner->m_afButtonPressed & IN_INSPECT)
		HandleInspect();

	if (pOwner->m_afButtonReleased & IN_INSPECT)
		m_nInspectStage = 2;
}

If you do not have an ItemPostFrame for the weapon you will need to make an override function, add the above, and call the Baseclass::ItemPostFrame

You should now have Weapon Inspecting.