summaryrefslogtreecommitdiff
path: root/game/client/tf2/c_order.cpp
diff options
context:
space:
mode:
authorFluorescentCIAAfricanAmerican <[email protected]>2020-04-22 12:56:21 -0400
committerFluorescentCIAAfricanAmerican <[email protected]>2020-04-22 12:56:21 -0400
commit3bf9df6b2785fa6d951086978a3e66f49427166a (patch)
tree2c0f1f0c63c4832882bc93814ebd2c2b1c6224e5 /game/client/tf2/c_order.cpp
downloadarchived-source-engine-2018-hl2-src-master.tar.xz
archived-source-engine-2018-hl2-src-master.zip
Diffstat (limited to 'game/client/tf2/c_order.cpp')
-rw-r--r--game/client/tf2/c_order.cpp462
1 files changed, 462 insertions, 0 deletions
diff --git a/game/client/tf2/c_order.cpp b/game/client/tf2/c_order.cpp
new file mode 100644
index 0000000..4309e63
--- /dev/null
+++ b/game/client/tf2/c_order.cpp
@@ -0,0 +1,462 @@
+//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// Purpose: Client Side COrder class
+//
+// $NoKeywords: $
+//=============================================================================//
+#include "cbase.h"
+#include "hud_orders.h"
+#include "c_order.h"
+#include <vgui_controls/Controls.h>
+#include <vgui/ISurface.h>
+#include "minimap_trace.h"
+#include "VGuiMatSurface/IMatSystemSurface.h"
+#include "c_func_resource.h"
+#include "tf_shareddefs.h"
+#include "c_baseobject.h"
+#include "tf_hints.h"
+#include "hud.h"
+#include "c_basetfplayer.h"
+#include "c_tf_hintmanager.h"
+#include "clientmode_tfnormal.h"
+
+#define NEW_ORDER_ANIM_DURATION 1.0f
+#define NEW_ORDERS_RIGHT XRES(640-8)
+#define NEW_ORDERS_LEFT XRES(8)
+#define NEW_ORDERS_WIDTH (ORDERS_RIGHT - NEW_ORDERS_LEFT) //(NEW_ORDERS_RIGHT - ORDERS_LEFT)
+
+
+class COrderLabel : public vgui::Label
+{
+public:
+ COrderLabel( vgui::Panel *pParent, const char *pPanelName, const char *pText )
+ : vgui::Label( pParent, pPanelName, pText )
+ {
+ }
+
+ virtual void OnThink()
+ {
+ BaseClass::OnThink();
+
+ // Resize?
+ int x, y, w, h;
+ if( m_flAnimCounter < NEW_ORDER_ANIM_DURATION )
+ {
+ int wantedWidth, dummy;
+ GetContentSize( wantedWidth, dummy );
+ wantedWidth += 10;
+
+ float flPercent = m_flAnimCounter / NEW_ORDER_ANIM_DURATION;
+ int newWidth = (int)(NEW_ORDERS_WIDTH + (wantedWidth - NEW_ORDERS_WIDTH) * flPercent);
+
+ GetBounds( x, y, w, h );
+
+ m_flAnimCounter += gpGlobals->frametime;
+ if( m_flAnimCounter >= NEW_ORDER_ANIM_DURATION )
+ {
+ SetBounds( ORDERS_RIGHT - wantedWidth, y, wantedWidth, h );
+ }
+ else
+ {
+ SetBounds( ORDERS_RIGHT - newWidth, y, newWidth, h );
+ }
+ }
+ }
+
+ virtual void PaintBackground()
+ {
+ // BaseClass::PaintBackground();
+
+ // Draw our background.
+ int x, y, w, h;
+ GetBounds( x, y, w, h );
+
+ vgui::surface()->DrawSetColor( Color( 0, 0, 0, 160 ) );
+ vgui::surface()->DrawFilledRect( 0, 0, w, h );
+
+ vgui::surface()->DrawSetColor( Color( 63, 63, 63, 255 ) );
+ vgui::surface()->DrawOutlinedRect( 0, 0, w, h );
+ }
+
+public:
+ float m_flAnimCounter;
+};
+
+
+class CMinimapOrderPanel : public CMinimapTraceBitmapPanel
+{
+ DECLARE_CLASS( CMinimapOrderPanel, CMinimapTraceBitmapPanel );
+
+public:
+ CMinimapOrderPanel( vgui::Panel *parent, const char *panelName )
+ : BaseClass( parent, "CMinimapOrderPanel" )
+ {
+ }
+ virtual bool Init( KeyValues* pKeyValues, MinimapInitData_t* pInitData );
+ virtual void OnTick();
+ virtual void Paint( );
+
+private:
+ C_Order *m_pOrder;
+};
+
+
+DECLARE_MINIMAP_FACTORY( CMinimapOrderPanel, "minimap_order_panel" );
+
+bool CMinimapOrderPanel::Init( KeyValues* pKeyValues, MinimapInitData_t* pInitData )
+{
+ m_pOrder = dynamic_cast<C_Order*>(pInitData->m_pEntity);
+ if (!m_pOrder)
+ return false;
+
+ if (!BaseClass::Init( pKeyValues, pInitData ))
+ return false;
+
+ return true;
+}
+
+//-----------------------------------------------------------------------------
+// called when we're ticked...
+//-----------------------------------------------------------------------------
+void CMinimapOrderPanel::OnTick()
+{
+ // NOTE: Do *not* chain down the the base OnTick; it's going to do
+ // a totally different computation that will conflict with ours
+ Assert( m_pOrder );
+ if( m_pOrder->GetTarget() <= 0 )
+ {
+ SetVisible(false);
+ return;
+ }
+
+ C_BaseEntity *pTarget = ClientEntityList().GetEnt( m_pOrder->GetTarget() );
+ if( !pTarget )
+ {
+ SetVisible(false);
+ return;
+ }
+
+ SetEntity( pTarget );
+
+ // Now that we're attached to the correct target, compute position!
+ BaseClass::OnTick();
+}
+
+
+void CMinimapOrderPanel::Paint( )
+{
+ Assert( m_pOrder );
+
+ if( m_pOrder->GetTarget() <= 0 )
+ return;
+
+ C_BaseEntity *pTarget = ClientEntityList().GetEnt( m_pOrder->GetTarget() );
+ if( !pTarget )
+ return;
+
+ g_pMatSystemSurface->DisableClipping( true );
+
+ static float flStrobeDuration = 0.5;
+ float flShade = sin( gpGlobals->curtime * M_PI / flStrobeDuration ) * 0.5f + 0.5f;
+
+ Color color(255*flShade, 0, 0, 255);
+ m_Image.SetColor( color );
+ m_Image.Paint();
+
+ g_pMatSystemSurface->DisableClipping( false );
+}
+
+
+
+enum GetTargetDescriptionType_t
+{
+ GETDESC_RESOURCEZONE=0,
+ GETDESC_OBJECT
+};
+
+char* GetTargetDescription( int entindex, GetTargetDescriptionType_t type )
+{
+ static char szDesc[128];
+ szDesc[0]=0;
+
+ // Order target
+ if ( entindex )
+ {
+ C_BaseEntity *pEnt = cl_entitylist->GetEnt( entindex );
+ if ( pEnt )
+ {
+ if( type == GETDESC_RESOURCEZONE )
+ {
+ C_ResourceZone *pZone = dynamic_cast<C_ResourceZone*>(pEnt);
+ if ( pZone )
+ Q_strncpy( szDesc, pZone->GetTargetDescription(), sizeof( szDesc ) );
+ }
+ else if( type == GETDESC_OBJECT )
+ {
+ C_BaseObject *pObj = dynamic_cast<C_BaseObject*>( pEnt );
+ if( pObj )
+ Q_strncpy( szDesc, pObj->GetTargetDescription(), sizeof( szDesc ) );
+ }
+ }
+ }
+
+ return szDesc;
+}
+
+
+IMPLEMENT_CLIENTCLASS_DT(C_Order, DT_Order, COrder)
+ RecvPropInt( RECVINFO(m_iPriority) ),
+ RecvPropInt( RECVINFO(m_iOrderType) ),
+ RecvPropInt( RECVINFO(m_iTargetEntIndex) ),
+END_RECV_TABLE()
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+C_Order::C_Order( void )
+{
+ m_nHintID = TF_HINT_UNDEFINED;
+
+ m_pNameLabel = NULL;
+
+ CONSTRUCT_MINIMAP_PANEL( "minimap_order", MINIMAP_PERSONAL_ORDERS );
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+C_Order::~C_Order( void )
+{
+ RemoveOrder();
+
+ if( C_BaseTFPlayer::GetLocalPlayer() )
+ C_BaseTFPlayer::GetLocalPlayer()->RemoveOrderTarget();
+
+
+ if ( m_nHintID != TF_HINT_UNDEFINED )
+ {
+ DestroyGlobalHint( m_nHintID );
+ }
+}
+
+void C_Order::ClientThink( void )
+{
+ BaseClass::ClientThink();
+
+ if ( m_nHintID != TF_HINT_UNDEFINED )
+ {
+ switch ( m_iOrderType )
+ {
+ case ORDER_REPAIR:
+ m_nHintID = TF_HINT_REPAIROBJECT;
+ break;
+ default:
+ break;
+ }
+ }
+
+ if ( m_nHintID != TF_HINT_UNDEFINED )
+ {
+ CreateGlobalHint_Panel( m_pNameLabel, m_nHintID, NULL, index );
+ }
+}
+
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void C_Order::OnDataChanged( DataUpdateType_t updateType )
+{
+ BaseClass::OnDataChanged( updateType );
+
+ C_BaseTFPlayer *pPlayer = C_BaseTFPlayer::GetLocalPlayer();
+ pPlayer->SetPersonalOrder( this );
+
+ // Update us if we've changed
+ if( updateType == DATA_UPDATE_CREATED )
+ {
+ CreateStatus( GetClientModeNormal()->GetViewport() );
+ }
+ else
+ {
+ GetHudOrderList()->RecalculateOrderList();
+ UpdateStatus();
+ }
+
+ if( m_iTargetEntIndex > 0 )
+ {
+ C_BaseEntity *pTarget = ClientEntityList().GetEnt( m_iTargetEntIndex );
+ m_OverlayPanel.Activate( pTarget, "personal_order", true );
+ }
+
+ if ( (updateType == DATA_UPDATE_CREATED) && ( m_nHintID != TF_HINT_UNDEFINED ) )
+ {
+ // Wait for animation to fly all the way in
+ SetNextClientThink( gpGlobals->curtime + NEW_ORDER_ANIM_DURATION + 0.25f );
+ }
+}
+
+
+//-----------------------------------------------------------------------------
+// Purpose: Clean up a removed order
+//-----------------------------------------------------------------------------
+void C_Order::RemoveOrder( void )
+{
+ m_OverlayPanel.RemoveOverlay();
+
+ DestroyStatus();
+
+ if ( m_pNameLabel )
+ {
+ delete m_pNameLabel;
+ m_pNameLabel = NULL;
+ }
+}
+
+//-----------------------------------------------------------------------------
+// Purpose: Get a text description of this order
+//-----------------------------------------------------------------------------
+void C_Order::GetDescription( char *pDest, int bufferSize )
+{
+ char targetDesc[512];
+ GetTargetDescription( targetDesc, sizeof( targetDesc ) );
+
+ switch ( m_iOrderType )
+ {
+ case ORDER_ATTACK:
+ Q_snprintf( pDest, bufferSize, "Attack %s", targetDesc );
+ break;
+
+ case ORDER_DEFEND:
+ Q_snprintf( pDest, bufferSize, "Defend %s", targetDesc );
+ break;
+
+ case ORDER_CAPTURE:
+ Q_snprintf( pDest, bufferSize, "Capture %s", targetDesc );
+ break;
+
+ default:
+ Q_snprintf( pDest, bufferSize, "INVALID" );
+ break;
+ }
+}
+
+//-----------------------------------------------------------------------------
+// Purpose: Get a text description for the target of this order
+//-----------------------------------------------------------------------------
+void C_Order::GetTargetDescription( char *pDest, int bufferSize )
+{
+ pDest[0] = 0;
+
+ if ( !m_iTargetEntIndex )
+ return;
+
+ C_BaseEntity *pEnt = cl_entitylist->GetEnt( m_iTargetEntIndex );
+ if ( !pEnt )
+ return;
+
+ C_ResourceZone *pZone = dynamic_cast<C_ResourceZone*>(pEnt);
+ if ( pZone )
+ {
+ Q_strncpy( pDest, pZone->GetTargetDescription(), bufferSize );
+ }
+ else
+ {
+ C_BaseObject *pObj = dynamic_cast<C_BaseObject*>( pEnt );
+ if( pObj )
+ Q_strncpy( pDest, pObj->GetTargetDescription(), bufferSize );
+ }
+}
+
+
+//-----------------------------------------------------------------------------
+// Purpose: Create all elements needed in a status panel for this order
+//-----------------------------------------------------------------------------
+void C_Order::CreateStatus( vgui::Panel *pParent )
+{
+ // If we already have our elements, we're just moving.
+ if ( m_pNameLabel )
+ {
+ m_pNameLabel->SetParent( pParent );
+ }
+ else
+ {
+ m_pNameLabel = new COrderLabel( pParent, "NameLabel", "Temp" );
+ m_pNameLabel->SetBounds( ORDERS_LEFT, ORDERS_TOP, NEW_ORDERS_WIDTH, ORDERS_ELEMENT_HEIGHT );
+ m_pNameLabel->SetAutoDelete( false );
+ m_pNameLabel->SetPaintBackgroundEnabled( true );
+ m_pNameLabel->SetFgColor( Color( 0, 0, 0, 255 ) );
+ m_pNameLabel->SetContentAlignment( vgui::Label::a_east );
+ m_pNameLabel->SetTextInset( -2, 0 );
+ }
+
+ UpdateStatus();
+}
+
+//-----------------------------------------------------------------------------
+// Purpose: Destroy all elements in the status panel for this order
+//-----------------------------------------------------------------------------
+void C_Order::DestroyStatus( void )
+{
+ if ( m_pNameLabel )
+ {
+ delete m_pNameLabel;
+ m_pNameLabel = NULL;
+ }
+}
+
+//-----------------------------------------------------------------------------
+// Purpose: Update all elements in the status panel for this order
+//-----------------------------------------------------------------------------
+void C_Order::UpdateStatus( void )
+{
+ if ( m_pNameLabel )
+ {
+ char desc[512];
+ GetDescription( desc, sizeof( desc ) );
+
+ m_pNameLabel->SetText( desc );
+ m_pNameLabel->m_flAnimCounter = 0;
+ }
+}
+
+//-----------------------------------------------------------------------------
+// Purpose: Return true if this order wants a target reticle created around it's target
+//-----------------------------------------------------------------------------
+bool C_Order::ShouldDrawReticle( void )
+{
+ return true;
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+int C_Order::GetPriority( void )
+{
+ return m_iPriority;
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+int C_Order::GetType( void )
+{
+ return m_iOrderType;
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+int C_Order::GetTarget( void )
+{
+ return m_iTargetEntIndex;
+}
+
+//-----------------------------------------------------------------------------
+// Purpose: Return true if this order is a personal one for this player
+//-----------------------------------------------------------------------------
+bool C_Order::IsPersonalOrder( void )
+{
+ return (GetPriority() == 0);
+}
+