//========= Copyright Valve Corporation, All rights reserved. ============// // // Purpose: Client's CWeaponBuilder class // // $Workfile: $ // $Date: $ // $NoKeywords: $ //=============================================================================// #include "cbase.h" #include "hud.h" #include "in_buttons.h" #include "clientmode_tfnormal.h" #include "engine/IEngineSound.h" #include "c_weapon_builder.h" #include "c_weapon__stubs.h" #include "iinput.h" #include "ObjectControlPanel.h" #include #define BUILD_ICON_SCALE 0.75 #define BUILD_ICON_BOTTOM_OFFSET YRES(160) //----------------------------------------------------------------------------- // Purpose: Draw a material on a quad //----------------------------------------------------------------------------- void DrawQuadMaterial( IMaterial *pMaterial, int iX, int iY, int iWidth, int iHeight, unsigned char r = 255, unsigned char g = 255, unsigned char b = 255, unsigned char a = 255, float flTextureLeft = 0.0, float flTextureRight = 1.0, bool bRotated = false ) { IMesh* pMesh = materials->GetDynamicMesh( true, NULL, NULL, pMaterial ); CMeshBuilder meshBuilder; meshBuilder.Begin( pMesh, MATERIAL_QUADS, 1 ); meshBuilder.Color4ub( r, g, b, a ); if ( bRotated ) { meshBuilder.TexCoord2f( 0,flTextureLeft,1 ); } else { meshBuilder.TexCoord2f( 0,flTextureLeft,0 ); } meshBuilder.Position3f( iX,iY,0 ); meshBuilder.AdvanceVertex(); meshBuilder.Color4ub( r, g, b, a ); if ( bRotated ) { meshBuilder.TexCoord2f( 0,flTextureLeft,0 ); } else { meshBuilder.TexCoord2f( 0,flTextureRight,0 ); } meshBuilder.Position3f( iX+iWidth, iY, 0 ); meshBuilder.AdvanceVertex(); meshBuilder.Color4ub( r, g, b, a ); if ( bRotated ) { meshBuilder.TexCoord2f( 0,flTextureRight,0 ); } else { meshBuilder.TexCoord2f( 0,flTextureRight,1 ); } meshBuilder.Position3f( iX+iWidth, iY+iHeight, 0 ); meshBuilder.AdvanceVertex(); meshBuilder.Color4ub( r, g, b, a ); if ( bRotated ) { meshBuilder.TexCoord2f( 0,flTextureRight,1 ); } else { meshBuilder.TexCoord2f( 0,flTextureLeft,1 ); } meshBuilder.Position3f( iX, iY+iHeight, 0 ); meshBuilder.AdvanceVertex(); meshBuilder.End(); pMesh->Draw(); } STUB_WEAPON_CLASS_IMPLEMENT( weapon_builder, C_WeaponBuilder ); IMPLEMENT_CLIENTCLASS_DT(C_WeaponBuilder, DT_WeaponBuilder, CWeaponBuilder) RecvPropInt( RECVINFO(m_iBuildState) ), RecvPropInt( RECVINFO(m_iCurrentObject) ), RecvPropInt( RECVINFO(m_iCurrentObjectState) ), RecvPropEHandle( RECVINFO(m_hObjectBeingBuilt) ), RecvPropTime( RECVINFO(m_flStartTime) ), RecvPropTime( RECVINFO(m_flTotalTime) ), RecvPropArray ( RecvPropInt( RECVINFO(m_bObjectValidity[0])), m_bObjectValidity ), RecvPropArray ( RecvPropInt( RECVINFO(m_bObjectBuildability[0])), m_bObjectBuildability ), END_RECV_TABLE() //----------------------------------------------------------------------------- // Purpose: //----------------------------------------------------------------------------- C_WeaponBuilder::C_WeaponBuilder() { m_iBuildState = 0; m_iCurrentObject = BUILDER_INVALID_OBJECT; m_iCurrentObjectState = 0; m_flStartTime = 0; m_flTotalTime = 0; m_pIconFireToSelect.Init( "Hud/build/firetobuild", TEXTURE_GROUP_VGUI ); } //----------------------------------------------------------------------------- // Purpose: //----------------------------------------------------------------------------- C_WeaponBuilder::~C_WeaponBuilder() { } //----------------------------------------------------------------------------- // A couple helper methods for drawing builder status //----------------------------------------------------------------------------- static void DrawTextIcon( IMaterial* pMaterial, int parentWidth, int parentHeight, float r = 1.0f, float g = 1.0f, float b = 1.0f ) { if ( !pMaterial ) return; // We're in build selection mode, so draw the current build icon int iWidth = pMaterial->GetMappingWidth(); int iHeight = pMaterial->GetMappingHeight(); int iX = (parentWidth - iWidth) / 2; int iY = (parentHeight - 216); DrawQuadMaterial( pMaterial, iX, iY, iWidth, iHeight, r * 255, g * 255, b * 255 ); } //----------------------------------------------------------------------------- // Purpose: // Output : char const //----------------------------------------------------------------------------- const char *C_WeaponBuilder::GetCurrentSelectionObjectName( void ) { if ( m_iCurrentObject == -1 || (m_iBuildState == BS_SELECTING) ) return ""; return GetObjectInfo( m_iCurrentObject )->m_pBuilderWeaponName; } //----------------------------------------------------------------------------- // Purpose: //----------------------------------------------------------------------------- void C_WeaponBuilder::Redraw() { BaseClass::Redraw(); // Don't draw if we're hiding the weapons, or the player's dead if ( gHUD.IsHidden( HIDEHUD_WEAPONSELECTION | HIDEHUD_PLAYERDEAD ) ) return; C_BaseTFPlayer *pPlayer = C_BaseTFPlayer::GetLocalPlayer(); if (!pPlayer) return; vgui::Panel *pParent = GetClientModeNormal()->GetViewport(); int parentWidth, parentHeight; pParent->GetSize(parentWidth, parentHeight); // If we're in placement mode, draw the placement icon switch( m_iBuildState ) { case BS_PLACING: case BS_PLACING_INVALID: break; default: { if( !inv_demo.GetInt() ) { DrawTextIcon( m_pIconFireToSelect, parentWidth, parentHeight ); } break; } break; } } //----------------------------------------------------------------------------- // Purpose: // Output : Returns true on success, false on failure. //----------------------------------------------------------------------------- bool C_WeaponBuilder::IsPlacingObject( void ) { if ( m_iBuildState == BS_PLACING || m_iBuildState == BS_PLACING_INVALID ) return true; return false; } //----------------------------------------------------------------------------- // Purpose: // Output : Returns true on success, false on failure. //----------------------------------------------------------------------------- bool C_WeaponBuilder::IsBuildingObject( void ) { if ( m_iBuildState == BS_BUILDING ) return true; return false; } #include "vgui_bitmapimage.h" #include "vgui_bitmappanel.h" //----------------------------------------------------------------------------- // Control screen //----------------------------------------------------------------------------- class CHumanPDAPanel : public CVGuiScreenPanel { DECLARE_CLASS( CHumanPDAPanel, CVGuiScreenPanel ); public: CHumanPDAPanel( vgui::Panel *parent, const char *panelName ); ~CHumanPDAPanel(); virtual bool Init( KeyValues* pKeyValues, VGuiScreenInitData_t* pInitData ); virtual void OnTick(); private: C_BaseCombatWeapon *GetOwningWeapon(); vgui::Label *m_pObjectName; vgui::Label *m_pObjectCost; vgui::Label *m_pObjectOnTeamCount; vgui::Label *m_pObjectPlacementDetails; CBitmapPanel *m_pBitmapPanel; BitmapImage *m_pObjectImage; int m_nLastObjectID; int m_nLastObjectCount; int m_nLastObjectCost; }; DECLARE_VGUI_SCREEN_FACTORY( CHumanPDAPanel, "human_pda" ); //----------------------------------------------------------------------------- // Constructor: //----------------------------------------------------------------------------- CHumanPDAPanel::CHumanPDAPanel( vgui::Panel *parent, const char *panelName ) : BaseClass( parent, "CHumanPDAPanel", vgui::scheme()->LoadSchemeFromFileEx( enginevgui->GetPanel( PANEL_CLIENTDLL ), "resource/PDAControlPanelScheme.res", "TFBase" ) ) { m_pObjectImage = NULL; m_pObjectName = new vgui::Label( this, "ObjectName", "" ); m_pObjectCost = new vgui::Label( this, "ObjectCost", "" ); m_pObjectOnTeamCount = new vgui::Label( this, "ObjectOnTeamCount", "" ); m_pObjectPlacementDetails = new vgui::Label( this, "ObjectPlacementDetails", "" ); m_pBitmapPanel = new CBitmapPanel( this, "ObjectImage" ); m_pObjectImage = new BitmapImage(); m_pObjectImage->UsePanelRenderSize( m_pBitmapPanel->GetVPanel() ); m_pBitmapPanel->SetImage( m_pObjectImage ); m_nLastObjectID = -1; m_nLastObjectCount = -1; m_nLastObjectCost = -1; } CHumanPDAPanel::~CHumanPDAPanel() { if ( m_pObjectImage ) { delete m_pObjectImage; } } //----------------------------------------------------------------------------- // Initialization //----------------------------------------------------------------------------- bool CHumanPDAPanel::Init( KeyValues* pKeyValues, VGuiScreenInitData_t* pInitData ) { // Make sure we get ticked... vgui::ivgui()->AddTickSignal( GetVPanel() ); if (!BaseClass::Init(pKeyValues, pInitData)) return false; return true; } //----------------------------------------------------------------------------- // Returns the object it's attached to //----------------------------------------------------------------------------- C_BaseCombatWeapon *CHumanPDAPanel::GetOwningWeapon() { C_BaseEntity *pScreenEnt = GetEntity(); if (!pScreenEnt) return NULL; C_BaseEntity *pOwner = pScreenEnt->GetOwnerEntity(); if (!pOwner) return NULL; C_BaseViewModel *pViewModel = dynamic_cast< C_BaseViewModel * >( pOwner ); if ( !pViewModel ) return NULL; return pViewModel->GetOwningWeapon(); } //----------------------------------------------------------------------------- // Frame-based update //----------------------------------------------------------------------------- void CHumanPDAPanel::OnTick() { BaseClass::OnTick(); SetVisible( true ); char buf[256]; C_BaseCombatWeapon *weapon = GetOwningWeapon(); if ( !weapon ) return; C_WeaponBuilder *builder = dynamic_cast< C_WeaponBuilder * >( weapon ); if ( !builder ) return; CBaseTFPlayer *pOwner = ToBaseTFPlayer( builder->GetOwner() ); if ( !pOwner ) return; // FIXME: Check build state?? int objectType = builder->m_iCurrentObject; CObjectInfo const *info = GetObjectInfo( objectType ); if ( !info ) return; int numOwned = pOwner->GetNumObjects(objectType); int iCost = CalculateObjectCost( objectType, numOwned, pOwner->GetTeamNumber() ); if ( m_nLastObjectID == objectType && m_nLastObjectCount == numOwned && m_nLastObjectCost == iCost) return; m_nLastObjectID = objectType; m_nLastObjectCount = numOwned; m_nLastObjectCost = iCost; Q_snprintf( buf, sizeof( buf ), "hud/menu/%s", info->m_pClassName ); m_pObjectImage->SetImageFile( buf ); m_pObjectImage->SetColor( GetFgColor() ); Q_snprintf( buf, sizeof( buf ), "%s", info->m_pStatusName ); m_pObjectName->SetText( buf ); Q_snprintf( buf, sizeof( buf ), "Cost: %i", iCost ); m_pObjectCost->SetText( buf ); Q_snprintf( buf, sizeof( buf ), "You own: %i", numOwned ); m_pObjectOnTeamCount->SetText( buf ); Q_snprintf( buf, sizeof( buf ), "%s", info->m_pBuilderPlacementString ? info->m_pBuilderPlacementString : "" ); m_pObjectPlacementDetails->SetText( buf ); //m_pObjectPlacementDetails->SizeToContents(); }