Portable Half-Life SDK. GoldSource and Xash3D. Crossplatform.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1245 lines
26 KiB

9 years ago
/***
*
* Copyright (c) 1996-2002, Valve LLC. All rights reserved.
*
* This product contains software technology licensed from Id
* Software, Inc. ("Id Technology"). Id Technology (c) 1996 Id Software, Inc.
* All Rights Reserved.
*
* Use, distribution, and modification of this source code and/or resulting
* object code is restricted to non-commercial enhancements to products from
* Valve LLC. All other use, distribution, or modification is prohibited
* without written permission from Valve LLC.
*
****/
//
// Ammo.cpp
//
// implementation of CHudAmmo class
//
#include "hud.h"
#include "cl_util.h"
#include "parsemsg.h"
#include "pm_shared.h"
#include <string.h>
#include <stdio.h>
#include "ammohistory.h"
#if USE_VGUI
#include "vgui_TeamFortressViewport.h"
#endif
9 years ago
WEAPON *gpActiveSel; // NULL means off, 1 means just the menu bar, otherwise
// this points to the active weapon menu item
WEAPON *gpLastSel; // Last weapon menu selection
client_sprite_t *GetSpriteList(client_sprite_t *pList, const char *psz, int iRes, int iCount);
WeaponsResource gWR;
int g_weaponselect = 0;
9 years ago
void WeaponsResource::LoadAllWeaponSprites( void )
9 years ago
{
9 years ago
for( int i = 0; i < MAX_WEAPONS; i++ )
9 years ago
{
9 years ago
if( rgWeapons[i].iId )
9 years ago
LoadWeaponSprites( &rgWeapons[i] );
}
}
9 years ago
int WeaponsResource::CountAmmo( int iId )
9 years ago
{
9 years ago
if( iId < 0 )
9 years ago
return 0;
return riAmmo[iId];
}
9 years ago
int WeaponsResource::HasAmmo( WEAPON *p )
9 years ago
{
9 years ago
if( !p )
9 years ago
return FALSE;
// weapons with no max ammo can always be selected
9 years ago
if( p->iMax1 == -1 )
9 years ago
return TRUE;
9 years ago
return ( p->iAmmoType == -1 ) || p->iClip > 0 || CountAmmo( p->iAmmoType )
|| CountAmmo( p->iAmmo2Type ) || ( p->iFlags & WEAPON_FLAGS_SELECTONEMPTY );
9 years ago
}
9 years ago
void WeaponsResource::LoadWeaponSprites( WEAPON *pWeapon )
9 years ago
{
int i, iRes;
9 years ago
if( ScreenWidth < 640 )
9 years ago
iRes = 320;
else
iRes = 640;
char sz[256];
9 years ago
9 years ago
if( !pWeapon )
9 years ago
return;
memset( &pWeapon->rcActive, 0, sizeof(wrect_t) );
memset( &pWeapon->rcInactive, 0, sizeof(wrect_t) );
memset( &pWeapon->rcAmmo, 0, sizeof(wrect_t) );
memset( &pWeapon->rcAmmo2, 0, sizeof(wrect_t) );
pWeapon->hInactive = 0;
pWeapon->hActive = 0;
pWeapon->hAmmo = 0;
pWeapon->hAmmo2 = 0;
9 years ago
sprintf( sz, "sprites/%s.txt", pWeapon->szName );
client_sprite_t *pList = SPR_GetList( sz, &i );
9 years ago
9 years ago
if( !pList )
9 years ago
return;
client_sprite_t *p;
9 years ago
9 years ago
p = GetSpriteList( pList, "crosshair", iRes, i );
9 years ago
if( p )
9 years ago
{
9 years ago
sprintf( sz, "sprites/%s.spr", p->szSprite );
pWeapon->hCrosshair = SPR_Load( sz );
9 years ago
pWeapon->rcCrosshair = p->rc;
}
else
pWeapon->hCrosshair = 0;
9 years ago
p = GetSpriteList( pList, "autoaim", iRes, i );
if( p )
9 years ago
{
9 years ago
sprintf( sz, "sprites/%s.spr", p->szSprite );
pWeapon->hAutoaim = SPR_Load( sz );
9 years ago
pWeapon->rcAutoaim = p->rc;
}
else
pWeapon->hAutoaim = 0;
p = GetSpriteList( pList, "zoom", iRes, i );
9 years ago
if( p )
9 years ago
{
9 years ago
sprintf( sz, "sprites/%s.spr", p->szSprite );
pWeapon->hZoomedCrosshair = SPR_Load( sz );
9 years ago
pWeapon->rcZoomedCrosshair = p->rc;
}
else
{
pWeapon->hZoomedCrosshair = pWeapon->hCrosshair; //default to non-zoomed crosshair
pWeapon->rcZoomedCrosshair = pWeapon->rcCrosshair;
}
9 years ago
p = GetSpriteList( pList, "zoom_autoaim", iRes, i );
if( p )
9 years ago
{
9 years ago
sprintf( sz, "sprites/%s.spr", p->szSprite );
pWeapon->hZoomedAutoaim = SPR_Load( sz );
9 years ago
pWeapon->rcZoomedAutoaim = p->rc;
}
else
{
pWeapon->hZoomedAutoaim = pWeapon->hZoomedCrosshair; //default to zoomed crosshair
pWeapon->rcZoomedAutoaim = pWeapon->rcZoomedCrosshair;
}
9 years ago
p = GetSpriteList( pList, "weapon", iRes, i );
if( p )
9 years ago
{
9 years ago
sprintf( sz, "sprites/%s.spr", p->szSprite );
pWeapon->hInactive = SPR_Load( sz );
9 years ago
pWeapon->rcInactive = p->rc;
gHR.iHistoryGap = Q_max( gHR.iHistoryGap, pWeapon->rcActive.bottom - pWeapon->rcActive.top );
9 years ago
}
else
pWeapon->hInactive = 0;
9 years ago
p = GetSpriteList( pList, "weapon_s", iRes, i );
if( p )
9 years ago
{
9 years ago
sprintf( sz, "sprites/%s.spr", p->szSprite );
pWeapon->hActive = SPR_Load( sz );
9 years ago
pWeapon->rcActive = p->rc;
}
else
pWeapon->hActive = 0;
9 years ago
p = GetSpriteList( pList, "ammo", iRes, i );
if( p )
9 years ago
{
9 years ago
sprintf( sz, "sprites/%s.spr", p->szSprite );
pWeapon->hAmmo = SPR_Load( sz );
9 years ago
pWeapon->rcAmmo = p->rc;
gHR.iHistoryGap = Q_max( gHR.iHistoryGap, pWeapon->rcActive.bottom - pWeapon->rcActive.top );
9 years ago
}
else
pWeapon->hAmmo = 0;
9 years ago
p = GetSpriteList( pList, "ammo2", iRes, i );
if( p )
9 years ago
{
9 years ago
sprintf( sz, "sprites/%s.spr", p->szSprite );
pWeapon->hAmmo2 = SPR_Load( sz );
9 years ago
pWeapon->rcAmmo2 = p->rc;
gHR.iHistoryGap = Q_max( gHR.iHistoryGap, pWeapon->rcActive.bottom - pWeapon->rcActive.top );
9 years ago
}
else
pWeapon->hAmmo2 = 0;
}
// Returns the first weapon for a given slot.
9 years ago
WEAPON *WeaponsResource::GetFirstPos( int iSlot )
9 years ago
{
WEAPON *pret = NULL;
9 years ago
for( int i = 0; i < MAX_WEAPON_POSITIONS; i++ )
9 years ago
{
if ( rgSlots[iSlot][i] && HasAmmo( rgSlots[iSlot][i] ) )
{
pret = rgSlots[iSlot][i];
break;
}
}
return pret;
}
9 years ago
WEAPON* WeaponsResource::GetNextActivePos( int iSlot, int iSlotPos )
9 years ago
{
if ( iSlotPos >= MAX_WEAPON_POSITIONS || iSlot >= MAX_WEAPON_SLOTS )
return NULL;
9 years ago
WEAPON *p = gWR.rgSlots[iSlot][iSlotPos + 1];
9 years ago
9 years ago
if ( !p || !gWR.HasAmmo( p ) )
9 years ago
return GetNextActivePos( iSlot, iSlotPos + 1 );
return p;
}
int giBucketHeight, giBucketWidth, giABHeight, giABWidth; // Ammo Bar width and height
HSPRITE ghsprBuckets; // Sprite for top row of weapons menu
9 years ago
DECLARE_MESSAGE( m_Ammo, CurWeapon ) // Current weapon and clip
DECLARE_MESSAGE( m_Ammo, WeaponList ) // new weapon type
DECLARE_MESSAGE( m_Ammo, AmmoX ) // update known ammo type's count
DECLARE_MESSAGE( m_Ammo, AmmoPickup ) // flashes an ammo pickup record
DECLARE_MESSAGE( m_Ammo, WeapPickup ) // flashes a weapon pickup record
DECLARE_MESSAGE( m_Ammo, HideWeapon ) // hides the weapon, ammo, and crosshair displays temporarily
DECLARE_MESSAGE( m_Ammo, ItemPickup )
DECLARE_COMMAND( m_Ammo, Slot1 )
DECLARE_COMMAND( m_Ammo, Slot2 )
DECLARE_COMMAND( m_Ammo, Slot3 )
DECLARE_COMMAND( m_Ammo, Slot4 )
DECLARE_COMMAND( m_Ammo, Slot5 )
DECLARE_COMMAND( m_Ammo, Slot6 )
DECLARE_COMMAND( m_Ammo, Slot7 )
DECLARE_COMMAND( m_Ammo, Slot8 )
DECLARE_COMMAND( m_Ammo, Slot9 )
DECLARE_COMMAND( m_Ammo, Slot10 )
DECLARE_COMMAND( m_Ammo, Close )
DECLARE_COMMAND( m_Ammo, NextWeapon )
DECLARE_COMMAND( m_Ammo, PrevWeapon )
9 years ago
// width of ammo fonts
#define AMMO_SMALL_WIDTH 10
#define AMMO_LARGE_WIDTH 20
#define HISTORY_DRAW_TIME "5"
9 years ago
int CHudAmmo::Init( void )
9 years ago
{
9 years ago
gHUD.AddHudElem( this );
HOOK_MESSAGE( CurWeapon );
HOOK_MESSAGE( WeaponList );
HOOK_MESSAGE( AmmoPickup );
HOOK_MESSAGE( WeapPickup );
HOOK_MESSAGE( ItemPickup );
HOOK_MESSAGE( HideWeapon );
HOOK_MESSAGE( AmmoX );
HOOK_COMMAND( "slot1", Slot1 );
HOOK_COMMAND( "slot2", Slot2 );
HOOK_COMMAND( "slot3", Slot3 );
HOOK_COMMAND( "slot4", Slot4 );
HOOK_COMMAND( "slot5", Slot5 );
HOOK_COMMAND( "slot6", Slot6 );
HOOK_COMMAND( "slot7", Slot7 );
HOOK_COMMAND( "slot8", Slot8 );
HOOK_COMMAND( "slot9", Slot9 );
HOOK_COMMAND( "slot10", Slot10 );
HOOK_COMMAND( "cancelselect", Close );
HOOK_COMMAND( "invnext", NextWeapon );
HOOK_COMMAND( "invprev", PrevWeapon );
9 years ago
Reset();
CVAR_CREATE( "hud_drawhistory_time", HISTORY_DRAW_TIME, 0 );
CVAR_CREATE( "hud_fastswitch", "0", FCVAR_ARCHIVE ); // controls whether or not weapons can be selected in one keypress
m_iFlags |= HUD_ACTIVE; //!!!
gWR.Init();
gHR.Init();
return 1;
}
9 years ago
9 years ago
void CHudAmmo::Reset( void )
9 years ago
{
m_fFade = 0;
m_iFlags |= HUD_ACTIVE; //!!!
gpActiveSel = NULL;
gHUD.m_iHideHUDDisplay = 0;
gWR.Reset();
gHR.Reset();
9 years ago
//VidInit();
wrect_t nullrc = {0,};
7 years ago
SetCrosshair( 0, nullrc, 0, 0, 0 ); // reset crosshair
m_pWeapon = NULL; // reset last weapon
9 years ago
}
9 years ago
int CHudAmmo::VidInit( void )
9 years ago
{
// Load sprites for buckets (top row of weapon menu)
m_HUD_bucket0 = gHUD.GetSpriteIndex( "bucket1" );
m_HUD_selection = gHUD.GetSpriteIndex( "selection" );
9 years ago
ghsprBuckets = gHUD.GetSprite( m_HUD_bucket0 );
giBucketWidth = gHUD.GetSpriteRect( m_HUD_bucket0 ).right - gHUD.GetSpriteRect( m_HUD_bucket0 ).left;
giBucketHeight = gHUD.GetSpriteRect( m_HUD_bucket0 ).bottom - gHUD.GetSpriteRect( m_HUD_bucket0 ).top;
9 years ago
gHR.iHistoryGap = Q_max( gHR.iHistoryGap, gHUD.GetSpriteRect( m_HUD_bucket0 ).bottom - gHUD.GetSpriteRect( m_HUD_bucket0 ).top );
9 years ago
// If we've already loaded weapons, let's get new sprites
gWR.LoadAllWeaponSprites();
9 years ago
if( ScreenWidth >= 640 )
9 years ago
{
giABWidth = 20;
giABHeight = 4;
}
else
{
giABWidth = 10;
giABHeight = 2;
}
return 1;
}
//
// Think:
// Used for selection of weapon menu item.
//
9 years ago
void CHudAmmo::Think( void )
9 years ago
{
9 years ago
if( gHUD.m_fPlayerDead )
9 years ago
return;
9 years ago
if( gHUD.m_iWeaponBits != gWR.iOldWeaponBits )
9 years ago
{
gWR.iOldWeaponBits = gHUD.m_iWeaponBits;
9 years ago
for( int i = MAX_WEAPONS-1; i > 0; i-- )
9 years ago
{
9 years ago
WEAPON *p = gWR.GetWeapon( i );
9 years ago
if( p && p->iId )
9 years ago
{
9 years ago
if( gHUD.m_iWeaponBits & ( 1 << p->iId ) )
9 years ago
gWR.PickupWeapon( p );
else
gWR.DropWeapon( p );
}
}
}
9 years ago
if( !gpActiveSel )
9 years ago
return;
// has the player selected one?
9 years ago
if( gHUD.m_iKeyBits & IN_ATTACK )
9 years ago
{
9 years ago
if( gpActiveSel != (WEAPON *) 1 )
9 years ago
{
9 years ago
ServerCmd( gpActiveSel->szName );
9 years ago
g_weaponselect = gpActiveSel->iId;
}
gpLastSel = gpActiveSel;
gpActiveSel = NULL;
gHUD.m_iKeyBits &= ~IN_ATTACK;
9 years ago
PlaySound( "common/wpn_select.wav", 1 );
9 years ago
}
}
//
// Helper function to return a Ammo pointer from id
//
9 years ago
HSPRITE* WeaponsResource::GetAmmoPicFromWeapon( int iAmmoId, wrect_t& rect )
9 years ago
{
9 years ago
for( int i = 0; i < MAX_WEAPONS; i++ )
9 years ago
{
9 years ago
if( rgWeapons[i].iAmmoType == iAmmoId )
9 years ago
{
rect = rgWeapons[i].rcAmmo;
return &rgWeapons[i].hAmmo;
}
9 years ago
else if( rgWeapons[i].iAmmo2Type == iAmmoId )
9 years ago
{
rect = rgWeapons[i].rcAmmo2;
return &rgWeapons[i].hAmmo2;
}
}
return NULL;
}
// Menu Selection Code
9 years ago
void WeaponsResource::SelectSlot( int iSlot, int fAdvance, int iDirection )
9 years ago
{
9 years ago
if( gHUD.m_Menu.m_fMenuDisplayed && ( fAdvance == FALSE ) && ( iDirection == 1 ) )
{
// menu is overriding slot use commands
9 years ago
gHUD.m_Menu.SelectMenuItem( iSlot + 1 ); // slots are one off the key numbers
return;
}
9 years ago
if( iSlot > MAX_WEAPON_SLOTS )
9 years ago
return;
9 years ago
if( gHUD.m_fPlayerDead || gHUD.m_iHideHUDDisplay & ( HIDEHUD_WEAPONS | HIDEHUD_ALL ) )
9 years ago
return;
9 years ago
if ( !( gHUD.m_iWeaponBits & ( 1 << ( WEAPON_SUIT ) ) ) )
9 years ago
return;
9 years ago
if( ! ( gHUD.m_iWeaponBits & ~( 1 << ( WEAPON_SUIT ) ) ) )
9 years ago
return;
WEAPON *p = NULL;
bool fastSwitch = CVAR_GET_FLOAT( "hud_fastswitch" ) != 0;
9 years ago
if ( ( gpActiveSel == NULL ) || ( gpActiveSel == (WEAPON *) 1 ) || ( iSlot != gpActiveSel->iSlot ) )
9 years ago
{
PlaySound( "common/wpn_hudon.wav", 1 );
p = 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
WEAPON *p2 = GetNextActivePos( p->iSlot, p->iSlotPos );
if ( !p2 )
9 years ago
{
// only one active item in bucket, so change directly to weapon
9 years ago
ServerCmd( p->szName );
g_weaponselect = p->iId;
return;
}
}
}
else
{
9 years ago
PlaySound( "common/wpn_moveselect.wav", 1 );
9 years ago
if ( gpActiveSel )
p = GetNextActivePos( gpActiveSel->iSlot, gpActiveSel->iSlotPos );
if ( !p )
p = GetFirstPos( iSlot );
}
if ( !p ) // no selection found
{
// just display the weapon list, unless fastswitch is on just ignore it
if ( !fastSwitch )
gpActiveSel = (WEAPON *)1;
else
gpActiveSel = NULL;
}
else
gpActiveSel = p;
}
//------------------------------------------------------------------------
// Message Handlers
//------------------------------------------------------------------------
//
// AmmoX -- Update the count of a known type of ammo
//
9 years ago
int CHudAmmo::MsgFunc_AmmoX( const char *pszName, int iSize, void *pbuf )
9 years ago
{
BEGIN_READ( pbuf, iSize );
int iIndex = READ_BYTE();
int iCount = READ_BYTE();
9 years ago
gWR.SetAmmo( iIndex, abs( iCount ) );
9 years ago
return 1;
}
int CHudAmmo::MsgFunc_AmmoPickup( const char *pszName, int iSize, void *pbuf )
{
BEGIN_READ( pbuf, iSize );
int iIndex = READ_BYTE();
int iCount = READ_BYTE();
// Add ammo to the history
9 years ago
gHR.AddToHistory( HISTSLOT_AMMO, iIndex, abs( iCount ) );
9 years ago
return 1;
}
int CHudAmmo::MsgFunc_WeapPickup( const char *pszName, int iSize, void *pbuf )
{
BEGIN_READ( pbuf, iSize );
int iIndex = READ_BYTE();
// Add the weapon to the history
gHR.AddToHistory( HISTSLOT_WEAP, iIndex );
return 1;
}
int CHudAmmo::MsgFunc_ItemPickup( const char *pszName, int iSize, void *pbuf )
{
BEGIN_READ( pbuf, iSize );
const char *szName = READ_STRING();
// Add the weapon to the history
gHR.AddToHistory( HISTSLOT_ITEM, szName );
return 1;
}
int CHudAmmo::MsgFunc_HideWeapon( const char *pszName, int iSize, void *pbuf )
{
BEGIN_READ( pbuf, iSize );
gHUD.m_iHideHUDDisplay = READ_BYTE();
9 years ago
if( gEngfuncs.IsSpectateOnly() )
9 years ago
return 1;
9 years ago
if( gHUD.m_iHideHUDDisplay & ( HIDEHUD_WEAPONS | HIDEHUD_ALL ) )
9 years ago
{
wrect_t nullrc = {0,};
9 years ago
gpActiveSel = NULL;
SetCrosshair( 0, nullrc, 0, 0, 0 );
}
else
{
if( m_pWeapon )
{
if( gHUD.m_iHideHUDDisplay & HIDEHUD_NOHEV )
{
SetCrosshair( m_pWeapon->hCrosshair, m_pWeapon->rcCrosshair, 255, 16, 16 );
}
else
{
SetCrosshair( m_pWeapon->hCrosshair, m_pWeapon->rcCrosshair, 255, 255, 255 );
}
}
9 years ago
}
return 1;
}
//
// CurWeapon: Update hud state with the current weapon and clip count. Ammo
// counts are updated with AmmoX. Server assures that the Weapon ammo type
// numbers match a real ammo type.
//
9 years ago
int CHudAmmo::MsgFunc_CurWeapon( const char *pszName, int iSize, void *pbuf )
9 years ago
{
wrect_t nullrc = {0,};
9 years ago
int fOnTarget = FALSE;
BEGIN_READ( pbuf, iSize );
int iState = READ_BYTE();
int iId = READ_CHAR();
int iClip = READ_CHAR();
// detect if we're also on target
9 years ago
if( iState > 1 )
9 years ago
{
fOnTarget = TRUE;
}
9 years ago
if( iId < 1 )
9 years ago
{
9 years ago
SetCrosshair( 0, nullrc, 0, 0, 0 );
// Clear out the weapon so we don't keep drawing the last active weapon's ammo. - Solokiller
m_pWeapon = 0;
9 years ago
return 0;
}
9 years ago
if( g_iUser1 != OBS_IN_EYE )
9 years ago
{
// Is player dead???
9 years ago
if( ( iId == -1 ) && ( iClip == -1 ) )
9 years ago
{
gHUD.m_fPlayerDead = TRUE;
gpActiveSel = NULL;
return 1;
}
gHUD.m_fPlayerDead = FALSE;
}
WEAPON *pWeapon = gWR.GetWeapon( iId );
9 years ago
if( !pWeapon )
9 years ago
return 0;
9 years ago
if( iClip < -1 )
pWeapon->iClip = abs( iClip );
9 years ago
else
pWeapon->iClip = iClip;
9 years ago
if( iState == 0 ) // we're not the current weapon, so update no more
9 years ago
return 1;
m_pWeapon = pWeapon;
7 years ago
if( !( gHUD.m_iHideHUDDisplay & ( HIDEHUD_WEAPONS | HIDEHUD_ALL ) ) )
9 years ago
{
7 years ago
if( gHUD.m_iFOV >= 90 )
{
7 years ago
// normal crosshairs
if( fOnTarget && m_pWeapon->hAutoaim )
{
if( gHUD.m_iHideHUDDisplay & HIDEHUD_NOHEV )
{
SetCrosshair( m_pWeapon->hAutoaim, m_pWeapon->rcAutoaim, 255, 16, 16 );
}
else
{
SetCrosshair( m_pWeapon->hAutoaim, m_pWeapon->rcAutoaim, 255, 255, 255 );
}
}
else
{
if( gHUD.m_iHideHUDDisplay & HIDEHUD_NOHEV )
{
SetCrosshair( m_pWeapon->hCrosshair, m_pWeapon->rcCrosshair, 255, 16, 16 );
}
else
{
SetCrosshair( m_pWeapon->hCrosshair, m_pWeapon->rcCrosshair, 255, 255, 255 );
}
}
}
9 years ago
else
{
7 years ago
// zoomed crosshairs
if( fOnTarget && m_pWeapon->hZoomedAutoaim )
{
if( gHUD.m_iHideHUDDisplay & HIDEHUD_NOHEV )
{
SetCrosshair( m_pWeapon->hZoomedAutoaim, m_pWeapon->rcZoomedAutoaim, 255, 16, 16 );
}
else
{
SetCrosshair( m_pWeapon->hZoomedAutoaim, m_pWeapon->rcZoomedAutoaim, 255, 255, 255 );
}
}
else
{
if( gHUD.m_iHideHUDDisplay & HIDEHUD_NOHEV )
{
SetCrosshair( m_pWeapon->hZoomedCrosshair, m_pWeapon->rcZoomedCrosshair, 255, 16, 16 );
}
else
{
SetCrosshair( m_pWeapon->hZoomedCrosshair, m_pWeapon->rcZoomedCrosshair, 255, 255, 255 );
}
}
}
9 years ago
}
m_fFade = 200.0f; //!!!
m_iFlags |= HUD_ACTIVE;
return 1;
}
//
// WeaponList -- Tells the hud about a new weapon type.
//
9 years ago
int CHudAmmo::MsgFunc_WeaponList( const char *pszName, int iSize, void *pbuf )
9 years ago
{
BEGIN_READ( pbuf, iSize );
9 years ago
WEAPON Weapon;
strcpy( Weapon.szName, READ_STRING() );
Weapon.iAmmoType = (int)READ_CHAR();
Weapon.iMax1 = READ_BYTE();
9 years ago
if( Weapon.iMax1 == 255 )
9 years ago
Weapon.iMax1 = -1;
Weapon.iAmmo2Type = READ_CHAR();
Weapon.iMax2 = READ_BYTE();
9 years ago
if( Weapon.iMax2 == 255 )
9 years ago
Weapon.iMax2 = -1;
Weapon.iSlot = READ_CHAR();
Weapon.iSlotPos = READ_CHAR();
Weapon.iId = READ_CHAR();
Weapon.iFlags = READ_BYTE();
Weapon.iClip = 0;
gWR.AddWeapon( &Weapon );
return 1;
}
//------------------------------------------------------------------------
// Command Handlers
//------------------------------------------------------------------------
// Slot button pressed
void CHudAmmo::SlotInput( int iSlot )
{
#if USE_VGUI
9 years ago
// Let the Viewport use it first, for menus
if( gViewPort && gViewPort->SlotInput( iSlot ) )
return;
#endif
9 years ago
gWR.SelectSlot(iSlot, FALSE, 1);
}
9 years ago
void CHudAmmo::UserCmd_Slot1( void )
9 years ago
{
SlotInput( 0 );
}
9 years ago
void CHudAmmo::UserCmd_Slot2( void )
9 years ago
{
SlotInput( 1 );
}
9 years ago
void CHudAmmo::UserCmd_Slot3( void )
9 years ago
{
SlotInput( 2 );
}
9 years ago
void CHudAmmo::UserCmd_Slot4( void )
9 years ago
{
SlotInput( 3 );
}
9 years ago
void CHudAmmo::UserCmd_Slot5( void )
9 years ago
{
SlotInput( 4 );
}
9 years ago
void CHudAmmo::UserCmd_Slot6( void )
9 years ago
{
SlotInput( 5 );
}
9 years ago
void CHudAmmo::UserCmd_Slot7( void )
9 years ago
{
SlotInput( 6 );
}
9 years ago
void CHudAmmo::UserCmd_Slot8( void )
9 years ago
{
SlotInput( 7 );
}
9 years ago
void CHudAmmo::UserCmd_Slot9( void )
9 years ago
{
SlotInput( 8 );
}
9 years ago
void CHudAmmo::UserCmd_Slot10( void )
9 years ago
{
SlotInput( 9 );
}
9 years ago
void CHudAmmo::UserCmd_Close( void )
9 years ago
{
9 years ago
if( gpActiveSel )
9 years ago
{
gpLastSel = gpActiveSel;
gpActiveSel = NULL;
9 years ago
PlaySound( "common/wpn_hudoff.wav", 1 );
9 years ago
}
else
9 years ago
ClientCmd( "escape" );
9 years ago
}
// Selects the next item in the weapon menu
9 years ago
void CHudAmmo::UserCmd_NextWeapon( void )
9 years ago
{
9 years ago
if( gHUD.m_fPlayerDead || ( gHUD.m_iHideHUDDisplay & ( HIDEHUD_WEAPONS | HIDEHUD_ALL ) ) )
9 years ago
return;
9 years ago
if( !gpActiveSel || gpActiveSel == (WEAPON*)1 )
9 years ago
gpActiveSel = m_pWeapon;
int pos = 0;
int slot = 0;
if ( gpActiveSel )
{
pos = gpActiveSel->iSlotPos + 1;
slot = gpActiveSel->iSlot;
}
9 years ago
for( int loop = 0; loop <= 1; loop++ )
9 years ago
{
9 years ago
for( ; slot < MAX_WEAPON_SLOTS; slot++ )
9 years ago
{
9 years ago
for( ; pos < MAX_WEAPON_POSITIONS; pos++ )
9 years ago
{
WEAPON *wsp = gWR.GetWeaponSlot( slot, pos );
9 years ago
if( wsp && gWR.HasAmmo( wsp ) )
9 years ago
{
gpActiveSel = wsp;
return;
}
}
pos = 0;
}
slot = 0; // start looking from the first slot again
}
gpActiveSel = NULL;
}
// Selects the previous item in the menu
9 years ago
void CHudAmmo::UserCmd_PrevWeapon( void )
9 years ago
{
9 years ago
if( gHUD.m_fPlayerDead || ( gHUD.m_iHideHUDDisplay & ( HIDEHUD_WEAPONS | HIDEHUD_ALL ) ) )
9 years ago
return;
9 years ago
if( !gpActiveSel || gpActiveSel == (WEAPON*) 1 )
9 years ago
gpActiveSel = m_pWeapon;
9 years ago
int pos = MAX_WEAPON_POSITIONS - 1;
int slot = MAX_WEAPON_SLOTS - 1;
if( gpActiveSel )
9 years ago
{
pos = gpActiveSel->iSlotPos - 1;
slot = gpActiveSel->iSlot;
}
9 years ago
for( int loop = 0; loop <= 1; loop++ )
9 years ago
{
9 years ago
for( ; slot >= 0; slot-- )
9 years ago
{
9 years ago
for( ; pos >= 0; pos-- )
9 years ago
{
WEAPON *wsp = gWR.GetWeaponSlot( slot, pos );
9 years ago
if( wsp && gWR.HasAmmo( wsp ) )
9 years ago
{
gpActiveSel = wsp;
return;
}
}
9 years ago
pos = MAX_WEAPON_POSITIONS - 1;
9 years ago
}
9 years ago
slot = MAX_WEAPON_SLOTS - 1;
9 years ago
}
gpActiveSel = NULL;
}
//-------------------------------------------------------------------------
// Drawing code
//-------------------------------------------------------------------------
9 years ago
int CHudAmmo::Draw( float flTime )
9 years ago
{
int a, x, y, r, g, b;
int AmmoWidth;
9 years ago
if( !( gHUD.m_iWeaponBits & ( 1 << ( WEAPON_SUIT ) ) ) )
9 years ago
return 1;
9 years ago
if( ( gHUD.m_iHideHUDDisplay & ( HIDEHUD_WEAPONS | HIDEHUD_ALL ) ) )
9 years ago
return 1;
// Draw Weapon Menu
9 years ago
DrawWList( flTime );
9 years ago
// Draw ammo pickup history
gHR.DrawAmmoHistory( flTime );
9 years ago
if( !( m_iFlags & HUD_ACTIVE ) )
9 years ago
return 0;
9 years ago
if( !m_pWeapon )
9 years ago
return 0;
WEAPON *pw = m_pWeapon; // shorthand
// SPR_Draw Ammo
9 years ago
if( ( pw->iAmmoType < 0 ) && ( pw->iAmmo2Type < 0 ) )
9 years ago
return 0;
int iFlags = DHN_DRAWZERO; // draw 0 values
9 years ago
AmmoWidth = gHUD.GetSpriteRect( gHUD.m_HUD_number_0 ).right - gHUD.GetSpriteRect( gHUD.m_HUD_number_0 ).left;
9 years ago
a = (int)Q_max( MIN_ALPHA, m_fFade );
9 years ago
9 years ago
if( m_fFade > 0 )
m_fFade -= ( (float)gHUD.m_flTimeDelta * 20.0f );
9 years ago
if( gHUD.m_iHideHUDDisplay & HIDEHUD_NOHEV )
{
UnpackRGB( r, g, b, RGB_REDISH );
}
else
{
UnpackRGB( r, g, b, RGB_YELLOWISH );
}
9 years ago
9 years ago
ScaleColors( r, g, b, a );
9 years ago
// Does this weapon have a clip?
9 years ago
y = ScreenHeight - gHUD.m_iFontHeight - gHUD.m_iFontHeight / 2;
9 years ago
// Does weapon have any ammo at all?
9 years ago
if( m_pWeapon->iAmmoType > 0 )
9 years ago
{
int iIconWidth = m_pWeapon->rcAmmo.right - m_pWeapon->rcAmmo.left;
9 years ago
if( pw->iClip >= 0 )
9 years ago
{
// room for the number and the '|' and the current ammo
9 years ago
x = ScreenWidth - ( 8 * AmmoWidth ) - iIconWidth;
x = gHUD.DrawHudNumber( x, y, iFlags | DHN_3DIGITS, pw->iClip, r, g, b );
9 years ago
/*wrect_t rc;
9 years ago
rc.top = 0;
rc.left = 0;
rc.right = AmmoWidth;
rc.bottom = 100;*/
9 years ago
9 years ago
int iBarWidth = AmmoWidth / 10;
9 years ago
9 years ago
x += AmmoWidth / 2;
9 years ago
if( gHUD.m_iHideHUDDisplay & HIDEHUD_NOHEV )
{
UnpackRGB( r, g, b, RGB_REDISH );
}
else
{
UnpackRGB( r, g, b, RGB_YELLOWISH );
}
9 years ago
// draw the | bar
9 years ago
FillRGBA( x, y, iBarWidth, gHUD.m_iFontHeight, r, g, b, a );
9 years ago
9 years ago
x += iBarWidth + AmmoWidth / 2;
9 years ago
// GL Seems to need this
9 years ago
ScaleColors( r, g, b, a );
x = gHUD.DrawHudNumber( x, y, iFlags | DHN_3DIGITS, gWR.CountAmmo( pw->iAmmoType ), r, g, b );
9 years ago
}
else
{
// SPR_Draw a bullets only line
x = ScreenWidth - 4 * AmmoWidth - iIconWidth;
9 years ago
x = gHUD.DrawHudNumber( x, y, iFlags | DHN_3DIGITS, gWR.CountAmmo( pw->iAmmoType ), r, g, b );
9 years ago
}
// Draw the ammo Icon
9 years ago
int iOffset = ( m_pWeapon->rcAmmo.bottom - m_pWeapon->rcAmmo.top ) / 8;
SPR_Set( m_pWeapon->hAmmo, r, g, b );
SPR_DrawAdditive( 0, x, y - iOffset, &m_pWeapon->rcAmmo );
9 years ago
}
// Does weapon have seconday ammo?
9 years ago
if( pw->iAmmo2Type > 0 )
9 years ago
{
int iIconWidth = m_pWeapon->rcAmmo2.right - m_pWeapon->rcAmmo2.left;
// Do we have secondary ammo?
9 years ago
if( ( pw->iAmmo2Type != 0 ) && ( gWR.CountAmmo( pw->iAmmo2Type ) > 0 ) )
9 years ago
{
9 years ago
y -= gHUD.m_iFontHeight + gHUD.m_iFontHeight / 4;
9 years ago
x = ScreenWidth - 4 * AmmoWidth - iIconWidth;
9 years ago
x = gHUD.DrawHudNumber( x, y, iFlags | DHN_3DIGITS, gWR.CountAmmo( pw->iAmmo2Type ), r, g, b );
9 years ago
// Draw the ammo Icon
9 years ago
SPR_Set( m_pWeapon->hAmmo2, r, g, b );
int iOffset = ( m_pWeapon->rcAmmo2.bottom - m_pWeapon->rcAmmo2.top) / 8;
SPR_DrawAdditive(0, x, y - iOffset, &m_pWeapon->rcAmmo2 );
9 years ago
}
}
return 1;
}
//
// Draws the ammo bar on the hud
//
9 years ago
int DrawBar( int x, int y, int width, int height, float f )
9 years ago
{
int r, g, b;
9 years ago
if( f < 0 )
9 years ago
f = 0;
9 years ago
if( f > 1 )
9 years ago
f = 1;
9 years ago
if( f )
9 years ago
{
int w = f * width;
// Always show at least one pixel if we have ammo.
9 years ago
if( w <= 0 )
9 years ago
w = 1;
9 years ago
UnpackRGB( r, g, b, RGB_GREENISH );
FillRGBA( x, y, w, height, r, g, b, 255 );
9 years ago
x += w;
width -= w;
}
if( gHUD.m_iHideHUDDisplay & HIDEHUD_NOHEV )
UnpackRGB( r, g, b, RGB_REDISH );
else
UnpackRGB( r, g, b, RGB_YELLOWISH );
9 years ago
9 years ago
FillRGBA( x, y, width, height, r, g, b, 128 );
9 years ago
9 years ago
return ( x + width );
9 years ago
}
9 years ago
void DrawAmmoBar( WEAPON *p, int x, int y, int width, int height )
9 years ago
{
9 years ago
if( !p )
9 years ago
return;
9 years ago
if( p->iAmmoType != -1 )
9 years ago
{
9 years ago
if( !gWR.CountAmmo( p->iAmmoType ) )
9 years ago
return;
9 years ago
float f = (float)gWR.CountAmmo( p->iAmmoType ) / (float)p->iMax1;
9 years ago
9 years ago
x = DrawBar( x, y, width, height, f );
9 years ago
// Do we have secondary ammo too?
9 years ago
if( p->iAmmo2Type != -1 )
9 years ago
{
9 years ago
f = (float)gWR.CountAmmo( p->iAmmo2Type ) / (float)p->iMax2;
9 years ago
x += 5; //!!!
9 years ago
DrawBar( x, y, width, height, f );
9 years ago
}
}
}
//
// Draw Weapon Menu
//
9 years ago
int CHudAmmo::DrawWList( float flTime )
9 years ago
{
9 years ago
int r, g, b, x, y, a, i;
9 years ago
9 years ago
if( !gpActiveSel )
9 years ago
return 0;
int iActiveSlot;
9 years ago
if( gpActiveSel == (WEAPON *) 1 )
9 years ago
iActiveSlot = -1; // current slot has no weapons
else
iActiveSlot = gpActiveSel->iSlot;
x = 10; //!!!
y = 10; //!!!
// Ensure that there are available choices in the active slot
9 years ago
if( iActiveSlot > 0 )
9 years ago
{
9 years ago
if( !gWR.GetFirstPos( iActiveSlot ) )
9 years ago
{
9 years ago
gpActiveSel = (WEAPON *) 1;
9 years ago
iActiveSlot = -1;
}
}
9 years ago
9 years ago
// Draw top line
9 years ago
for( i = 0; i < MAX_WEAPON_SLOTS; i++ )
9 years ago
{
int iWidth;
9 years ago
UnpackRGB( r, g, b, RGB_YELLOWISH );
if( iActiveSlot == i )
9 years ago
a = 255;
else
a = 192;
9 years ago
ScaleColors( r, g, b, 255 );
SPR_Set( gHUD.GetSprite( m_HUD_bucket0 + i ), r, g, b );
9 years ago
// make active slot wide enough to accomodate gun pictures
9 years ago
if( i == iActiveSlot )
9 years ago
{
9 years ago
WEAPON *p = gWR.GetFirstPos( iActiveSlot );
if( p )
9 years ago
iWidth = p->rcActive.right - p->rcActive.left;
else
iWidth = giBucketWidth;
}
else
iWidth = giBucketWidth;
9 years ago
SPR_DrawAdditive( 0, x, y, &gHUD.GetSpriteRect( m_HUD_bucket0 + i ) );
9 years ago
x += iWidth + 5;
}
a = 128; //!!!
x = 10;
// Draw all of the buckets
9 years ago
for( i = 0; i < MAX_WEAPON_SLOTS; i++ )
9 years ago
{
y = giBucketHeight + 10;
// If this is the active slot, draw the bigger pictures,
// otherwise just draw boxes
9 years ago
if( i == iActiveSlot )
9 years ago
{
WEAPON *p = gWR.GetFirstPos( i );
int iWidth = giBucketWidth;
9 years ago
if( p )
9 years ago
iWidth = p->rcActive.right - p->rcActive.left;
9 years ago
for( int iPos = 0; iPos < MAX_WEAPON_POSITIONS; iPos++ )
9 years ago
{
p = gWR.GetWeaponSlot( i, iPos );
9 years ago
if( !p || !p->iId )
9 years ago
continue;
9 years ago
UnpackRGB( r, g, b, RGB_YELLOWISH );
9 years ago
9 years ago
// if active, then we must have ammo.
if( gpActiveSel == p )
9 years ago
{
9 years ago
SPR_Set( p->hActive, r, g, b );
SPR_DrawAdditive( 0, x, y, &p->rcActive );
9 years ago
9 years ago
SPR_Set( gHUD.GetSprite( m_HUD_selection ), r, g, b );
SPR_DrawAdditive( 0, x, y, &gHUD.GetSpriteRect( m_HUD_selection ) );
9 years ago
}
else
{
// Draw Weapon if Red if no ammo
9 years ago
if( gWR.HasAmmo( p ) )
ScaleColors( r, g, b, 192 );
9 years ago
else
{
9 years ago
UnpackRGB( r, g, b, RGB_REDISH );
ScaleColors( r, g, b, 128 );
9 years ago
}
SPR_Set( p->hInactive, r, g, b );
SPR_DrawAdditive( 0, x, y, &p->rcInactive );
}
// Draw Ammo Bar
9 years ago
DrawAmmoBar( p, x + giABWidth / 2, y, giABWidth, giABHeight );
9 years ago
y += p->rcActive.bottom - p->rcActive.top + 5;
}
x += iWidth + 5;
}
else
{
// Draw Row of weapons.
9 years ago
UnpackRGB( r, g, b, RGB_YELLOWISH );
9 years ago
9 years ago
for( int iPos = 0; iPos < MAX_WEAPON_POSITIONS; iPos++ )
9 years ago
{
WEAPON *p = gWR.GetWeaponSlot( i, iPos );
9 years ago
if( !p || !p->iId )
9 years ago
continue;
9 years ago
if( gWR.HasAmmo( p ) )
9 years ago
{
9 years ago
UnpackRGB( r, g, b, RGB_YELLOWISH );
9 years ago
a = 128;
}
else
{
9 years ago
UnpackRGB( r, g, b, RGB_REDISH );
9 years ago
a = 96;
}
FillRGBA( x, y, giBucketWidth, giBucketHeight, r, g, b, a );
y += giBucketHeight + 5;
}
x += giBucketWidth + 5;
}
9 years ago
}
9 years ago
return 1;
}
/* =================================
GetSpriteList
Finds and returns the matching
sprite name 'psz' and resolution 'iRes'
in the given sprite list 'pList'
iCount is the number of items in the pList
================================= */
9 years ago
client_sprite_t *GetSpriteList( client_sprite_t *pList, const char *psz, int iRes, int iCount )
9 years ago
{
9 years ago
if( !pList )
9 years ago
return NULL;
int i = iCount;
client_sprite_t *p = pList;
9 years ago
while( i-- )
9 years ago
{
9 years ago
if( ( !strcmp( psz, p->szName ) ) && ( p->iRes == iRes ) )
9 years ago
return p;
p++;
}
return NULL;
}