// // Think: // Used for selection of weapon menu item. // void CHudAmmo::Think() { if( m_bNeedsLocalUpdate ) { m_bNeedsLocalUpdate = false; if( m_pWeapon ) UpdateWeaponHUD( m_pWeapon, m_bOnTarget ); } if ( gHUD.m_bPlayerDead ) return; CBasePlayer* pPlayer = g_Prediction.GetLocalPlayer(); if ( gHUD.m_iWeaponBits != pPlayer->pev->weapons ) { pPlayer->pev->weapons = gHUD.m_iWeaponBits; for (int i = MAX_WEAPONS-1; i > 0; i-- ) { CBasePlayerWeapon *p = g_Prediction.GetWeapon(i); if ( p && p->GetWeaponInfo() ) { if ( gHUD.m_iWeaponBits & ( 1 << p->GetWeaponInfo()->GetID() ) ) pPlayer->AddPlayerItem( p ); else pPlayer->RemovePlayerItem( p ); } } } if( !m_pActiveSel ) return; // has the player selected one? if (gHUD.m_iKeyBits & IN_ATTACK) { if ( m_pActiveSel != (CBasePlayerWeapon *)1) { ServerCmd( m_pActiveSel->GetWeaponInfo()->GetWeaponName()); g_weaponselect = m_pActiveSel->GetWeaponInfo()->GetID(); } m_pLastSel = m_pActiveSel; m_pActiveSel = nullptr; gHUD.m_iKeyBits &= ~IN_ATTACK; PlaySound("common/wpn_select.wav", 1); } }
// // Draw Weapon Menu // int CHudAmmo::DrawWList(float flTime) { int r,g,b,x,y,a,i; if ( !m_pActiveSel ) return 0; int iActiveSlot; if ( m_pActiveSel == ( CBasePlayerWeapon *)1 ) iActiveSlot = -1; // current slot has no weapons else iActiveSlot = m_pActiveSel->GetWeaponInfo()->GetBucket(); x = 10; //!!! y = 10; //!!! CBasePlayer* pPlayer = g_Prediction.GetLocalPlayer(); // Ensure that there are available choices in the active slot if ( iActiveSlot > 0 ) { if ( !pPlayer->GetFirstPos( iActiveSlot ) ) { m_pActiveSel = ( CBasePlayerWeapon *)1; iActiveSlot = -1; } } // Shepard : determine how many buckets we should draw int iBucketsToDraw = 0; for ( i = 0; i < MAX_WEAPON_SLOTS; i++ ) { for ( int j = 0; j < MAX_WEAPONS; j++ ) { CBasePlayerWeapon *pWeapon = pPlayer->GetWeapon( i, j ); if ( pWeapon && pWeapon->GetWeaponInfo() && pWeapon->GetWeaponInfo()->GetBucket() > iBucketsToDraw ) iBucketsToDraw = pWeapon->GetWeaponInfo()->GetBucket(); } } iBucketsToDraw++; // Draw top line for ( i = 0; i < iBucketsToDraw; i++ ) { int iWidth; gHUD.GetPrimaryColor().UnpackRGB(r,g,b); if ( iActiveSlot == i ) a = 255; else a = 192; ScaleColors(r, g, b, 255); SPR_Set(gHUD.GetSprite(m_HUD_bucket0 + i), r, g, b ); // make active slot wide enough to accomodate gun pictures if ( i == iActiveSlot ) { CBasePlayerWeapon *p = pPlayer->GetFirstPos(iActiveSlot); if ( p ) iWidth = p->GetWeaponInfo()->GetHUDInfo()->GetActive().rect.right - p->GetWeaponInfo()->GetHUDInfo()->GetActive().rect.left; else iWidth = m_iBucketWidth; } else iWidth = m_iBucketWidth; SPR_DrawAdditive(0, x, y, &gHUD.GetSpriteRect(m_HUD_bucket0 + i)); x += iWidth + 5; } a = 128; //!!! x = 10; // Draw all of the buckets for (i = 0; i < iBucketsToDraw; i++) { y = m_iBucketHeight + 10; // If this is the active slot, draw the bigger pictures, // otherwise just draw boxes if ( i == iActiveSlot ) { CBasePlayerWeapon *p = pPlayer->GetFirstPos( i ); int iWidth = m_iBucketWidth; if ( p ) iWidth = p->GetWeaponInfo()->GetHUDInfo()->GetActive().rect.right - p->GetWeaponInfo()->GetHUDInfo()->GetActive().rect.left; for ( int iPos = 0; iPos < MAX_WEAPONS; iPos++ ) { p = pPlayer->GetWeapon( i, iPos ); if ( !p || !p->GetWeaponInfo() ) continue; auto pHUDInfo = p->GetWeaponInfo()->GetHUDInfo(); gHUD.GetPrimaryColor().UnpackRGB( r,g,b ); // if active, then we must have ammo. if ( m_pActiveSel == p ) { SPR_Set( pHUDInfo->GetActive().hSprite, r, g, b ); SPR_DrawAdditive(0, x, y, &pHUDInfo->GetActive().rect ); SPR_Set(gHUD.GetSprite(m_HUD_selection), r, g, b ); SPR_DrawAdditive(0, x, y, &gHUD.GetSpriteRect(m_HUD_selection)); } else { // Draw Weapon if Red if no ammo if ( pPlayer->HasAmmo(p) ) ScaleColors(r, g, b, 192); else { gHUD.GetEmptyItemColor().UnpackRGB(r,g,b); ScaleColors(r, g, b, 128); } SPR_Set( pHUDInfo->GetInactive().hSprite, r, g, b ); SPR_DrawAdditive( 0, x, y, &pHUDInfo->GetInactive().rect ); } // Draw Ammo Bar DrawAmmoBar(p, x + m_iABWidth/2, y, m_iABWidth, m_iABHeight); y += pHUDInfo->GetActive().rect.bottom - pHUDInfo->GetActive().rect.top + 5; } x += iWidth + 5; } else { // Draw Row of weapons. gHUD.GetPrimaryColor().UnpackRGB(r,g,b); for ( int iPos = 0; iPos < MAX_WEAPONS; iPos++ ) { CBasePlayerWeapon *p = pPlayer->GetWeapon( i, iPos ); if ( !p || !p->GetWeaponInfo() ) continue; if ( pPlayer->HasAmmo(p) ) { gHUD.GetPrimaryColor().UnpackRGB(r,g,b); a = 128; } else { gHUD.GetEmptyItemColor().UnpackRGB(r,g,b); a = 96; } FillRGBA( x, y, m_iBucketWidth, m_iBucketHeight, r, g, b, a ); y += m_iBucketHeight + 5; } x += m_iBucketWidth + 5; } } return 1; }
bool CHudAmmo::Draw(float flTime) { int a, x, y, r, g, b; int AmmoWidth; if (!(gHUD.m_iWeaponBits & (1<<(WEAPON_SUIT)) )) return true; if ( (gHUD.m_iHideHUDDisplay & ( HIDEHUD_WEAPONS | HIDEHUD_ALL )) ) return true; // Draw Weapon Menu DrawWList(flTime); // Draw ammo pickup history gHR.DrawAmmoHistory( flTime ); if (!(m_iFlags & HUD_ACTIVE)) return false; if (!m_pWeapon) return false; if( m_pCrosshair->value != 0 && m_hCrosshair != INVALID_HSPRITE ) { float flScale; switch( static_cast<int>( m_pCrosshairMode->value ) ) { default: case CROSS_NATIVESCALE: flScale = 1; break; case CROSS_RESSCALE: flScale = max( ( ScreenWidth / 640.0 ) * 0.75, 1.0 ); break; case CROSS_USERSCALE: flScale = abs( m_pCrosshairScale->value ); break; } class CCrosshairTriCallback : public ITriCoordFallback { public: void Calculate( HSPRITE hSprite, const int frame, const wrect_t& rect, const float flScale, int& x, int& y ) override { x = ( ScreenWidth - ( ( rect.right - rect.left ) ) ) / 2; y = ( ScreenHeight - ( ( rect.bottom - rect.top ) ) ) / 2; } }; CCrosshairTriCallback callback; Tri_DrawScaledSprite( m_hCrosshair, 0, m_iR, m_iG, m_iB, 255, kRenderTransTexture, flScale, callback, &m_CrosshairRC ); } CBasePlayerWeapon *pw = m_pWeapon; // shorthand // SPR_Draw Ammo if( !pw->GetWeaponInfo()->GetPrimaryAmmo() && !pw->GetWeaponInfo()->GetSecondaryAmmo() ) return false; int iFlags = DHN_DRAWZERO; // draw 0 values AmmoWidth = gHUD.GetSpriteRect(gHUD.m_HUD_number_0).right - gHUD.GetSpriteRect(gHUD.m_HUD_number_0).left; a = (int) max( static_cast<float>( MIN_ALPHA ), m_fFade ); if (m_fFade > 0) m_fFade -= (gHUD.m_flTimeDelta * 20); gHUD.GetPrimaryColor().UnpackRGB(r,g,b); ScaleColors(r, g, b, a ); // Does this weapon have a clip? y = ScreenHeight - gHUD.m_iFontHeight - gHUD.m_iFontHeight/2; CBasePlayer* pPlayer = g_Prediction.GetLocalPlayer(); // Does weapon have any ammo at all? if ( auto pAmmo = pw->GetWeaponInfo()->GetPrimaryAmmo() ) { const auto& ammo = m_pWeapon->GetWeaponInfo()->GetHUDInfo()->GetPrimaryAmmo(); int iIconWidth = ammo.rect.right - ammo.rect.left; if (pw->m_iClientClip >= 0) { // room for the number and the '|' and the current ammo x = ScreenWidth - (8 * AmmoWidth) - iIconWidth; x = gHUD.DrawHudNumber(x, y, iFlags | DHN_3DIGITS, pw->m_iClientClip, r, g, b); wrect_t rc; rc.top = 0; rc.left = 0; rc.right = AmmoWidth; rc.bottom = 100; int iBarWidth = AmmoWidth/10; x += AmmoWidth/2; gHUD.GetPrimaryColor().UnpackRGB(r,g,b); // draw the | bar FillRGBA(x, y, iBarWidth, gHUD.m_iFontHeight, r, g, b, a); x += iBarWidth + AmmoWidth/2;; // GL Seems to need this ScaleColors(r, g, b, a ); x = gHUD.DrawHudNumber(x, y, iFlags | DHN_3DIGITS, pPlayer->CountAmmo( pAmmo->GetID() ), r, g, b); } else { // SPR_Draw a bullets only line x = ScreenWidth - 4 * AmmoWidth - iIconWidth; x = gHUD.DrawHudNumber(x, y, iFlags | DHN_3DIGITS, pPlayer->CountAmmo( pAmmo->GetID() ), r, g, b); } // Draw the ammo Icon int iOffset = ( ammo.rect.bottom - ammo.rect.top)/8; SPR_Set( ammo.hSprite, r, g, b); SPR_DrawAdditive(0, x, y - iOffset, &ammo.rect ); } // Does weapon have seconday ammo? if ( auto pAmmo = pw->GetWeaponInfo()->GetSecondaryAmmo() ) { const auto& ammo2 = m_pWeapon->GetWeaponInfo()->GetHUDInfo()->GetSecondaryAmmo(); int iIconWidth = ammo2.rect.right - ammo2.rect.left; // Do we have secondary ammo? if ( pPlayer->CountAmmo( pAmmo->GetID() ) > 0 ) { y -= gHUD.m_iFontHeight + gHUD.m_iFontHeight/4; x = ScreenWidth - 4 * AmmoWidth - iIconWidth; x = gHUD.DrawHudNumber(x, y, iFlags|DHN_3DIGITS, pPlayer->CountAmmo( pAmmo->GetID() ), r, g, b); // Draw the ammo Icon SPR_Set( ammo2.hSprite, r, g, b); int iOffset = ( ammo2.rect.bottom - ammo2.rect.top)/8; SPR_DrawAdditive(0, x, y - iOffset, &ammo2.rect ); } } return true; }
void CHudAmmo::SelectSlot( int iSlot, const bool fAdvance, int iDirection ) { if ( gHUD.m_Menu.m_fMenuDisplayed && !fAdvance && (iDirection == 1) ) { // menu is overriding slot use commands gHUD.m_Menu.SelectMenuItem( iSlot + 1 ); // slots are one off the key numbers return; } if ( iSlot > MAX_WEAPON_SLOTS ) return; if ( gHUD.m_bPlayerDead || gHUD.m_iHideHUDDisplay & ( HIDEHUD_WEAPONS | HIDEHUD_ALL ) ) return; if (!(gHUD.m_iWeaponBits & (1<<(WEAPON_SUIT)) )) return; if ( ! ( gHUD.m_iWeaponBits & ~(1<<(WEAPON_SUIT)) )) return; CBasePlayerWeapon *p = NULL; bool fastSwitch = CVAR_GET_FLOAT( "hud_fastswitch" ) != 0; CBasePlayer* pPlayer = g_Prediction.GetLocalPlayer(); if ( ( m_pActiveSel == NULL) || ( m_pActiveSel == ( CBasePlayerWeapon *)1) || (iSlot != m_pActiveSel->GetWeaponInfo()->GetBucket()) ) { PlaySound( "common/wpn_hudon.wav", 1 ); p = pPlayer->GetFirstPos( iSlot ); if ( p && fastSwitch ) // check for fast weapon switch mode { // if fast weapon switch is on, then weapons can be selected in a single keypress // but only if there is only one item in the bucket CBasePlayerWeapon *p2 = pPlayer->GetNextActivePos( p->GetWeaponInfo()->GetBucket(), p->GetWeaponInfo()->GetPosition() ); if ( !p2 ) { // only one active item in bucket, so change directly to weapon ServerCmd( p->GetWeaponInfo()->GetWeaponName() ); g_weaponselect = p->GetWeaponInfo()->GetID(); return; } } } else { PlaySound("common/wpn_moveselect.wav", 1); if ( m_pActiveSel ) p = pPlayer->GetNextActivePos( m_pActiveSel->GetWeaponInfo()->GetBucket(), m_pActiveSel->GetWeaponInfo()->GetPosition() ); if ( !p ) p = pPlayer->GetFirstPos( iSlot ); } if ( !p ) // no selection found { // just display the weapon list, unless fastswitch is on just ignore it if ( !fastSwitch ) m_pActiveSel = ( CBasePlayerWeapon *)1; else m_pActiveSel = nullptr; } else m_pActiveSel = p; }