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.
356 lines
9.8 KiB
356 lines
9.8 KiB
5 years ago
|
//========= 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 );
|
||
|
}
|
||
|
|