Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

(Half-Life/Opposing Force) Show pickup icons in HUD for all weapons #3137

Open
WinNT50 opened this issue Sep 4, 2021 · 1 comment
Open

Comments

@WinNT50
Copy link

WinNT50 commented Sep 4, 2021

Normally, GoldSource games display notification icons when picking up certain weapons, like these:
20210904061658_1

However, these icons never show for picking up crowbar, wrench, knife, or pistol, both in single player and deathmatch.

Would be nice to see them for these weapons too, as some maps don't give them by default and this makes orientation in game world a bit easier. Also handy when picking up dropped backpacks.

@SamVanheer
Copy link

SamVanheer commented Mar 1, 2022

I suspect the reason why they don't show pickup icons for those weapons is because you spawn with the crowbar and pistol in Half-Life multiplayer, and in Opposing Force CTF you start with the wrench and desert eagle.

To stop you from seeing the pickup icons on spawn they disabled that.

The code can be reworked to do both:

In util.h add this to the end of the file:

/**
*	@brief Helper type to run a function when the helper is destroyed.
*	Useful for running cleanup on scope exit and function return.
*/
template<typename Func>
struct CallOnDestroy
{
	const Func Function;

	explicit CallOnDestroy(Func&& function)
		: Function(function)
	{
	}

	~CallOnDestroy()
	{
		Function();
	}
};

At the end of the CBasePlayer class definition here:

halflife/dlls/player.h

Lines 324 to 326 in c7240b9

float m_flNextChatTime;
};

Add this:

public:
//True if the player is currently spawning.
bool m_bIsSpawning = false;

At the start of this function:

halflife/dlls/player.cpp

Lines 2850 to 2852 in c7240b9

void CBasePlayer::Spawn( void )
{
pev->classname = MAKE_STRING("player");

Add this (requires C++11 or newer):

m_bIsSpawning = true;

//Make sure this gets reset even if somebody adds an early return or throws an exception.
const CallOnDestroy resetIsSpawning{[this]()
	{
		//Done spawning; reset.
		m_bIsSpawning = false;
	}
};

Modify this function:

halflife/dlls/weapons.cpp

Lines 792 to 808 in c7240b9

int CBasePlayerWeapon::AddToPlayer( CBasePlayer *pPlayer )
{
int bResult = CBasePlayerItem::AddToPlayer( pPlayer );
pPlayer->pev->weapons |= (1<<m_iId);
if ( !m_iPrimaryAmmoType )
{
m_iPrimaryAmmoType = pPlayer->GetAmmoIndex( pszAmmo1() );
m_iSecondaryAmmoType = pPlayer->GetAmmoIndex( pszAmmo2() );
}
if (bResult)
return AddWeapon( );
return FALSE;
}

To look like this:

bool CBasePlayerWeapon::AddToPlayer(CBasePlayer* pPlayer)
{
	int bResult = CBasePlayerItem::AddToPlayer(pPlayer);

	pPlayer->pev->weapons |= (1<<m_iId);

	if (!m_iPrimaryAmmoType)
	{
		m_iPrimaryAmmoType = pPlayer->GetAmmoIndex(pszAmmo1());
		m_iSecondaryAmmoType = pPlayer->GetAmmoIndex(pszAmmo2());
	}

	if (!bResult)
	{
		return FALSE;
	}

	if (!AddWeapon())
	{
		return FALSE;
	}

	//Don't show weapon pickup if we're spawning or if it's an exhaustible weapon (will show ammo pickup instead).
	if (!m_pPlayer->m_bIsSpawning && (iFlags() & ITEM_FLAG_EXHAUSTIBLE) == 0)
	{
		MESSAGE_BEGIN(MSG_ONE, gmsgWeapPickup, NULL, pPlayer->pev);
		WRITE_BYTE(m_iId);
		MESSAGE_END();
	}

	return TRUE;
}

Remove the AddToPlayer function from all weapon classes except CHgun and CSatchel. Those two need to be modified.

Modify this function:

int CHgun::AddToPlayer( CBasePlayer *pPlayer )
{
if ( CBasePlayerWeapon::AddToPlayer( pPlayer ) )
{
#ifndef CLIENT_DLL
if ( g_pGameRules->IsMultiplayer() )
{
// in multiplayer, all hivehands come full.
pPlayer->m_rgAmmo[ PrimaryAmmoIndex() ] = HORNET_MAX_CARRY;
}
#endif
MESSAGE_BEGIN( MSG_ONE, gmsgWeapPickup, NULL, pPlayer->pev );
WRITE_BYTE( m_iId );
MESSAGE_END();
return TRUE;
}
return FALSE;
}

To look like this:

int CHgun::AddToPlayer(CBasePlayer* pPlayer)
{
#ifndef CLIENT_DLL
	if (g_pGameRules->IsMultiplayer())
	{
		// in multiplayer, all hivehands come full.
		m_iDefaultAmmo = HORNET_MAX_CARRY;
	}
#endif

	return CBasePlayerWeapon::AddToPlayer(pPlayer);
}

Modify this function:

halflife/dlls/satchel.cpp

Lines 201 to 213 in c7240b9

int CSatchel::AddToPlayer( CBasePlayer *pPlayer )
{
int bResult = CBasePlayerItem::AddToPlayer( pPlayer );
pPlayer->pev->weapons |= (1<<m_iId);
m_chargeReady = 0;// this satchel charge weapon now forgets that any satchels are deployed by it.
if ( bResult )
{
return AddWeapon( );
}
return FALSE;
}

To look like this:

int CSatchel::AddToPlayer(CBasePlayer* pPlayer)
{
	m_chargeReady = 0; // this satchel charge weapon now forgets that any satchels are deployed by it.
	return CBasePlayerWeapon::AddToPlayer(pPlayer);
}

The changes made to the player class allows code to know if the player is currently spawning.

The changes made to the weapon base class lets the base class handle the weapon pickup logic. It'll tell the HUD to show the pickup if the player isn't spawning (weapons given on spawn will not show up as a pickup) and if it's not an exhaustible weapon.

Exhaustible weapons are the hand grenade, satchel charge, tripmine and Snark grenade. They don't currently show up as weapon pickups, only as ammo pickups so this behavior is consistent with what it was before.

The changes made to the Hornet gun code ensures the weapon always has ammo when picked up, even if another player emptied it before dropping it. This was the original behavior, now done in a slightly different way that results in the same behavior.

The changes made to the Satchel charge code ensures the weapon forgets about deployed satchels as before, only now it doesn't skip the CBasePlayerWeapon version of AddToPlayer. This fixes a minor issue where m_iPrimaryAmmoType isn't initialized and ensures consistency with all other weapons in calling the correct version of the function. It also gets rid of a minor case of code duplication (the AddWeapon part).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants