Adding Weapon Inspect

From Valve Developer Community
Revision as of 18:42, 7 October 2020 by Anthonypython (talk | contribs) (weapon_hl2mpbase.cpp)
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to: navigation, search

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 final 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

static    kbutton_t    in_inspect;

put the above below this line in in_main.cpp

kbutton_t	in_ducktoggle;

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 follow 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 follow:

// 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:

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

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_hl2mbase.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 to add Inspect too.

If weapon has a 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 a ItemPostFrame for the weapon you will need to make a override function add the above and call the Baseclass::ItemPostFrame

You now should have Weapon Inspecting.