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.
355 lines
9.8 KiB
355 lines
9.8 KiB
//========= Copyright Valve Corporation, All rights reserved. ============// |
|
// |
|
// Purpose: |
|
// |
|
// $NoKeywords: $ |
|
//=============================================================================// |
|
#include "cbase.h" |
|
#include "ObjectControlPanel.h" |
|
#include <vgui_controls/Controls.h> |
|
#include <vgui_controls/Label.h> |
|
#include "vgui_bitmapbutton.h" |
|
#include <vgui/ISurface.h> |
|
#include <vgui/IVGui.h> |
|
#include "C_BaseTFPlayer.h" |
|
#include "clientmode_tfbase.h" |
|
#include <vgui/IScheme.h> |
|
#include <vgui_controls/Slider.h> |
|
#include "vgui_rotation_slider.h" |
|
|
|
// memdbgon must be the last include file in a .cpp file!!! |
|
#include "tier0/memdbgon.h" |
|
|
|
|
|
#define DISMANTLE_WAIT_TIME 5.0 |
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
// Standard VGUI panel for objects |
|
//----------------------------------------------------------------------------- |
|
DECLARE_VGUI_SCREEN_FACTORY( CObjectControlPanel, "object_control_panel" ); |
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
// Constructor: |
|
//----------------------------------------------------------------------------- |
|
CObjectControlPanel::CObjectControlPanel( vgui::Panel *parent, const char *panelName ) |
|
: BaseClass( parent, panelName, g_hVGuiObjectScheme ) |
|
{ |
|
// Make some high-level panels to group stuff we want to activate/deactivate |
|
m_pActivePanel = new CCommandChainingPanel( this, "ActivePanel" ); |
|
m_pDeterioratingPanel = new CCommandChainingPanel( this, "DeterioratingPanel" ); |
|
m_pDismantlingPanel = new CCommandChainingPanel( this, "DismantlingPanel" ); |
|
|
|
SetCursor( vgui::dc_none ); // don't draw a VGUI cursor for this panel, and for its children |
|
|
|
// Make sure these are behind everything |
|
m_pActivePanel->SetZPos( -1 ); |
|
m_pDeterioratingPanel->SetZPos( -1 ); |
|
m_pDismantlingPanel->SetZPos( -1 ); |
|
} |
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
// Initialization |
|
//----------------------------------------------------------------------------- |
|
bool CObjectControlPanel::Init( KeyValues* pKeyValues, VGuiScreenInitData_t* pInitData ) |
|
{ |
|
// Grab ahold of certain well-known controls |
|
m_pHealthLabel = new vgui::Label( this, "HealthReadout", "" ); |
|
m_pOwnerLabel = new vgui::Label( this, "OwnerReadout", "" ); |
|
m_pDismantleButton = new CBitmapButton( this, "DismantleButton", "Dismantle" ); |
|
m_pAssumeControlButton = new CBitmapButton( GetDeterioratingPanel(), "AssumeControl", "" ); |
|
m_pDismantleTimeLabel = new vgui::Label( GetDismantlingPanel(), "DismantleTime", "" ); |
|
|
|
m_flDismantleTime = -1; |
|
|
|
// Make sure we get ticked... |
|
vgui::ivgui()->AddTickSignal( GetVPanel() ); |
|
|
|
if (!BaseClass::Init(pKeyValues, pInitData)) |
|
return false; |
|
|
|
SetCursor( vgui::dc_none ); // don't draw a VGUI cursor for this panel, and for its children |
|
|
|
// Make the bounds of the sub-panels match |
|
int x, y, w, h; |
|
GetBounds( x, y, w, h ); |
|
m_pActivePanel->SetBounds( x, y, w, h ); |
|
m_pDeterioratingPanel->SetBounds( x, y, w, h ); |
|
m_pDismantlingPanel->SetBounds( x, y, w, h ); |
|
|
|
// Make em all invisible |
|
m_pActivePanel->SetVisible( false ); |
|
m_pDeterioratingPanel->SetVisible( false ); |
|
m_pDismantlingPanel->SetVisible( false ); |
|
m_pCurrentPanel = m_pActivePanel; |
|
|
|
return true; |
|
} |
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
// Returns the object it's attached to |
|
//----------------------------------------------------------------------------- |
|
C_BaseObject *CObjectControlPanel::GetOwningObject() const |
|
{ |
|
C_BaseEntity *pScreenEnt = GetEntity(); |
|
if (!pScreenEnt) |
|
return NULL; |
|
|
|
C_BaseEntity *pObj = pScreenEnt->GetOwnerEntity(); |
|
if (!pObj) |
|
return NULL; |
|
|
|
Assert( dynamic_cast<C_BaseObject*>(pObj) ); |
|
return static_cast<C_BaseObject*>(pObj); |
|
} |
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
// Ticks the panel when its in its various states |
|
//----------------------------------------------------------------------------- |
|
|
|
void CObjectControlPanel::OnTickDeteriorating( C_BaseObject *pObj, C_BaseTFPlayer *pLocalPlayer ) |
|
{ |
|
char buf[256]; |
|
if ( pLocalPlayer && ClassCanBuild( pLocalPlayer->PlayerClass(), pObj->GetType() ) ) |
|
{ |
|
int nCost = CalculateObjectCost( pObj->GetType(), pLocalPlayer->GetNumObjects( pObj->GetType() ), pLocalPlayer->GetTeamNumber() ); |
|
Q_snprintf( buf, sizeof( buf ), "Buy for %d", nCost ); |
|
m_pAssumeControlButton->SetText( buf ); |
|
m_pAssumeControlButton->SetVisible( true ); |
|
|
|
bool bHasEnoughResources = pLocalPlayer->GetBankResources() >= nCost; |
|
m_pAssumeControlButton->SetEnabled( bHasEnoughResources ); |
|
} |
|
else |
|
{ |
|
m_pAssumeControlButton->SetVisible( false ); |
|
} |
|
|
|
ShowDismantleButton( false ); |
|
} |
|
|
|
void CObjectControlPanel::OnTickActive( C_BaseObject *pObj, C_BaseTFPlayer *pLocalPlayer ) |
|
{ |
|
ShowDismantleButton( !(pObj->GetFlags() & OF_CANNOT_BE_DISMANTLED) && pObj->GetOwner() == pLocalPlayer ); |
|
} |
|
|
|
void CObjectControlPanel::OnTickDismantling( C_BaseObject *pObj, C_BaseTFPlayer *pLocalPlayer ) |
|
{ |
|
ShowDismantleButton( false ); |
|
if ( !m_bDismantled && (gpGlobals->curtime >= m_flDismantleTime)) |
|
{ |
|
Dismantle(); |
|
m_bDismantled = true; |
|
} |
|
|
|
int nSec = (int)(m_flDismantleTime - gpGlobals->curtime + 0.5f); |
|
if (nSec < 0) |
|
nSec = 0; |
|
|
|
char buf[256]; |
|
int nLen = Q_snprintf( buf, sizeof( buf ), "%d second", nSec ); |
|
if (nSec != 1) |
|
{ |
|
buf[nLen] = 's'; |
|
++nLen; |
|
buf[nLen] = 0; |
|
} |
|
|
|
m_pDismantleTimeLabel->SetText( buf ); |
|
} |
|
|
|
|
|
vgui::Panel* CObjectControlPanel::TickCurrentPanel() |
|
{ |
|
C_BaseTFPlayer *pLocalPlayer = C_BaseTFPlayer::GetLocalPlayer(); |
|
C_BaseObject *pObj = GetOwningObject(); |
|
|
|
if (IsDismantling()) |
|
{ |
|
m_pCurrentPanel = GetDismantlingPanel(); |
|
|
|
OnTickDismantling(pObj, pLocalPlayer); |
|
} |
|
else if (pObj->IsDeteriorating()) |
|
{ |
|
m_pCurrentPanel = GetDeterioratingPanel(); |
|
|
|
OnTickDeteriorating(pObj, pLocalPlayer); |
|
} |
|
else |
|
{ |
|
m_pCurrentPanel = GetActivePanel(); |
|
|
|
OnTickActive(pObj, pLocalPlayer); |
|
} |
|
|
|
return m_pCurrentPanel; |
|
} |
|
|
|
|
|
void CObjectControlPanel::ShowDismantleButton( bool bShow ) |
|
{ |
|
m_pDismantleButton->SetVisible( bShow ); |
|
} |
|
|
|
|
|
void CObjectControlPanel::ShowOwnerLabel( bool bShow ) |
|
{ |
|
m_pOwnerLabel->SetVisible( bShow ); |
|
} |
|
|
|
|
|
void CObjectControlPanel::ShowHealthLabel( bool bShow ) |
|
{ |
|
m_pHealthLabel->SetVisible( bShow ); |
|
} |
|
|
|
|
|
void CObjectControlPanel::SendToServerObject( const char *pMsg ) |
|
{ |
|
C_BaseObject *pObj = GetOwningObject(); |
|
if (pObj) |
|
{ |
|
pObj->SendClientCommand( pMsg ); |
|
} |
|
} |
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
// Frame-based update |
|
//----------------------------------------------------------------------------- |
|
void CObjectControlPanel::OnTick() |
|
{ |
|
BaseClass::OnTick(); |
|
|
|
C_BaseObject *pObj = GetOwningObject(); |
|
if (!pObj) |
|
return; |
|
|
|
char buf[256]; |
|
Q_snprintf( buf, sizeof( buf ), "Health: %d%%", (int)(pObj->HealthFraction() * 100.0f) ); |
|
m_pHealthLabel->SetText( buf ); |
|
|
|
C_BaseTFPlayer *pPlayer = pObj->GetOwner(); |
|
if (pPlayer) |
|
{ |
|
Q_snprintf( buf, sizeof( buf ), "Owner: %s", pPlayer->GetPlayerName() ); |
|
} |
|
else |
|
{ |
|
Q_snprintf( buf, sizeof( buf ), "No Owner" ); |
|
} |
|
|
|
m_pOwnerLabel->SetText( buf ); |
|
|
|
// Update the current subpanel |
|
m_pCurrentPanel->SetVisible( false ); |
|
|
|
m_pCurrentPanel = TickCurrentPanel(); |
|
|
|
m_pCurrentPanel->SetVisible( true ); |
|
} |
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
// Dismantles the object |
|
//----------------------------------------------------------------------------- |
|
void CObjectControlPanel::Dismantle() |
|
{ |
|
SendToServerObject( "dismantle" ); |
|
} |
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
// Starts/stops dismantling |
|
//----------------------------------------------------------------------------- |
|
void CObjectControlPanel::StartDismantling() |
|
{ |
|
m_flDismantleTime = gpGlobals->curtime + DISMANTLE_WAIT_TIME; |
|
m_bDismantled = false; |
|
} |
|
|
|
void CObjectControlPanel::StopDismantling() |
|
{ |
|
m_flDismantleTime = -1.0f; |
|
} |
|
|
|
bool CObjectControlPanel::IsDismantling() const |
|
{ |
|
return m_flDismantleTime >= 0.0f; |
|
} |
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
// Assumes control of the object |
|
//----------------------------------------------------------------------------- |
|
void CObjectControlPanel::AssumeControl() |
|
{ |
|
SendToServerObject( "takecontrol" ); |
|
} |
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
// Button click handlers |
|
//----------------------------------------------------------------------------- |
|
void CObjectControlPanel::OnCommand( const char *command ) |
|
{ |
|
if (!Q_strnicmp(command, "Dismantle", 10)) |
|
{ |
|
StartDismantling(); |
|
return; |
|
} |
|
|
|
if (!Q_strnicmp(command, "CancelDismantle", 20)) |
|
{ |
|
StopDismantling(); |
|
return; |
|
} |
|
|
|
if (!Q_strnicmp(command, "AssumeControl", 15)) |
|
{ |
|
AssumeControl(); |
|
return; |
|
} |
|
|
|
BaseClass::OnCommand(command); |
|
} |
|
|
|
|
|
DECLARE_VGUI_SCREEN_FACTORY( CRotatingObjectControlPanel, "rotating_object_control_panel" ); |
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
// This is a panel for an object that has rotational controls |
|
//----------------------------------------------------------------------------- |
|
CRotatingObjectControlPanel::CRotatingObjectControlPanel( vgui::Panel *parent, const char *panelName ) |
|
: BaseClass( parent, panelName ) |
|
{ |
|
} |
|
|
|
bool CRotatingObjectControlPanel::Init( KeyValues* pKeyValues, VGuiScreenInitData_t* pInitData ) |
|
{ |
|
// Grab ahold of certain well-known controls |
|
m_pRotationSlider = new CRotationSlider( GetActivePanel(), "RotationSlider" ); |
|
m_pRotationLabel = new vgui::Label( GetActivePanel(), "RotationLabel", "Rotation Control" ); |
|
|
|
if (!BaseClass::Init(pKeyValues, pInitData)) |
|
return false; |
|
|
|
m_pRotationSlider->SetControlledObject( GetOwningObject() ); |
|
|
|
return true; |
|
} |
|
|
|
void CRotatingObjectControlPanel::OnTickActive( C_BaseObject *pObj, C_BaseTFPlayer *pLocalPlayer ) |
|
{ |
|
BaseClass::OnTickActive( pObj, pLocalPlayer ); |
|
bool bEnable = (pObj->GetOwner() == pLocalPlayer); |
|
m_pRotationSlider->SetVisible( bEnable ); |
|
m_pRotationLabel->SetVisible( bEnable ); |
|
} |
|
|
|
|