Skip to content

[TF2] Improve ammo display on target ID #1212

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

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 13 additions & 3 deletions src/game/client/tf/c_tf_player.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3695,6 +3695,7 @@ END_RECV_TABLE()
//-----------------------------------------------------------------------------
BEGIN_RECV_TABLE_NOBASE( C_TFPlayer, DT_TFSendHealersDataTable )
RecvPropInt( RECVINFO( m_nActiveWpnClip ) ),
RecvPropInt( RECVINFO( m_nActiveWpnReserve ) ),
END_RECV_TABLE()

IMPLEMENT_CLIENTCLASS_DT( C_TFPlayer, DT_TFPlayer, CTFPlayer )
Expand Down Expand Up @@ -9724,14 +9725,23 @@ void C_TFPlayer::GetTargetIDDataString( bool bIsDisguised, OUT_Z_BYTECAP(iMaxLen
}

// Show target's clip state to attached medics
if ( !sDataString[0] && m_nActiveWpnClip >= 0 )
if ( !sDataString[0] && m_nActiveWpnClip != UINT16_MAX )
{
C_TFPlayer *pTFHealTarget = ToTFPlayer( pLocalPlayer->MedicGetHealTarget() );
if ( pTFHealTarget && pTFHealTarget == this )
{
wchar_t wszClip[10];
V_snwprintf( wszClip, ARRAYSIZE(wszClip) - 1, L"%d", m_nActiveWpnClip );
g_pVGuiLocalize->ConstructString( sDataString, iMaxLenInBytes, g_pVGuiLocalize->Find( "#TF_playerid_ammo" ), 1, wszClip );
V_snwprintf( wszClip, ARRAYSIZE( wszClip ) - 1, L"%d", m_nActiveWpnClip );
if ( m_nActiveWpnReserve != UINT16_MAX )
{
wchar_t wszReserve[10];
V_snwprintf( wszReserve, ARRAYSIZE( wszReserve ) - 1, L"%d", m_nActiveWpnReserve );
g_pVGuiLocalize->ConstructString( sDataString, iMaxLenInBytes, g_pVGuiLocalize->Find( "#TF_playerid_ammo_reserve" ), 2, wszClip, wszReserve );
}
else
{
g_pVGuiLocalize->ConstructString( sDataString, iMaxLenInBytes, g_pVGuiLocalize->Find("#TF_playerid_ammo" ), 1, wszClip );
}
bIsAmmoData = true;
}
}
Expand Down
1 change: 1 addition & 0 deletions src/game/client/tf/c_tf_player.h
Original file line number Diff line number Diff line change
Expand Up @@ -874,6 +874,7 @@ class C_TFPlayer : public C_BasePlayer, public IHasAttributes, public IInventory

// Medic healtarget active weapon ammo/clip count
uint16 m_nActiveWpnClip;
uint16 m_nActiveWpnReserve;

// Blast jump whistle
CSoundPatch *m_pBlastJumpLoop;
Expand Down
31 changes: 21 additions & 10 deletions src/game/server/tf/tf_player.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -613,6 +613,8 @@ BEGIN_ENT_SCRIPTDESC( CTFPlayer, CBaseMultiplayerPlayer , "Team Fortress 2 Playe
DEFINE_SCRIPTFUNC_NAMED( ScriptIsImmuneToPushback, "IsImmuneToPushback", "" )
DEFINE_SCRIPTFUNC_NAMED( ScriptGetDisguiseAmmoCount, "GetDisguiseAmmoCount", "" )
DEFINE_SCRIPTFUNC_NAMED( ScriptSetDisguiseAmmoCount, "SetDisguiseAmmoCount", "" )
DEFINE_SCRIPTFUNC_NAMED( ScriptGetDisguiseAmmoReserveCount, "GetDisguiseAmmoReserveCount", "" )
DEFINE_SCRIPTFUNC_NAMED( ScriptSetDisguiseAmmoReserveCount, "SetDisguiseAmmoReserveCount", "" )
DEFINE_SCRIPTFUNC_NAMED( ScriptGetDisguiseTeam, "GetDisguiseTeam", "" )
DEFINE_SCRIPTFUNC_NAMED( ScriptIsFullyInvisible, "IsFullyInvisible", "" )
DEFINE_SCRIPTFUNC_NAMED( ScriptGetSpyCloakMeter, "GetSpyCloakMeter", "" )
Expand Down Expand Up @@ -756,7 +758,8 @@ END_SEND_TABLE()
// Purpose: Sent to attached medics
//-----------------------------------------------------------------------------
BEGIN_SEND_TABLE_NOBASE( CTFPlayer, DT_TFSendHealersDataTable )
SendPropInt( SENDINFO( m_nActiveWpnClip ), -1, SPROP_VARINT | SPROP_UNSIGNED ),
SendPropInt( SENDINFO( m_nActiveWpnClip ), 0, SPROP_VARINT | SPROP_UNSIGNED ),
SendPropInt( SENDINFO( m_nActiveWpnReserve ), 0, SPROP_VARINT | SPROP_UNSIGNED ),
END_SEND_TABLE()

//============
Expand Down Expand Up @@ -1058,7 +1061,9 @@ CTFPlayer::CTFPlayer()
ResetDamagePerSecond();

m_nActiveWpnClip.Set( 0 );
m_nActiveWpnReserve.Set( 0 );
m_nActiveWpnClipPrev = 0;
m_nActiveWpnReservePrev = 0;
m_flNextClipSendTime = 0;

m_nCanPurchaseUpgradesCount = 0;
Expand Down Expand Up @@ -1626,26 +1631,32 @@ void CTFPlayer::TFPlayerThink()
CTFWeaponBase *pTFWeapon = GetActiveTFWeapon();
if ( pTFWeapon )
{
int nClip = 0;
int nClip = UINT16_MAX, nReserve = UINT16_MAX;

if ( m_Shared.InCond( TF_COND_DISGUISED ) )
{
nClip = m_Shared.GetDisguiseAmmoCount();
nReserve = m_Shared.GetDisguiseAmmoReserveCount();
}
else
else if ( pTFWeapon->UsesPrimaryAmmo() )
{
nClip = pTFWeapon->UsesClipsForAmmo1() ? pTFWeapon->Clip1() : GetAmmoCount( pTFWeapon->GetPrimaryAmmoType() );
if ( pTFWeapon->UsesClipsForAmmo1() && !pTFWeapon->IsMeleeWeapon() )
{
nClip = pTFWeapon->Clip1();
nReserve = GetAmmoCount( pTFWeapon->GetPrimaryAmmoType() );
}
else
{
nClip = GetAmmoCount( pTFWeapon->GetPrimaryAmmoType() );
}
}

if ( nClip >= 0 && nClip != m_nActiveWpnClipPrev )
if ( ( nClip != m_nActiveWpnClipPrev ) || ( nReserve != m_nActiveWpnReservePrev ) )
{
if ( nClip > 500 )
{
Warning( "Heal Target: ClipSize Data Limit Exceeded: %d (max 500)\n", nClip );
nClip = MIN( nClip, 500 );
}
m_nActiveWpnClip.Set( nClip );
m_nActiveWpnClipPrev = m_nActiveWpnClip;
m_nActiveWpnReserve.Set( nReserve );
m_nActiveWpnReservePrev = m_nActiveWpnReserve;
m_flNextClipSendTime = gpGlobals->curtime + 0.25f;
}
}
Expand Down
78 changes: 41 additions & 37 deletions src/game/server/tf/tf_player.h
Original file line number Diff line number Diff line change
Expand Up @@ -747,43 +747,45 @@ class CTFPlayer : public CBaseMultiplayerPlayer, public IHasAttributes, public I
void ScriptSetCondDuration( int nCond, float flNewDuration );
HSCRIPT ScriptGetDisguiseTarget();

bool ScriptIsCarryingRune() { return m_Shared.IsCarryingRune(); }

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just whitespace changes?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I added an additional tab spacing past the function declaration to make it look uniform with the two new functions I added, in hindsight this with probably unnecessary and creates confusion when trying to diff this.

bool ScriptIsCritBoosted( void ) const { return m_Shared.IsCritBoosted(); }
bool ScriptIsInvulnerable( void ) const { return m_Shared.IsInvulnerable(); }
bool ScriptIsStealthed( void ) const { return m_Shared.IsStealthed(); }
bool ScriptCanBeDebuffed( void ) const { return m_Shared.CanBeDebuffed(); }
bool ScriptIsImmuneToPushback( void ) const { return m_Shared.IsImmuneToPushback(); }
int ScriptGetDisguiseAmmoCount() { return m_Shared.GetDisguiseAmmoCount(); }
void ScriptSetDisguiseAmmoCount( int nValue ) { return m_Shared.SetDisguiseAmmoCount(nValue); }
int ScriptGetDisguiseTeam() { return m_Shared.GetDisguiseTeam(); }
bool ScriptIsFullyInvisible() { return m_Shared.IsFullyInvisible(); }
float ScriptGetSpyCloakMeter() { return m_Shared.GetSpyCloakMeter(); }
void ScriptSetSpyCloakMeter( float flValue ) { return m_Shared.SetSpyCloakMeter( flValue ); }
bool ScriptIsRageDraining() { return m_Shared.IsRageDraining(); }
float ScriptGetRageMeter() { return m_Shared.GetRageMeter(); }
void ScriptSetRageMeter( float flValue ) { return m_Shared.SetRageMeter( flValue ); }
float ScriptGetScoutHypeMeter() { return m_Shared.GetScoutHypeMeter(); }
void ScriptSetScoutHypeMeter( float flValue ) { return m_Shared.SetScoutHypeMeter( flValue ); }
bool ScriptIsHypeBuffed() { return m_Shared.IsHypeBuffed(); }
bool ScriptIsJumping() { return m_Shared.IsJumping(); }
bool ScriptIsAirDashing() { return m_Shared.IsAirDashing(); }
bool ScriptIsControlStunned() { return m_Shared.IsControlStunned(); }
bool ScriptIsSnared() { return m_Shared.IsSnared(); }
int ScriptGetCaptures() const { return m_Shared.GetCaptures( 0 ); }
int ScriptGetDefenses() const { return m_Shared.GetDefenses( 0 ); }
int ScriptGetDominations() const { return m_Shared.GetDominations( 0 ); }
int ScriptGetRevenge() const { return m_Shared.GetRevenge( 0 ); }
int ScriptGetBuildingsDestroyed() const { return m_Shared.GetBuildingsDestroyed( 0 ); }
int ScriptGetHeadshots() const { return m_Shared.GetHeadshots( 0 ); }
int ScriptGetBackstabs() const { return m_Shared.GetBackstabs( 0 ); }
int ScriptGetHealPoints() const { return m_Shared.GetHealPoints( 0 ); }
int ScriptGetInvulns() const { return m_Shared.GetInvulns( 0 ); }
int ScriptGetTeleports() const { return m_Shared.GetTeleports( 0 ); }
int ScriptGetResupplyPoints() const { return m_Shared.GetResupplyPoints( 0 ); }
int ScriptGetKillAssists() const { return m_Shared.GetKillAssists( 0 ); }
int ScriptGetBonusPoints() const { return m_Shared.GetBonusPoints( 0 ); }
void ScriptResetScores() { m_Shared.ResetScores(); }
bool ScriptIsParachuteEquipped() { return m_Shared.IsParachuteEquipped(); }
bool ScriptIsCarryingRune() { return m_Shared.IsCarryingRune(); }
bool ScriptIsCritBoosted( void ) const { return m_Shared.IsCritBoosted(); }
bool ScriptIsInvulnerable( void ) const { return m_Shared.IsInvulnerable(); }
bool ScriptIsStealthed( void ) const { return m_Shared.IsStealthed(); }
bool ScriptCanBeDebuffed( void ) const { return m_Shared.CanBeDebuffed(); }
bool ScriptIsImmuneToPushback( void ) const { return m_Shared.IsImmuneToPushback(); }
int ScriptGetDisguiseAmmoCount() { return m_Shared.GetDisguiseAmmoCount(); }
void ScriptSetDisguiseAmmoCount( int nValue ) { return m_Shared.SetDisguiseAmmoCount(nValue); }
int ScriptGetDisguiseAmmoReserveCount() { return m_Shared.GetDisguiseAmmoReserveCount(); }
void ScriptSetDisguiseAmmoReserveCount( int nValue ) { return m_Shared.SetDisguiseAmmoReserveCount(nValue); }
int ScriptGetDisguiseTeam() { return m_Shared.GetDisguiseTeam(); }
bool ScriptIsFullyInvisible() { return m_Shared.IsFullyInvisible(); }
float ScriptGetSpyCloakMeter() { return m_Shared.GetSpyCloakMeter(); }
void ScriptSetSpyCloakMeter( float flValue ) { return m_Shared.SetSpyCloakMeter( flValue ); }
bool ScriptIsRageDraining() { return m_Shared.IsRageDraining(); }
float ScriptGetRageMeter() { return m_Shared.GetRageMeter(); }
void ScriptSetRageMeter( float flValue ) { return m_Shared.SetRageMeter( flValue ); }
float ScriptGetScoutHypeMeter() { return m_Shared.GetScoutHypeMeter(); }
void ScriptSetScoutHypeMeter( float flValue ) { return m_Shared.SetScoutHypeMeter( flValue ); }
bool ScriptIsHypeBuffed() { return m_Shared.IsHypeBuffed(); }
bool ScriptIsJumping() { return m_Shared.IsJumping(); }
bool ScriptIsAirDashing() { return m_Shared.IsAirDashing(); }
bool ScriptIsControlStunned() { return m_Shared.IsControlStunned(); }
bool ScriptIsSnared() { return m_Shared.IsSnared(); }
int ScriptGetCaptures() const { return m_Shared.GetCaptures( 0 ); }
int ScriptGetDefenses() const { return m_Shared.GetDefenses( 0 ); }
int ScriptGetDominations() const { return m_Shared.GetDominations( 0 ); }
int ScriptGetRevenge() const { return m_Shared.GetRevenge( 0 ); }
int ScriptGetBuildingsDestroyed() const { return m_Shared.GetBuildingsDestroyed( 0 ); }
int ScriptGetHeadshots() const { return m_Shared.GetHeadshots( 0 ); }
int ScriptGetBackstabs() const { return m_Shared.GetBackstabs( 0 ); }
int ScriptGetHealPoints() const { return m_Shared.GetHealPoints( 0 ); }
int ScriptGetInvulns() const { return m_Shared.GetInvulns( 0 ); }
int ScriptGetTeleports() const { return m_Shared.GetTeleports( 0 ); }
int ScriptGetResupplyPoints() const { return m_Shared.GetResupplyPoints( 0 ); }
int ScriptGetKillAssists() const { return m_Shared.GetKillAssists( 0 ); }
int ScriptGetBonusPoints() const { return m_Shared.GetBonusPoints( 0 ); }
void ScriptResetScores() { m_Shared.ResetScores(); }
bool ScriptIsParachuteEquipped() { return m_Shared.IsParachuteEquipped(); }

int ScriptGetPlayerClass()
{
Expand Down Expand Up @@ -1391,7 +1393,9 @@ class CTFPlayer : public CBaseMultiplayerPlayer, public IHasAttributes, public I
int m_peakDamagePerSecond;

CNetworkVar( uint16, m_nActiveWpnClip );
CNetworkVar( uint16, m_nActiveWpnReserve );
uint16 m_nActiveWpnClipPrev;
uint16 m_nActiveWpnReservePrev;
float m_flNextClipSendTime;

float m_flWaterExitTime;
Expand Down
43 changes: 32 additions & 11 deletions src/game/shared/tf/tf_player_shared.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7231,6 +7231,7 @@ void CTFPlayerShared::OnRemoveDisguised( void )
m_iDisguiseHealth = 0;
SetDisguiseBody( 0 );
m_iDisguiseAmmo = 0;
m_iDisguiseAmmoReserve = 0;

// Update the player model and skin.
m_pOuter->UpdateModel();
Expand Down Expand Up @@ -8477,29 +8478,49 @@ void CTFPlayerShared::DetermineDisguiseWeapon( bool bForcePrimary )


// Ammo/clip state is displayed to attached medics
m_iDisguiseAmmo = 0;
if ( !m_hDisguiseWeapon->IsMeleeWeapon() )
m_iDisguiseAmmo = UINT16_MAX;
m_iDisguiseAmmoReserve = UINT16_MAX;

if ( m_hDisguiseWeapon->UsesPrimaryAmmo() )
{
// Use the player we're disguised as if possible
if ( pDisguiseTarget )
{
CTFWeaponBase *pWeapon = pDisguiseTarget->GetActiveTFWeapon();
if ( pWeapon && pWeapon->GetWeaponID() == m_hDisguiseWeapon->GetWeaponID() )
{
m_iDisguiseAmmo = pWeapon->UsesClipsForAmmo1() ?
pWeapon->Clip1() :
pDisguiseTarget->GetAmmoCount( pWeapon->GetPrimaryAmmoType() );
if ( pWeapon->UsesClipsForAmmo1() && !pWeapon->IsMeleeWeapon() )
{
m_iDisguiseAmmo = pWeapon->Clip1();
m_iDisguiseAmmoReserve = pDisguiseTarget->GetAmmoCount( pWeapon->GetPrimaryAmmoType() );
}
else
{
m_iDisguiseAmmo = pDisguiseTarget->GetAmmoCount( pWeapon->GetPrimaryAmmoType() );
}
}
}

// Otherwise display a faked ammo count
if ( !m_iDisguiseAmmo )
if ( m_iDisguiseAmmo == UINT16_MAX )
{
int nMaxCount = m_hDisguiseWeapon->UsesClipsForAmmo1() ?
m_hDisguiseWeapon->GetMaxClip1() :
m_pOuter->GetMaxAmmo( m_hDisguiseWeapon->GetPrimaryAmmoType(), m_nDisguiseClass );

m_iDisguiseAmmo = (int)random->RandomInt( 1, nMaxCount );
int nMaxAmmo = 0, nMaxReserve = 0;
if ( m_hDisguiseWeapon->UsesClipsForAmmo1() && !m_hDisguiseWeapon->IsMeleeWeapon() )
{
nMaxAmmo = m_hDisguiseWeapon->GetMaxClip1();
nMaxReserve = m_pOuter->GetMaxAmmo( m_hDisguiseWeapon->GetPrimaryAmmoType(), m_nDisguiseClass );
}
else
{
nMaxAmmo = m_pOuter->GetMaxAmmo( m_hDisguiseWeapon->GetPrimaryAmmoType(), m_nDisguiseClass );
}

m_iDisguiseAmmo = (int)random->RandomInt( 1, nMaxAmmo );

if ( nMaxReserve )
{
m_iDisguiseAmmoReserve = (int)random->RandomInt( 1, nMaxReserve );
}
}
}
}
Expand Down
3 changes: 3 additions & 0 deletions src/game/shared/tf/tf_player_shared.h
Original file line number Diff line number Diff line change
Expand Up @@ -389,6 +389,8 @@ class CTFPlayerShared : public CGameEventListener
void ProcessDisguiseImpulse( CTFPlayer *pPlayer );
int GetDisguiseAmmoCount( void ) { return m_iDisguiseAmmo; }
void SetDisguiseAmmoCount( int nValue ) { m_iDisguiseAmmo = nValue; }
int GetDisguiseAmmoReserveCount( void ) { return m_iDisguiseAmmoReserve; }
void SetDisguiseAmmoReserveCount( int nValue ) { m_iDisguiseAmmoReserve = nValue; }

bool CanRecieveMedigunChargeEffect( medigun_charge_types eType ) const;
#ifdef CLIENT_DLL
Expand Down Expand Up @@ -960,6 +962,7 @@ class CTFPlayerShared : public CGameEventListener
CNetworkVar( int, m_nTeamTeleporterUsed ); // for disguised spies using enemy teleporters
CHandle<CTFPlayer> m_hDesiredDisguiseTarget;
int m_iDisguiseAmmo;
int m_iDisguiseAmmoReserve;

bool m_bEnableSeparation; // Keeps separation forces on when player stops moving, but still penetrating
Vector m_vSeparationVelocity; // Velocity used to keep player separate from teammates
Expand Down