mirror of
https://github.com/nillerusr/source-engine.git
synced 2026-08-12 03:39:10 +00:00
1
This commit is contained in:
@@ -0,0 +1,117 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================//
|
||||
#include "cbase.h"
|
||||
#include "proxyentity.h"
|
||||
#include "materialsystem/imaterial.h"
|
||||
#include "materialsystem/imaterialvar.h"
|
||||
#include "c_baseobject.h"
|
||||
#include <KeyValues.h>
|
||||
|
||||
// memdbgon must be the last include file in a .cpp file!!!
|
||||
#include "tier0/memdbgon.h"
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
class CObjectBuildAlphaProxy : public CEntityMaterialProxy
|
||||
{
|
||||
public:
|
||||
CObjectBuildAlphaProxy();
|
||||
virtual ~CObjectBuildAlphaProxy();
|
||||
virtual bool Init( IMaterial *pMaterial, KeyValues* pKeyValues );
|
||||
virtual void OnBind( C_BaseEntity *pC_BaseEntity );
|
||||
|
||||
private:
|
||||
IMaterialVar* m_pAlphaVar;
|
||||
|
||||
float buildstart;
|
||||
float buildend;
|
||||
};
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Constructor, destructor
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
CObjectBuildAlphaProxy::CObjectBuildAlphaProxy()
|
||||
{
|
||||
m_pAlphaVar = 0;
|
||||
}
|
||||
|
||||
CObjectBuildAlphaProxy::~CObjectBuildAlphaProxy()
|
||||
{
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Init baby...
|
||||
//-----------------------------------------------------------------------------
|
||||
bool CObjectBuildAlphaProxy::Init( IMaterial *pMaterial, KeyValues* pKeyValues )
|
||||
{
|
||||
|
||||
bool foundVar;
|
||||
m_pAlphaVar = pMaterial->FindVar( "$alpha", &foundVar, false );
|
||||
if( !foundVar )
|
||||
{
|
||||
m_pAlphaVar = 0;
|
||||
}
|
||||
|
||||
buildstart = pKeyValues->GetFloat( "buildstart", 1.0f );
|
||||
buildend = pKeyValues->GetFloat( "buildfinish", 1.0f );
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Set the appropriate texture...
|
||||
//-----------------------------------------------------------------------------
|
||||
void CObjectBuildAlphaProxy::OnBind( C_BaseEntity *pEntity )
|
||||
{
|
||||
if( !m_pAlphaVar )
|
||||
return;
|
||||
|
||||
// It needs to be a TF2 C_BaseObject to have this proxy applied
|
||||
C_BaseObject *pObject = dynamic_cast< C_BaseObject * >( pEntity );
|
||||
if ( !pObject )
|
||||
return;
|
||||
|
||||
float build_amount = pObject->GetCycle(); //pObject->GetPercentageConstructed();
|
||||
float frac;
|
||||
|
||||
if ( build_amount <= buildstart )
|
||||
{
|
||||
frac = 0.0f;
|
||||
}
|
||||
else if ( build_amount >= buildend )
|
||||
{
|
||||
frac = 1.0f;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Avoid div by zero
|
||||
if ( buildend == buildstart )
|
||||
{
|
||||
frac = 1.0f;
|
||||
}
|
||||
else
|
||||
{
|
||||
frac = ( build_amount - buildstart ) / ( buildend - buildstart );
|
||||
frac = clamp( frac, 0.0f, 1.0f );
|
||||
}
|
||||
}
|
||||
|
||||
if ( !pObject->IsBuilding() )
|
||||
{
|
||||
frac = 1.0f;
|
||||
}
|
||||
|
||||
m_pAlphaVar->SetFloatValue( frac );
|
||||
}
|
||||
|
||||
EXPOSE_INTERFACE( CObjectBuildAlphaProxy, IMaterialProxy, "TFObjectBuildAlpha" IMATERIAL_PROXY_INTERFACE_VERSION );
|
||||
|
||||
|
||||
@@ -0,0 +1,355 @@
|
||||
//========= 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 );
|
||||
}
|
||||
|
||||
@@ -0,0 +1,135 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose: Clients CBaseObject
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================//
|
||||
|
||||
#ifndef OBJECTCONTROLPANEL_H
|
||||
#define OBJECTCONTROLPANEL_H
|
||||
|
||||
#ifdef _WIN32
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include "c_vguiscreen.h"
|
||||
|
||||
namespace vgui
|
||||
{
|
||||
class Panel;
|
||||
class Label;
|
||||
class Button;
|
||||
}
|
||||
|
||||
class C_BaseObject;
|
||||
class CRotationSlider;
|
||||
class C_BaseTFPlayer;
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Base class for all vgui screens on objects:
|
||||
//-----------------------------------------------------------------------------
|
||||
class CObjectControlPanel : public CVGuiScreenPanel
|
||||
{
|
||||
DECLARE_CLASS( CObjectControlPanel, CVGuiScreenPanel );
|
||||
|
||||
public:
|
||||
CObjectControlPanel( vgui::Panel *parent, const char *panelName );
|
||||
|
||||
virtual bool Init( KeyValues* pKeyValues, VGuiScreenInitData_t* pInitData );
|
||||
virtual void OnCommand( const char *command );
|
||||
virtual void OnTick();
|
||||
|
||||
protected:
|
||||
// Method to add controls to particular panels
|
||||
vgui::Panel *GetActivePanel() { return m_pActivePanel; }
|
||||
vgui::Panel *GetDeterioratingPanel() { return m_pDeterioratingPanel; }
|
||||
vgui::Panel *GetDismantlingPanel() { return m_pDismantlingPanel; }
|
||||
|
||||
// Override these to deal with various controls in various modes
|
||||
virtual void OnTickDeteriorating( C_BaseObject *pObj, C_BaseTFPlayer *pLocalPlayer );
|
||||
virtual void OnTickActive( C_BaseObject *pObj, C_BaseTFPlayer *pLocalPlayer );
|
||||
virtual void OnTickDismantling( C_BaseObject *pObj, C_BaseTFPlayer *pLocalPlayer );
|
||||
|
||||
C_BaseObject *GetOwningObject() const;
|
||||
|
||||
// This should update the current panel and return that panel.
|
||||
virtual vgui::Panel* TickCurrentPanel();
|
||||
|
||||
// The dismantle button has its own logic about whether or not to hide itself.
|
||||
// Use this to make it go away.
|
||||
void ShowDismantleButton( bool bShow );
|
||||
void ShowOwnerLabel( bool bShow );
|
||||
void ShowHealthLabel( bool bShow );
|
||||
|
||||
// Send a message to the owner.
|
||||
void SendToServerObject( const char *pMsg );
|
||||
|
||||
private:
|
||||
// Operations performed through the controls
|
||||
void AssumeControl();
|
||||
void Dismantle();
|
||||
void StartDismantling();
|
||||
void StopDismantling();
|
||||
bool IsDismantling() const;
|
||||
|
||||
vgui::EditablePanel *m_pActivePanel;
|
||||
vgui::EditablePanel *m_pDeterioratingPanel;
|
||||
vgui::EditablePanel *m_pDismantlingPanel;
|
||||
|
||||
vgui::Label *m_pHealthLabel;
|
||||
vgui::Label *m_pOwnerLabel;
|
||||
vgui::Button *m_pDismantleButton;
|
||||
vgui::Button *m_pAssumeControlButton;
|
||||
vgui::Label *m_pDismantleTimeLabel;
|
||||
|
||||
vgui::Panel *m_pCurrentPanel;
|
||||
|
||||
bool m_bDismantled;
|
||||
float m_flDismantleTime;
|
||||
};
|
||||
|
||||
|
||||
// This is used for child panels. It forwards the messages to the parent panel.
|
||||
class CCommandChainingPanel : public vgui::EditablePanel
|
||||
{
|
||||
typedef vgui::EditablePanel BaseClass;
|
||||
|
||||
public:
|
||||
CCommandChainingPanel( vgui::Panel *parent, const char *panelName ) :
|
||||
BaseClass( parent, panelName )
|
||||
{
|
||||
SetPaintBackgroundEnabled( false );
|
||||
}
|
||||
|
||||
void OnCommand( const char *command )
|
||||
{
|
||||
BaseClass::OnCommand( command );
|
||||
if (GetParent())
|
||||
{
|
||||
GetParent()->OnCommand(command);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// This is a panel for an object that has rotational controls
|
||||
//-----------------------------------------------------------------------------
|
||||
class CRotatingObjectControlPanel : public CObjectControlPanel
|
||||
{
|
||||
DECLARE_CLASS( CRotatingObjectControlPanel, CObjectControlPanel );
|
||||
|
||||
public:
|
||||
CRotatingObjectControlPanel( vgui::Panel *parent, const char *panelName );
|
||||
|
||||
virtual bool Init( KeyValues* pKeyValues, VGuiScreenInitData_t* pInitData );
|
||||
|
||||
protected:
|
||||
virtual void OnTickActive( C_BaseObject *pObj, C_BaseTFPlayer *pLocalPlayer );
|
||||
|
||||
private:
|
||||
CRotationSlider *m_pRotationSlider;
|
||||
vgui::Label *m_pRotationLabel;
|
||||
};
|
||||
|
||||
#endif // OBJECTCONTROLPANEL_H
|
||||
@@ -0,0 +1,198 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================//
|
||||
#include "cbase.h"
|
||||
#include "materialsystem/imaterial.h"
|
||||
#include "materialsystem/imaterialsystem.h"
|
||||
#include <KeyValues.h>
|
||||
#include "materialsystem/imaterialvar.h"
|
||||
#include "C_BaseTFPlayer.h"
|
||||
#include "functionproxy.h"
|
||||
#include "C_PlayerResource.h"
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Returns the player health (from 0 to 1)
|
||||
//-----------------------------------------------------------------------------
|
||||
class CPlayerHealthProxy : public CResultProxy
|
||||
{
|
||||
public:
|
||||
bool Init( IMaterial *pMaterial, KeyValues *pKeyValues );
|
||||
void OnBind( void *pEnt );
|
||||
|
||||
private:
|
||||
CFloatInput m_Factor;
|
||||
};
|
||||
|
||||
bool CPlayerHealthProxy::Init( IMaterial *pMaterial, KeyValues *pKeyValues )
|
||||
{
|
||||
if (!CResultProxy::Init( pMaterial, pKeyValues ))
|
||||
return false;
|
||||
|
||||
if (!m_Factor.Init( pMaterial, pKeyValues, "scale", 1 ))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void CPlayerHealthProxy::OnBind( void *pArg )
|
||||
{
|
||||
// NOTE: Player health max is not available on the server...
|
||||
C_BaseEntity *pEntity = BindArgToEntity( pArg );
|
||||
C_BaseTFPlayer* pPlayer = dynamic_cast<C_BaseTFPlayer*>(pEntity);
|
||||
if (!pPlayer)
|
||||
return;
|
||||
|
||||
Assert( m_pResult );
|
||||
SetFloatResult( pPlayer->HealthFraction() * m_Factor.GetFloat() );
|
||||
|
||||
/*
|
||||
// Should we draw their health?
|
||||
// If he's not on our team we can't see it unless we're a command with "targetinginfo".
|
||||
if ( GetLocalTeam() != GetTeam() && !(local->HasNamedTechnology("targetinginfo") && IsLocalPlayerClass(TFCLASS_COMMANDO) ))
|
||||
return drawn;
|
||||
// Don't draw health bars above myself
|
||||
if ( local == this )
|
||||
return drawn;
|
||||
// Don't draw health bars over dead/dying player
|
||||
if ( GetHealth() <= 0 )
|
||||
return drawn;
|
||||
|
||||
return drawn;
|
||||
*/
|
||||
}
|
||||
|
||||
EXPOSE_INTERFACE( CPlayerHealthProxy, IMaterialProxy, "PlayerHealth" IMATERIAL_PROXY_INTERFACE_VERSION );
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// A function that returns the time since last being damaged
|
||||
//-----------------------------------------------------------------------------
|
||||
class CPlayerDamageTimeProxy : public CResultProxy
|
||||
{
|
||||
public:
|
||||
bool Init( IMaterial *pMaterial, KeyValues *pKeyValues );
|
||||
void OnBind( void *pEnt );
|
||||
|
||||
private:
|
||||
CFloatInput m_Factor;
|
||||
};
|
||||
|
||||
bool CPlayerDamageTimeProxy::Init( IMaterial *pMaterial, KeyValues *pKeyValues )
|
||||
{
|
||||
if (!CResultProxy::Init( pMaterial, pKeyValues ))
|
||||
return false;
|
||||
|
||||
if (!m_Factor.Init( pMaterial, pKeyValues, "scale", 1.0f ))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void CPlayerDamageTimeProxy::OnBind( void *pArg )
|
||||
{
|
||||
C_BaseEntity *pEntity = BindArgToEntity( pArg );
|
||||
|
||||
// NOTE: Player health max is not available on the server...
|
||||
C_BaseTFPlayer* pPlayer = dynamic_cast<C_BaseTFPlayer*>(pEntity);
|
||||
if (!pPlayer)
|
||||
{
|
||||
SetFloatResult( 10000 * m_Factor.GetFloat() );
|
||||
return;
|
||||
}
|
||||
|
||||
Assert( m_pResult );
|
||||
float dt = gpGlobals->curtime - pPlayer->GetLastDamageTime();
|
||||
SetFloatResult( dt * m_Factor.GetFloat() );
|
||||
}
|
||||
|
||||
EXPOSE_INTERFACE( CPlayerDamageTimeProxy, IMaterialProxy, "PlayerDamageTime" IMATERIAL_PROXY_INTERFACE_VERSION );
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// A function that returns the time since last being healed
|
||||
//-----------------------------------------------------------------------------
|
||||
class CPlayerHealTimeProxy : public CResultProxy
|
||||
{
|
||||
public:
|
||||
bool Init( IMaterial *pMaterial, KeyValues *pKeyValues );
|
||||
void OnBind( void *pEnt );
|
||||
|
||||
private:
|
||||
CFloatInput m_Factor;
|
||||
};
|
||||
|
||||
bool CPlayerHealTimeProxy::Init( IMaterial *pMaterial, KeyValues *pKeyValues )
|
||||
{
|
||||
if (!CResultProxy::Init( pMaterial, pKeyValues ))
|
||||
return false;
|
||||
|
||||
if (!m_Factor.Init( pMaterial, pKeyValues, "scale", 1.0f ))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void CPlayerHealTimeProxy::OnBind( void *pArg )
|
||||
{
|
||||
// NOTE: Player health max is not available on the server...
|
||||
C_BaseEntity *pEntity = BindArgToEntity( pArg );
|
||||
C_BaseTFPlayer* pPlayer = dynamic_cast<C_BaseTFPlayer*>(pEntity);
|
||||
if (!pPlayer)
|
||||
return;
|
||||
|
||||
Assert( m_pResult );
|
||||
float dt = gpGlobals->curtime - pPlayer->GetLastGainHealthTime();
|
||||
SetFloatResult( dt * m_Factor.GetFloat() );
|
||||
}
|
||||
|
||||
EXPOSE_INTERFACE( CPlayerHealTimeProxy, IMaterialProxy, "PlayerHealTime" IMATERIAL_PROXY_INTERFACE_VERSION );
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Returns the player score
|
||||
//-----------------------------------------------------------------------------
|
||||
class CPlayerScoreProxy : public CResultProxy
|
||||
{
|
||||
public:
|
||||
bool Init( IMaterial *pMaterial, KeyValues *pKeyValues );
|
||||
void OnBind( void *pEntity );
|
||||
|
||||
private:
|
||||
CFloatInput m_Factor;
|
||||
};
|
||||
|
||||
bool CPlayerScoreProxy::Init( IMaterial *pMaterial, KeyValues *pKeyValues )
|
||||
{
|
||||
if (!CResultProxy::Init( pMaterial, pKeyValues ))
|
||||
return false;
|
||||
|
||||
if (!m_Factor.Init( pMaterial, pKeyValues, "scale", 1 ))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void CPlayerScoreProxy::OnBind( void *pArg )
|
||||
{
|
||||
// Find the view angle between the player and this entity....
|
||||
C_BaseEntity *pEntity = BindArgToEntity( pArg );
|
||||
C_BaseTFPlayer* pPlayer = dynamic_cast<C_BaseTFPlayer*>(pEntity);
|
||||
if (!pPlayer)
|
||||
return;
|
||||
|
||||
if ( !g_PR )
|
||||
return;
|
||||
|
||||
int score = g_PR->GetPlayerScore(pPlayer->index);
|
||||
|
||||
Assert( m_pResult );
|
||||
SetFloatResult( score * m_Factor.GetFloat() );
|
||||
}
|
||||
|
||||
EXPOSE_INTERFACE( CPlayerScoreProxy, IMaterialProxy, "PlayerScore" IMATERIAL_PROXY_INTERFACE_VERSION );
|
||||
|
||||
|
||||
@@ -0,0 +1,101 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================//
|
||||
#include "cbase.h"
|
||||
#include "c_vguiscreen.h"
|
||||
#include "clientmode_tfbase.h"
|
||||
#include <vgui/IVGui.h>
|
||||
#include <vgui_controls/Controls.h>
|
||||
#include <vgui_controls/Label.h>
|
||||
#include "c_info_act.h"
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Base class for all vgui screens on objects:
|
||||
//-----------------------------------------------------------------------------
|
||||
class CRespawnWaveVGuiScreen : public CVGuiScreenPanel
|
||||
{
|
||||
DECLARE_CLASS( CRespawnWaveVGuiScreen, CVGuiScreenPanel );
|
||||
|
||||
public:
|
||||
CRespawnWaveVGuiScreen( vgui::Panel *parent, const char *panelName );
|
||||
|
||||
virtual bool Init( KeyValues* pKeyValues, VGuiScreenInitData_t* pInitData );
|
||||
virtual void OnTick();
|
||||
|
||||
private:
|
||||
vgui::Label *m_pTime1RemainingLabel;
|
||||
vgui::Label *m_pTime2RemainingLabel;
|
||||
};
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Standard VGUI panel for objects
|
||||
//-----------------------------------------------------------------------------
|
||||
DECLARE_VGUI_SCREEN_FACTORY( CRespawnWaveVGuiScreen, "respawn_wave_screen" );
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Constructor:
|
||||
//-----------------------------------------------------------------------------
|
||||
CRespawnWaveVGuiScreen::CRespawnWaveVGuiScreen( vgui::Panel *parent, const char *panelName )
|
||||
: BaseClass( parent, panelName, g_hVGuiObjectScheme )
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Initialization
|
||||
//-----------------------------------------------------------------------------
|
||||
bool CRespawnWaveVGuiScreen::Init( KeyValues* pKeyValues, VGuiScreenInitData_t* pInitData )
|
||||
{
|
||||
// Load all of the controls in
|
||||
if (!BaseClass::Init(pKeyValues, pInitData))
|
||||
return false;
|
||||
|
||||
// Make sure we get ticked...
|
||||
vgui::ivgui()->AddTickSignal( GetVPanel() );
|
||||
|
||||
// Grab ahold of certain well-known controls
|
||||
// NOTE: it is valid for these controls to not exist!
|
||||
m_pTime1RemainingLabel = dynamic_cast<vgui::Label*>(FindChildByName( "RespawnTime1Remaining" ));
|
||||
m_pTime2RemainingLabel = dynamic_cast<vgui::Label*>(FindChildByName( "RespawnTime2Remaining" ));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Frame-based update
|
||||
//-----------------------------------------------------------------------------
|
||||
void CRespawnWaveVGuiScreen::OnTick()
|
||||
{
|
||||
BaseClass::OnTick();
|
||||
|
||||
if (!GetEntity())
|
||||
return;
|
||||
|
||||
int nTime1Remaining = 0;
|
||||
int nTime2Remaining = 0;
|
||||
if (g_hCurrentAct.Get())
|
||||
{
|
||||
nTime1Remaining = g_hCurrentAct->RespawnTimeRemaining( GetEntity()->GetTeamNumber(), 1 );
|
||||
nTime2Remaining = g_hCurrentAct->RespawnTimeRemaining( GetEntity()->GetTeamNumber(), 2 );
|
||||
}
|
||||
|
||||
char buf[32];
|
||||
if (m_pTime1RemainingLabel)
|
||||
{
|
||||
Q_snprintf( buf, sizeof( buf ), "%d", nTime1Remaining );
|
||||
m_pTime1RemainingLabel->SetText( buf );
|
||||
}
|
||||
if (m_pTime2RemainingLabel)
|
||||
{
|
||||
Q_snprintf( buf, sizeof( buf ), "%d", nTime2Remaining );
|
||||
m_pTime2RemainingLabel->SetText( buf );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,148 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================//
|
||||
#include "cbase.h"
|
||||
#include "c_vguiscreen.h"
|
||||
#include "clientmode_tfbase.h"
|
||||
#include <vgui/IVGui.h>
|
||||
#include <vgui_controls/Controls.h>
|
||||
#include <vgui_controls/Label.h>
|
||||
#include "vgui_bitmapbutton.h"
|
||||
#include "c_info_act.h"
|
||||
#include "tf_shareddefs.h"
|
||||
#include "c_basetfplayer.h"
|
||||
|
||||
int g_ValidVehicles[] =
|
||||
{
|
||||
OBJ_WAGON,
|
||||
OBJ_BATTERING_RAM,
|
||||
OBJ_VEHICLE_TANK,
|
||||
OBJ_VEHICLE_TELEPORT_STATION,
|
||||
OBJ_WALKER_STRIDER,
|
||||
OBJ_WALKER_MINI_STRIDER
|
||||
|
||||
// If you add a new vehicle here, you have to add a button for it to the screen_vehicle_bay.res file.
|
||||
// The button's name must be VehicleButton%d, where %d is it's index into this array.
|
||||
// Then add the build%d command to OnCommand at the bottom of this file.
|
||||
};
|
||||
|
||||
#define NUM_VEHICLES ARRAYSIZE(g_ValidVehicles)
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Vgui screen handling vehicle selection in vehicle bays
|
||||
//-----------------------------------------------------------------------------
|
||||
class CVehicleBayVGuiScreen : public CVGuiScreenPanel
|
||||
{
|
||||
DECLARE_CLASS( CVehicleBayVGuiScreen, CVGuiScreenPanel );
|
||||
|
||||
public:
|
||||
CVehicleBayVGuiScreen( vgui::Panel *parent, const char *panelName );
|
||||
|
||||
virtual bool Init( KeyValues* pKeyValues, VGuiScreenInitData_t* pInitData );
|
||||
virtual void OnTick();
|
||||
virtual void OnCommand( const char *command );
|
||||
|
||||
private:
|
||||
vgui::Button *m_pVehicleButtons[ NUM_VEHICLES ];
|
||||
};
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Standard VGUI panel for objects
|
||||
//-----------------------------------------------------------------------------
|
||||
DECLARE_VGUI_SCREEN_FACTORY( CVehicleBayVGuiScreen, "vehicle_bay_screen" );
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Constructor:
|
||||
//-----------------------------------------------------------------------------
|
||||
CVehicleBayVGuiScreen::CVehicleBayVGuiScreen( vgui::Panel *parent, const char *panelName )
|
||||
: BaseClass( parent, panelName, g_hVGuiObjectScheme )
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Initialization
|
||||
//-----------------------------------------------------------------------------
|
||||
bool CVehicleBayVGuiScreen::Init( KeyValues* pKeyValues, VGuiScreenInitData_t* pInitData )
|
||||
{
|
||||
// Create our vehicle buttons
|
||||
for ( int i = 0; i < NUM_VEHICLES; i++ )
|
||||
{
|
||||
char ch[128];
|
||||
Q_snprintf( ch, sizeof(ch), "VehicleButton%d", i );
|
||||
m_pVehicleButtons[i] = new CBitmapButton( this, ch, "Name" );
|
||||
}
|
||||
|
||||
// Load all of the controls in
|
||||
if (!BaseClass::Init(pKeyValues, pInitData))
|
||||
return false;
|
||||
|
||||
// Make sure we get ticked...
|
||||
vgui::ivgui()->AddTickSignal( GetVPanel() );
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Frame-based update
|
||||
//-----------------------------------------------------------------------------
|
||||
void CVehicleBayVGuiScreen::OnTick()
|
||||
{
|
||||
BaseClass::OnTick();
|
||||
|
||||
if (!GetEntity())
|
||||
return;
|
||||
|
||||
C_BaseTFPlayer *pLocalPlayer = C_BaseTFPlayer::GetLocalPlayer();
|
||||
if ( !pLocalPlayer )
|
||||
return;
|
||||
|
||||
int nBankResources = pLocalPlayer ? pLocalPlayer->GetBankResources() : 0;
|
||||
|
||||
// Set the vehicles costs
|
||||
for ( int i = 0; i < NUM_VEHICLES; i++ )
|
||||
{
|
||||
if ( !m_pVehicleButtons[i] )
|
||||
continue;
|
||||
|
||||
char buf[128];
|
||||
int iCost = CalculateObjectCost( g_ValidVehicles[i], pLocalPlayer->GetNumObjects( g_ValidVehicles[i] ), pLocalPlayer->GetTeamNumber() );
|
||||
Q_snprintf( buf, sizeof( buf ), "%s : %d", GetObjectInfo( g_ValidVehicles[i] )->m_pStatusName, iCost );
|
||||
m_pVehicleButtons[i]->SetText( buf );
|
||||
// Can't build if the game hasn't started
|
||||
if ( CurrentActIsAWaitingAct() )
|
||||
{
|
||||
m_pVehicleButtons[i]->SetEnabled( false );
|
||||
}
|
||||
else
|
||||
{
|
||||
m_pVehicleButtons[i]->SetEnabled( nBankResources >= iCost );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Button click handlers
|
||||
//-----------------------------------------------------------------------------
|
||||
void CVehicleBayVGuiScreen::OnCommand( const char *command )
|
||||
{
|
||||
if (!Q_strnicmp(command, "build", 5))
|
||||
{
|
||||
int iButton;
|
||||
int nCount = sscanf( command, "build%d", &iButton );
|
||||
if (nCount == 1)
|
||||
{
|
||||
char szbuf[64];
|
||||
Q_snprintf( szbuf, sizeof( szbuf ), "buildvehicle %d %d", GetEntity()->entindex(), g_ValidVehicles[iButton] );
|
||||
engine->ClientCmd(szbuf);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
BaseClass::OnCommand(command);
|
||||
}
|
||||
@@ -0,0 +1,284 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose: TF2 Specific C_BaseCombatCharacter code.
|
||||
//
|
||||
//=============================================================================//
|
||||
#include "cbase.h"
|
||||
#include "c_basecombatcharacter.h"
|
||||
#include "tf_shareddefs.h"
|
||||
#include "particles_simple.h"
|
||||
#include "functionproxy.h"
|
||||
#include "IEffects.h"
|
||||
#include "weapon_combatshield.h"
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void C_BaseCombatCharacter::Release( void )
|
||||
{
|
||||
RemoveAllPowerups();
|
||||
|
||||
BaseClass::Release();
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void C_BaseCombatCharacter::SetDormant( bool bDormant )
|
||||
{
|
||||
// If we're going dormant, stop all our powerup sounds
|
||||
if ( bDormant )
|
||||
{
|
||||
RemoveAllPowerups();
|
||||
}
|
||||
else
|
||||
{
|
||||
// Restart any powerups on him
|
||||
for ( int i = 0; i < MAX_POWERUPS; i++ )
|
||||
{
|
||||
if ( m_iPowerups & (1 << i) )
|
||||
{
|
||||
PowerupStart( i, false );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
BaseClass::SetDormant( bDormant );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
// Input : updateType -
|
||||
//-----------------------------------------------------------------------------
|
||||
void C_BaseCombatCharacter::OnPreDataChanged( DataUpdateType_t updateType )
|
||||
{
|
||||
BaseClass::OnPreDataChanged( updateType );
|
||||
|
||||
m_iPrevPowerups = m_iPowerups;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void C_BaseCombatCharacter::OnDataChanged( DataUpdateType_t updateType )
|
||||
{
|
||||
BaseClass::OnDataChanged( updateType );
|
||||
|
||||
if ( updateType == DATA_UPDATE_CREATED )
|
||||
{
|
||||
SetNextClientThink( CLIENT_THINK_ALWAYS );
|
||||
}
|
||||
|
||||
// Power state changed?
|
||||
if ( m_iPowerups != m_iPrevPowerups )
|
||||
{
|
||||
for ( int i = 0; i < MAX_POWERUPS; i++ )
|
||||
{
|
||||
bool bPoweredNow = ( m_iPowerups & (1 << i) );
|
||||
bool bPoweredThen = ( m_iPrevPowerups & (1 << i) );
|
||||
|
||||
if ( !bPoweredThen && bPoweredNow )
|
||||
{
|
||||
PowerupStart( i, true );
|
||||
}
|
||||
else if ( bPoweredThen && !bPoweredNow )
|
||||
{
|
||||
PowerupEnd( i );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Powerup has just started
|
||||
// If bInitial is set, the server's just told us this powerup has come on.
|
||||
// If it's false, the entity had it on when it left PVS, and now it's re-entered
|
||||
//-----------------------------------------------------------------------------
|
||||
void C_BaseCombatCharacter::PowerupStart( int iPowerup, bool bInitial )
|
||||
{
|
||||
Assert( iPowerup >= 0 && iPowerup < MAX_POWERUPS );
|
||||
|
||||
switch( iPowerup )
|
||||
{
|
||||
case POWERUP_BOOST:
|
||||
break;
|
||||
|
||||
case POWERUP_EMP:
|
||||
{
|
||||
// Play the EMP sound
|
||||
if ( !bInitial )
|
||||
{
|
||||
EmitSound( "BaseCombatCharacter.EMPPulse" );
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Powerup has just finished
|
||||
//-----------------------------------------------------------------------------
|
||||
void C_BaseCombatCharacter::PowerupEnd( int iPowerup )
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void C_BaseCombatCharacter::RemoveAllPowerups( void )
|
||||
{
|
||||
// Stop any powerups we have
|
||||
if ( m_iPowerups )
|
||||
{
|
||||
for ( int i = 0; i < MAX_POWERUPS; i++ )
|
||||
{
|
||||
if ( m_iPowerups & (1 << i) )
|
||||
{
|
||||
PowerupEnd( i );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void C_BaseCombatCharacter::ClientThink( void )
|
||||
{
|
||||
BaseClass::ClientThink();
|
||||
|
||||
if ( !IsDormant() )
|
||||
{
|
||||
if ( HasPowerup(POWERUP_EMP) )
|
||||
{
|
||||
AddEMPEffect( WorldAlignSize().Length() * 0.15 );
|
||||
}
|
||||
|
||||
if ( HasPowerup(POWERUP_BOOST) )
|
||||
{
|
||||
AddBuffEffect( WorldAlignSize().Length() * 0.15 );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Draw an effect to show this entity has been EMPed
|
||||
//-----------------------------------------------------------------------------
|
||||
void C_BaseCombatCharacter::AddEMPEffect( float flSize )
|
||||
{
|
||||
// Don't draw on the local player
|
||||
if ( this == C_BasePlayer::GetLocalPlayer() )
|
||||
return;
|
||||
|
||||
CSmartPtr<CSimpleEmitter> pEmitter;
|
||||
PMaterialHandle hParticleMaterial;
|
||||
TimedEvent pParticleEvent;
|
||||
|
||||
pParticleEvent.Init( 300 );
|
||||
pEmitter = CSimpleEmitter::Create( "ObjectEMPEffect" );
|
||||
hParticleMaterial = pEmitter->GetPMaterial( "sprites/chargeball" );
|
||||
|
||||
// Add particles
|
||||
float flCur = gpGlobals->frametime;
|
||||
Vector vCenter = WorldSpaceCenter( );
|
||||
|
||||
while ( pParticleEvent.NextEvent( flCur ) )
|
||||
{
|
||||
Vector vPos;
|
||||
Vector vOffset = RandomVector( -1, 1 );
|
||||
VectorNormalize( vOffset );
|
||||
vPos = vCenter + (vOffset * RandomFloat( 0, flSize ));
|
||||
|
||||
pEmitter->SetSortOrigin( vPos );
|
||||
SimpleParticle *pParticle = pEmitter->AddSimpleParticle( hParticleMaterial, vPos );
|
||||
if ( pParticle )
|
||||
{
|
||||
// Move the points along the path.
|
||||
pParticle->m_vecVelocity.Init();
|
||||
pParticle->m_flRoll = 0;
|
||||
pParticle->m_flRollDelta = 0;
|
||||
pParticle->m_flDieTime = 0.4f;
|
||||
pParticle->m_flLifetime = 0;
|
||||
pParticle->m_uchColor[0] = 255;
|
||||
pParticle->m_uchColor[1] = 255;
|
||||
pParticle->m_uchColor[2] = 255;
|
||||
pParticle->m_uchStartAlpha = 32;
|
||||
pParticle->m_uchEndAlpha = 0;
|
||||
pParticle->m_uchStartSize = 4;
|
||||
pParticle->m_uchEndSize = 2;
|
||||
pParticle->m_iFlags = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Draw an effect to show this entity is being buffed
|
||||
//-----------------------------------------------------------------------------
|
||||
void C_BaseCombatCharacter::AddBuffEffect( float flSize )
|
||||
{
|
||||
// Don't draw on the local player
|
||||
if ( this == C_BasePlayer::GetLocalPlayer() )
|
||||
return;
|
||||
|
||||
CSmartPtr<CSimpleEmitter> pEmitter;
|
||||
PMaterialHandle hParticleMaterial;
|
||||
TimedEvent pParticleEvent;
|
||||
|
||||
pParticleEvent.Init( 300 );
|
||||
pEmitter = CSimpleEmitter::Create( "ObjectBuffEffect" );
|
||||
hParticleMaterial = pEmitter->GetPMaterial( "sprites/chargeball" );
|
||||
|
||||
// Add particles
|
||||
float flCur = gpGlobals->frametime;
|
||||
Vector vCenter = WorldSpaceCenter( );
|
||||
|
||||
while ( pParticleEvent.NextEvent( flCur ) )
|
||||
{
|
||||
Vector vPos;
|
||||
Vector vOffset = RandomVector( -1, 1 );
|
||||
VectorNormalize( vOffset );
|
||||
vPos = vCenter + (vOffset * RandomFloat( 0, flSize ));
|
||||
|
||||
SimpleParticle *pParticle = pEmitter->AddSimpleParticle( hParticleMaterial, vPos );
|
||||
if ( pParticle )
|
||||
{
|
||||
// Move the points along the path.
|
||||
pParticle->m_vecVelocity.Init();
|
||||
pParticle->m_flRoll = 0;
|
||||
pParticle->m_flRollDelta = 0;
|
||||
pParticle->m_flDieTime = 0.4f;
|
||||
pParticle->m_flLifetime = 0;
|
||||
pParticle->m_uchColor[1] = 255; pParticle->m_uchColor[0] = pParticle->m_uchColor[2] = 0;
|
||||
pParticle->m_uchStartAlpha = 128;
|
||||
pParticle->m_uchEndAlpha = 0;
|
||||
pParticle->m_uchStartSize = 3;
|
||||
pParticle->m_uchEndSize = 1;
|
||||
pParticle->m_iFlags = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Returns shield if owned.
|
||||
//-----------------------------------------------------------------------------
|
||||
C_WeaponCombatShield *C_BaseCombatCharacter::GetShield( void )
|
||||
{
|
||||
C_BaseCombatWeapon *pWeapon;
|
||||
if ( GetTeamNumber() == TEAM_ALIENS )
|
||||
{
|
||||
pWeapon = Weapon_OwnsThisType( "weapon_combat_shield_alien" );
|
||||
}
|
||||
else
|
||||
{
|
||||
pWeapon = Weapon_OwnsThisType( "weapon_combat_shield" );
|
||||
}
|
||||
|
||||
if ( !pWeapon )
|
||||
return NULL;
|
||||
|
||||
return ( CWeaponCombatShield* )pWeapon;
|
||||
}
|
||||
@@ -0,0 +1,89 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================//
|
||||
#include "cbase.h"
|
||||
#include "C_BaseFourWheelVehicle.h"
|
||||
|
||||
IMPLEMENT_CLIENTCLASS_DT(C_BaseTFFourWheelVehicle, DT_BaseTFFourWheelVehicle, CBaseTFFourWheelVehicle)
|
||||
RecvPropFloat( RECVINFO( m_flDeployFinishTime ) ),
|
||||
RecvPropInt( RECVINFO( m_eDeployMode ) ),
|
||||
RecvPropInt( RECVINFO( m_bBoostUpgrade ) ),
|
||||
RecvPropInt( RECVINFO( m_nBoostTimeLeft ) ),
|
||||
END_RECV_TABLE()
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
C_BaseTFFourWheelVehicle::C_BaseTFFourWheelVehicle()
|
||||
{
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
float C_BaseTFFourWheelVehicle::GetDeployFinishTime() const
|
||||
{
|
||||
return m_flDeployFinishTime;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
VehicleModeDeploy_e C_BaseTFFourWheelVehicle::GetVehicleModeDeploy() const
|
||||
{
|
||||
return m_eDeployMode;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void C_BaseTFFourWheelVehicle::OnDataChanged( DataUpdateType_t updateType )
|
||||
{
|
||||
BaseClass::OnDataChanged( updateType );
|
||||
|
||||
if ( updateType == DATA_UPDATE_CREATED )
|
||||
{
|
||||
// Start thinking (Baseclass stops it)
|
||||
ClientThinkList()->SetNextClientThink( GetClientHandle(), CLIENT_THINK_ALWAYS );
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Restricts the view within a range of the center...
|
||||
//-----------------------------------------------------------------------------
|
||||
void C_BaseTFFourWheelVehicle::RestrictView( int nRole, float flMinYaw, float flMaxYaw, QAngle &vecViewAngles )
|
||||
{
|
||||
Assert( nRole >= 0 );
|
||||
Vector vehicleEyeOrigin;
|
||||
QAngle vehicleEyeAngles;
|
||||
GetRoleViewPosition( nRole, &vehicleEyeOrigin, &vehicleEyeAngles );
|
||||
|
||||
// Confine the view to the appropriate yaw range...
|
||||
float flCenterYaw = vehicleEyeAngles[YAW];
|
||||
|
||||
// View angles are dealt with in absolute terms here...
|
||||
float flAngleDiff = AngleDiff( vecViewAngles[YAW], flCenterYaw );
|
||||
|
||||
// Here, we must clamp to the cone...
|
||||
if (flAngleDiff < flMinYaw)
|
||||
vecViewAngles[YAW] = anglemod(flCenterYaw + flMinYaw);
|
||||
else if (flAngleDiff > flMaxYaw)
|
||||
vecViewAngles[YAW] = anglemod(flCenterYaw + flMaxYaw);
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Clamps the view angles while driving the vehicle
|
||||
//-----------------------------------------------------------------------------
|
||||
void C_BaseTFFourWheelVehicle::UpdateViewAngles( C_BasePlayer *pLocalPlayer, CUserCmd *pCmd )
|
||||
{
|
||||
int nRole = GetPassengerRole( pLocalPlayer );
|
||||
if ( nRole != VEHICLE_ROLE_DRIVER )
|
||||
{
|
||||
RestrictView( nRole, -90, 90, pCmd->viewangles );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,51 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================//
|
||||
|
||||
#ifndef C_BASE_FOUR_WHEEL_VEHICLE_H
|
||||
#define C_BASE_FOUR_WHEEL_VEHICLE_H
|
||||
|
||||
#include "basetfvehicle.h"
|
||||
|
||||
class C_BasePlayer;
|
||||
|
||||
class C_BaseTFFourWheelVehicle : public C_BaseTFVehicle
|
||||
{
|
||||
DECLARE_CLASS( C_BaseTFFourWheelVehicle, C_BaseTFVehicle );
|
||||
DECLARE_CLIENTCLASS();
|
||||
|
||||
public:
|
||||
|
||||
C_BaseTFFourWheelVehicle();
|
||||
|
||||
float GetDeployFinishTime() const;
|
||||
VehicleModeDeploy_e GetVehicleModeDeploy() const;
|
||||
|
||||
// TF2 vehicles are animated by the server
|
||||
virtual bool IsSelfAnimating() { return false; };
|
||||
|
||||
virtual void OnDataChanged( DataUpdateType_t updateType );
|
||||
|
||||
// IClientVehicle overrides.
|
||||
public:
|
||||
virtual void UpdateViewAngles( C_BasePlayer *pLocalPlayer, CUserCmd *pCmd );
|
||||
|
||||
protected:
|
||||
// Restricts the view within a range of the center...
|
||||
void RestrictView( int nRole, float flMinYaw, float flMaxYaw, QAngle &vecViewAngles );
|
||||
|
||||
private:
|
||||
|
||||
C_BaseTFFourWheelVehicle( const C_BaseTFFourWheelVehicle & ); // not defined, not accessible
|
||||
|
||||
private:
|
||||
|
||||
// Used to draw deploy timer on vgui screens.
|
||||
float m_flDeployFinishTime;
|
||||
VehicleModeDeploy_e m_eDeployMode;
|
||||
};
|
||||
|
||||
#endif // C_BASE_FOUR_WHEEL_VEHICLE_H
|
||||
@@ -0,0 +1,921 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose: Clients CBaseObject
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================//
|
||||
#include "cbase.h"
|
||||
#include "c_baseobject.h"
|
||||
#include "c_basetfplayer.h"
|
||||
#include "hud.h"
|
||||
#include "c_tfteam.h"
|
||||
#include "engine/IEngineSound.h"
|
||||
#include "particles_simple.h"
|
||||
#include "functionproxy.h"
|
||||
#include "IEffects.h"
|
||||
#include "c_hint_events.h"
|
||||
#include "model_types.h"
|
||||
#include "particlemgr.h"
|
||||
#include "particle_collision.h"
|
||||
#include "env_objecteffects.h"
|
||||
#include "basetfvehicle.h"
|
||||
#include "c_weapon_builder.h"
|
||||
#include "ivrenderview.h"
|
||||
#include "ObjectControlPanel.h"
|
||||
#include "engine/ivmodelinfo.h"
|
||||
#include "c_te_effect_dispatch.h"
|
||||
|
||||
// memdbgon must be the last include file in a .cpp file!!!
|
||||
#include "tier0/memdbgon.h"
|
||||
|
||||
#define MAX_VISIBLE_BUILDPOINT_DISTANCE (400 * 400)
|
||||
|
||||
// Remove aliasing of name due to shared code
|
||||
#undef CBaseObject
|
||||
|
||||
IMPLEMENT_CLIENTCLASS_DT(C_BaseObject, DT_BaseObject, CBaseObject)
|
||||
RecvPropInt(RECVINFO(m_iHealth)),
|
||||
RecvPropInt(RECVINFO(m_iMaxHealth)),
|
||||
RecvPropInt(RECVINFO(m_bHasSapper)),
|
||||
RecvPropInt(RECVINFO(m_iObjectType)),
|
||||
RecvPropInt(RECVINFO(m_bBuilding)),
|
||||
RecvPropInt(RECVINFO(m_bPlacing)),
|
||||
RecvPropFloat(RECVINFO(m_flPercentageConstructed)),
|
||||
RecvPropInt(RECVINFO(m_fObjectFlags)),
|
||||
RecvPropInt(RECVINFO(m_bDeteriorating)),
|
||||
RecvPropEHandle(RECVINFO(m_hBuiltOnEntity)),
|
||||
RecvPropInt(RECVINFO( m_takedamage ) ),
|
||||
RecvPropInt( RECVINFO( m_bDisabled ) ),
|
||||
RecvPropEHandle( RECVINFO( m_hBuilder ) ),
|
||||
END_RECV_TABLE()
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
C_BaseObject::C_BaseObject( )
|
||||
{
|
||||
m_flDamageFlash = 0;
|
||||
m_YawPreviewState = YAW_PREVIEW_OFF;
|
||||
m_bBuilding = false;
|
||||
m_bPlacing = false;
|
||||
m_flPercentageConstructed = 0;
|
||||
m_flNextEffect = 0;
|
||||
m_bOldSapper = m_bHasSapper = false;
|
||||
m_fObjectFlags = 0;
|
||||
m_bDeteriorating = false;
|
||||
m_ThermalMaterial.Init("player/thermal/thermal",TEXTURE_GROUP_CLIENT_EFFECTS);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
C_BaseObject::~C_BaseObject( void )
|
||||
{
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void C_BaseObject::PreDataUpdate( DataUpdateType_t updateType )
|
||||
{
|
||||
BaseClass::PreDataUpdate( updateType );
|
||||
|
||||
m_iOldHealth = m_iHealth;
|
||||
m_bOldSapper = m_bHasSapper;
|
||||
m_hOldOwner = GetOwner();
|
||||
m_bWasActive = ShouldBeActive();
|
||||
m_bWasBuilding = m_bBuilding;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void C_BaseObject::OnDataChanged( DataUpdateType_t updateType )
|
||||
{
|
||||
if (updateType == DATA_UPDATE_CREATED)
|
||||
{
|
||||
if ( !IS_MINIMAP_PANEL_DEFINED( ) && !(m_fObjectFlags & OF_SUPPRESS_APPEAR_ON_MINIMAP) )
|
||||
{
|
||||
CONSTRUCT_MINIMAP_PANEL( "minimap_object", MINIMAP_OBJECTS );
|
||||
}
|
||||
|
||||
CreateBuildPoints();
|
||||
}
|
||||
|
||||
BaseClass::OnDataChanged( updateType );
|
||||
|
||||
// Did we just finish building?
|
||||
if ( m_bWasBuilding && !m_bBuilding )
|
||||
{
|
||||
FinishedBuilding();
|
||||
}
|
||||
|
||||
// Did we just go active?
|
||||
bool bShouldBeActive = ShouldBeActive();
|
||||
if ( !m_bWasActive && bShouldBeActive )
|
||||
{
|
||||
OnGoActive();
|
||||
}
|
||||
else if ( m_bWasActive && !bShouldBeActive )
|
||||
{
|
||||
OnGoInactive();
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void C_BaseObject::SetDormant( bool bDormant )
|
||||
{
|
||||
BaseClass::SetDormant( bDormant );
|
||||
//ENTITY_PANEL_ACTIVATE( "analyzed_object", !bDormant );
|
||||
}
|
||||
|
||||
#define TF_OBJ_BODYGROUPTURNON 1
|
||||
#define TF_OBJ_BODYGROUPTURNOFF 0
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
// Input : origin -
|
||||
// angles -
|
||||
// event -
|
||||
// *options -
|
||||
//-----------------------------------------------------------------------------
|
||||
void C_BaseObject::FireEvent( const Vector& origin, const QAngle& angles, int event, const char *options )
|
||||
{
|
||||
switch ( event )
|
||||
{
|
||||
default:
|
||||
{
|
||||
BaseClass::FireEvent( origin, angles, event, options );
|
||||
}
|
||||
break;
|
||||
case TF_OBJ_PLAYBUILDSOUND:
|
||||
{
|
||||
EmitSound( options );
|
||||
}
|
||||
break;
|
||||
case TF_OBJ_ENABLEBODYGROUP:
|
||||
{
|
||||
int index = FindBodygroupByName( options );
|
||||
if ( index >= 0 )
|
||||
{
|
||||
SetBodygroup( index, TF_OBJ_BODYGROUPTURNON );
|
||||
}
|
||||
}
|
||||
break;
|
||||
case TF_OBJ_DISABLEBODYGROUP:
|
||||
{
|
||||
int index = FindBodygroupByName( options );
|
||||
if ( index >= 0 )
|
||||
{
|
||||
SetBodygroup( index, TF_OBJ_BODYGROUPTURNOFF );
|
||||
}
|
||||
}
|
||||
break;
|
||||
case TF_OBJ_ENABLEALLBODYGROUPS:
|
||||
case TF_OBJ_DISABLEALLBODYGROUPS:
|
||||
{
|
||||
// Start at 1, because body 0 is the main .mdl body...
|
||||
// Is this the way we want to do this?
|
||||
int count = GetNumBodyGroups();
|
||||
for ( int i = 1; i < count; i++ )
|
||||
{
|
||||
int subpartcount = GetBodygroupCount( i );
|
||||
if ( subpartcount == 2 )
|
||||
{
|
||||
SetBodygroup( i,
|
||||
( event == TF_OBJ_ENABLEALLBODYGROUPS ) ?
|
||||
TF_OBJ_BODYGROUPTURNON : TF_OBJ_BODYGROUPTURNOFF );
|
||||
}
|
||||
else
|
||||
{
|
||||
DevMsg( "TF_OBJ_ENABLE/DISABLEBODY GROUP: %s has a group with %i subparts, should be exactly 2\n",
|
||||
GetClassname(), subpartcount );
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
bool C_BaseObject::OffsetObjectOrigin( Vector& origin )
|
||||
{
|
||||
if ( !m_bBuilding )
|
||||
return false;
|
||||
|
||||
if ( inv_demo.GetBool() )
|
||||
return false;
|
||||
|
||||
Vector vecWorldMins, vecWorldMaxs;
|
||||
CollisionProp()->WorldSpaceAABB( &vecWorldMins, &vecWorldMaxs );
|
||||
float flSize = vecWorldMaxs.z - vecWorldMins.z;
|
||||
origin.z -= (flSize * (1 - m_flPercentageConstructed));
|
||||
|
||||
// If we're building, fake sliding the object out of the ground
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
const char* C_BaseObject::GetStatusName() const
|
||||
{
|
||||
return GetObjectInfo( GetType() )->m_pStatusName;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
int C_BaseObject::DrawModel( int flags )
|
||||
{
|
||||
Vector vRealOrigin = GetLocalOrigin();
|
||||
Vector vOrigin = vRealOrigin;
|
||||
bool needOriginReset = OffsetObjectOrigin( vOrigin );
|
||||
if ( needOriginReset )
|
||||
{
|
||||
SetLocalOrigin( vOrigin );
|
||||
InvalidateBoneCache();
|
||||
}
|
||||
|
||||
int drawn;
|
||||
C_BaseTFPlayer *pLocal = C_BaseTFPlayer::GetLocalPlayer();
|
||||
if ( pLocal && pLocal->IsUsingThermalVision() )
|
||||
{
|
||||
modelrender->ForcedMaterialOverride( m_ThermalMaterial );
|
||||
drawn = BaseClass::DrawModel(flags);
|
||||
modelrender->ForcedMaterialOverride( NULL );
|
||||
}
|
||||
else
|
||||
{
|
||||
// If we're a brush-built, map-defined object chain up to baseentity draw
|
||||
if ( modelinfo->GetModelType( GetModel() ) == mod_brush )
|
||||
{
|
||||
drawn = CBaseEntity::DrawModel(flags);
|
||||
}
|
||||
else
|
||||
{
|
||||
drawn = BaseClass::DrawModel(flags);
|
||||
}
|
||||
}
|
||||
|
||||
// Restore faked origin
|
||||
if ( needOriginReset )
|
||||
{
|
||||
SetLocalOrigin( vRealOrigin );
|
||||
}
|
||||
|
||||
// If we were drawn, draw building effects if we're building, or damage effects if we're damaged
|
||||
if ( drawn && (m_flNextEffect < gpGlobals->curtime) )
|
||||
{
|
||||
// Haxory LOD
|
||||
C_BasePlayer *pPlayer = C_BasePlayer::GetLocalPlayer();
|
||||
if ( (GetAbsOrigin() - pPlayer->GetAbsOrigin()).LengthSqr() < lod_effect_distance.GetFloat() )
|
||||
{
|
||||
if ( IsBuilding() )
|
||||
{
|
||||
DrawBuildEffects();
|
||||
}
|
||||
if ( !m_bPlacing && !m_bBuilding )
|
||||
{
|
||||
if ( !HasPowerup( POWERUP_EMP ) )
|
||||
{
|
||||
DrawRunningEffects();
|
||||
}
|
||||
|
||||
if ( GetHealth() < GetMaxHealth() )
|
||||
{
|
||||
DrawDamageEffects();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
HighlightBuildPoints( flags );
|
||||
|
||||
return drawn;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void C_BaseObject::HighlightBuildPoints( int flags )
|
||||
{
|
||||
C_BaseTFPlayer *pLocal = C_BaseTFPlayer::GetLocalPlayer();
|
||||
if ( !pLocal )
|
||||
return;
|
||||
|
||||
if ( !GetNumBuildPoints() || !InLocalTeam() )
|
||||
return;
|
||||
|
||||
C_WeaponBuilder *pBuilderWpn = dynamic_cast< C_WeaponBuilder * >( pLocal->GetActiveWeaponForSelection() );
|
||||
if ( !pBuilderWpn )
|
||||
return;
|
||||
if ( !pBuilderWpn->IsPlacingObject() )
|
||||
return;
|
||||
C_BaseObject *pPlacementObj = pBuilderWpn->GetPlacementModel();
|
||||
if ( !pPlacementObj || pPlacementObj == this )
|
||||
return;
|
||||
|
||||
// Near enough?
|
||||
if ( (GetAbsOrigin() - pLocal->GetAbsOrigin()).LengthSqr() < MAX_VISIBLE_BUILDPOINT_DISTANCE )
|
||||
{
|
||||
bool bRestoreModel = false;
|
||||
Vector vecPrevAbsOrigin = pPlacementObj->GetAbsOrigin();
|
||||
QAngle vecPrevAbsAngles = pPlacementObj->GetAbsAngles();
|
||||
|
||||
Vector orgColor;
|
||||
render->GetColorModulation( orgColor.Base() );
|
||||
float orgBlend = render->GetBlend();
|
||||
|
||||
// Any empty buildpoints?
|
||||
for ( int i = 0; i < GetNumBuildPoints(); i++ )
|
||||
{
|
||||
// Can this object build on this point?
|
||||
if ( CanBuildObjectOnBuildPoint( i, pPlacementObj->GetType() ) )
|
||||
{
|
||||
Vector vecBPOrigin;
|
||||
QAngle vecBPAngles;
|
||||
if ( GetBuildPoint(i, vecBPOrigin, vecBPAngles) )
|
||||
{
|
||||
pPlacementObj->InvalidateBoneCaches();
|
||||
|
||||
Vector color( 0, 255, 0 );
|
||||
render->SetColorModulation( color.Base() );
|
||||
float frac = fmod( gpGlobals->curtime, 3 );
|
||||
frac *= 2 * M_PI;
|
||||
frac = cos( frac );
|
||||
render->SetBlend( (175 + (int)( frac * 75.0f )) / 255.0 );
|
||||
|
||||
// HACK: Fixup angles on the HL2 model we're using
|
||||
if ( !strcmp( modelinfo->GetModelName( pPlacementObj->GetModel() ), "models/items/HealthKit.mdl" ) )
|
||||
{
|
||||
vecBPAngles.x += 90;
|
||||
}
|
||||
|
||||
// FIXME: This truly sucks! The bone cache should use
|
||||
// render location for this computation instead of directly accessing AbsAngles
|
||||
// Necessary for bone cache computations to work
|
||||
pPlacementObj->SetAbsOrigin( vecBPOrigin );
|
||||
pPlacementObj->SetAbsAngles( vecBPAngles );
|
||||
|
||||
|
||||
modelrender->DrawModel(
|
||||
flags,
|
||||
pPlacementObj,
|
||||
pPlacementObj->GetModelInstance(),
|
||||
pPlacementObj->index,
|
||||
pPlacementObj->GetModel(),
|
||||
vecBPOrigin,
|
||||
vecBPAngles,
|
||||
pPlacementObj->m_nSkin,
|
||||
pPlacementObj->m_nBody,
|
||||
pPlacementObj->m_nHitboxSet
|
||||
);
|
||||
|
||||
bRestoreModel = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ( bRestoreModel )
|
||||
{
|
||||
pPlacementObj->SetAbsOrigin(vecPrevAbsOrigin);
|
||||
pPlacementObj->SetAbsAngles(vecPrevAbsAngles);
|
||||
pPlacementObj->InvalidateBoneCaches();
|
||||
|
||||
render->SetColorModulation( orgColor.Base() );
|
||||
render->SetBlend( orgBlend );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Exit points for mounted vehicles....
|
||||
//-----------------------------------------------------------------------------
|
||||
void C_BaseObject::GetExitPoint( CBaseEntity *pPlayer, int nBuildPoint, Vector *pAbsPosition, QAngle *pAbsAngles )
|
||||
{
|
||||
Assert(0);
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Overridden to allow for brush-built map defined objects
|
||||
//-----------------------------------------------------------------------------
|
||||
bool C_BaseObject::IsIdentityBrush( void )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Builder preview...
|
||||
//-----------------------------------------------------------------------------
|
||||
void C_BaseObject::ActivateYawPreview( bool enable )
|
||||
{
|
||||
m_YawPreviewState = enable ? YAW_PREVIEW_ON : YAW_PREVIEW_WAITING_FOR_UPDATE;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void C_BaseObject::PreviewYaw( float yaw )
|
||||
{
|
||||
m_fYawPreview = yaw;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
bool C_BaseObject::IsPreviewingYaw() const
|
||||
{
|
||||
return m_YawPreviewState != YAW_PREVIEW_OFF;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: This is called to get the initial builder yaw...
|
||||
//-----------------------------------------------------------------------------
|
||||
float C_BaseObject::GetInitialBuilderYaw()
|
||||
{
|
||||
return GetAbsAngles().y;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void C_BaseObject::PostDataUpdate( DataUpdateType_t updateType )
|
||||
{
|
||||
BaseClass::PostDataUpdate( updateType );
|
||||
|
||||
bool bNewEntity = (updateType == DATA_UPDATE_CREATED);
|
||||
if ( bNewEntity )
|
||||
{
|
||||
m_flAttackTime = -1000;
|
||||
}
|
||||
|
||||
// Determine if we're under attack
|
||||
if ( !bNewEntity )
|
||||
{
|
||||
if ( m_iHealth < m_iOldHealth )
|
||||
{
|
||||
// Deteriorating objects don't play sounds
|
||||
if ( !IsDeteriorating() )
|
||||
{
|
||||
m_flAttackTime = gpGlobals->curtime;
|
||||
}
|
||||
}
|
||||
else if ( m_iHealth > m_iOldHealth && m_iHealth == m_iMaxHealth )
|
||||
{
|
||||
// If we were just fully healed, remove all decals
|
||||
RemoveAllDecals();
|
||||
}
|
||||
}
|
||||
|
||||
if ( m_bHasSapper )
|
||||
{
|
||||
// Play a specific sound for a sapper...
|
||||
if ( m_bOldSapper != m_bHasSapper )
|
||||
{
|
||||
// Don't create these for dragonsteeth
|
||||
if ( InLocalTeam() && GetType() != OBJ_DRAGONSTEETH )
|
||||
{
|
||||
// Play a sound.
|
||||
CLocalPlayerFilter filter;
|
||||
EmitSound( filter, SOUND_FROM_LOCAL_PLAYER, "BaseObject.SapperDestroyingTeamBuilding" );
|
||||
|
||||
MinimapCreateTempTrace( "minimap_under_attack", MINIMAP_PERSONAL_ORDERS, GetAbsOrigin() );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Notify the hint system of the object being built.
|
||||
if ( bNewEntity && GetOwner() && ( GetOwner() == C_BasePlayer::GetLocalPlayer() ) )
|
||||
{
|
||||
C_HintEvent_ObjectBuiltByLocalPlayer event( this );
|
||||
GlobalHintEvent( &event );
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void C_BaseObject::Release( void )
|
||||
{
|
||||
// Remove any reticles on this entity
|
||||
C_BaseTFPlayer *pPlayer = C_BaseTFPlayer::GetLocalPlayer();
|
||||
if ( pPlayer )
|
||||
{
|
||||
pPlayer->Remove_Target( this );
|
||||
}
|
||||
|
||||
BaseClass::Release();
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
bool C_BaseObject::IsUnderAttack( )
|
||||
{
|
||||
// It's under attack for the 3 seconds after the last attack time
|
||||
return (gpGlobals->curtime - m_flAttackTime) < 5.0f;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Ownership:
|
||||
//-----------------------------------------------------------------------------
|
||||
C_BaseTFPlayer *C_BaseObject::GetOwner()
|
||||
{
|
||||
return m_hBuilder;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
bool C_BaseObject::IsOwnedByLocalPlayer() const
|
||||
{
|
||||
if ( !m_hBuilder )
|
||||
return false;
|
||||
|
||||
return ( m_hBuilder == C_BaseTFPlayer::GetLocalPlayer() );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Add entity to visibile entities list
|
||||
//-----------------------------------------------------------------------------
|
||||
void C_BaseObject::AddEntity( void )
|
||||
{
|
||||
// If set to invisible, skip. Do this before resetting the entity pointer so it has
|
||||
// valid data to decide whether it's visible.
|
||||
if ( !ShouldDraw() )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// Update the entity position
|
||||
UpdatePosition();
|
||||
|
||||
// Yaw preview
|
||||
if (m_YawPreviewState != YAW_PREVIEW_OFF)
|
||||
{
|
||||
// This piece of code makes it so we keep using the preview
|
||||
// until we get a network update which matches the update value
|
||||
if (m_YawPreviewState == YAW_PREVIEW_WAITING_FOR_UPDATE)
|
||||
{
|
||||
if (fmod( fabs(GetLocalAngles().y - m_fYawPreview), 360.0f) < 1.0f)
|
||||
{
|
||||
m_YawPreviewState = YAW_PREVIEW_OFF;
|
||||
}
|
||||
}
|
||||
|
||||
if (GetLocalOrigin().y != m_fYawPreview)
|
||||
{
|
||||
SetLocalAnglesDim( Y_INDEX, m_fYawPreview );
|
||||
InvalidateBoneCache();
|
||||
}
|
||||
}
|
||||
|
||||
// Create flashlight effects, etc.
|
||||
CreateLightEffects();
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void C_BaseObject::Select( void )
|
||||
{
|
||||
C_BaseTFPlayer *pPlayer = C_BaseTFPlayer::GetLocalPlayer();
|
||||
pPlayer->SetSelectedObject( this );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Sends client commands back to the server:
|
||||
//-----------------------------------------------------------------------------
|
||||
void C_BaseObject::SendClientCommand( const char *pCmd )
|
||||
{
|
||||
char szbuf[128];
|
||||
Q_snprintf( szbuf, sizeof( szbuf ), "objcmd %d %s", entindex(), pCmd );
|
||||
engine->ClientCmd(szbuf);
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Get a text description for the object target
|
||||
//-----------------------------------------------------------------------------
|
||||
const char *C_BaseObject::GetTargetDescription( void ) const
|
||||
{
|
||||
return GetStatusName();
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Get a text description for the object target (more verbose)
|
||||
//-----------------------------------------------------------------------------
|
||||
char *C_BaseObject::GetIDString( void )
|
||||
{
|
||||
m_szIDString[0] = 0;
|
||||
RecalculateIDString();
|
||||
return m_szIDString;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// It's a valid ID target when it's building
|
||||
//-----------------------------------------------------------------------------
|
||||
bool C_BaseObject::IsValidIDTarget( void )
|
||||
{
|
||||
return InSameTeam( C_BaseTFPlayer::GetLocalPlayer() ) && m_bBuilding;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void C_BaseObject::RecalculateIDString( void )
|
||||
{
|
||||
// Subclasses may have filled this out with a string
|
||||
if ( !m_szIDString[0] )
|
||||
{
|
||||
Q_strncpy( m_szIDString, GetTargetDescription(), sizeof(m_szIDString) );
|
||||
}
|
||||
|
||||
// Have I taken damage?
|
||||
if ( m_iHealth < m_iMaxHealth )
|
||||
{
|
||||
char szHealth[ MAX_ID_STRING ];
|
||||
if ( IsDeteriorating() )
|
||||
{
|
||||
Q_snprintf( szHealth, sizeof(szHealth), "\nBUILDER LOST, DETERIORATING... %.0f percent", ceil(((float)m_iHealth / (float)m_iMaxHealth) * 100) );
|
||||
}
|
||||
else if ( m_bBuilding )
|
||||
{
|
||||
Q_snprintf( szHealth, sizeof(szHealth), "\nConstruction at %.0f percent\nHealth at %.0f percent", (m_flPercentageConstructed * 100), ceil(((float)m_iHealth / (float)m_iMaxHealth) * 100) );
|
||||
}
|
||||
else
|
||||
{
|
||||
Q_snprintf( szHealth, sizeof(szHealth), "\nHealth at %.0f percent", ceil(((float)m_iHealth / (float)m_iMaxHealth) * 100) );
|
||||
}
|
||||
Q_strncat( m_szIDString, szHealth, sizeof(m_szIDString), COPY_ALL_CHARACTERS );
|
||||
}
|
||||
|
||||
if ( m_bHasSapper )
|
||||
{
|
||||
Q_strncat( m_szIDString, "\nUse it to remove the attached enemy object", sizeof(m_szIDString), COPY_ALL_CHARACTERS );
|
||||
}
|
||||
|
||||
// If it's deteriorating, and I can buy it, tell me
|
||||
C_BaseTFPlayer *pLocalPlayer = C_BaseTFPlayer::GetLocalPlayer();
|
||||
if ( IsDeteriorating() && pLocalPlayer && ClassCanBuild( pLocalPlayer->PlayerClass(), GetType() ) )
|
||||
{
|
||||
char szBuy[ MAX_ID_STRING ];
|
||||
int iCost = CalculateObjectCost( GetType(), pLocalPlayer->GetNumObjects( GetType() ), pLocalPlayer->GetTeamNumber() );
|
||||
Q_snprintf( szBuy, sizeof(szBuy), "\nBUY THIS OBJECT FOR %d RESOURCES", iCost );
|
||||
Q_strncat( m_szIDString, szBuy, sizeof(m_szIDString), COPY_ALL_CHARACTERS );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Effects created when the object's running
|
||||
//-----------------------------------------------------------------------------
|
||||
void C_BaseObject::DrawRunningEffects( void )
|
||||
{
|
||||
if ( !GetMaxHealth() )
|
||||
return;
|
||||
|
||||
// Get the overall damage percentage
|
||||
float flDamaged = 1.0 - ((float)GetHealth() / (float)GetMaxHealth());
|
||||
|
||||
// Damage attachment points
|
||||
int iSmokeAttachment, iSparkAttachment;
|
||||
Vector vecSmoke, vecSpark, vecSmokeDir, dir;
|
||||
QAngle angSmoke, angSpark;
|
||||
|
||||
// Look for damage points
|
||||
iSmokeAttachment = LookupRandomAttachment( "r_smoke" );
|
||||
|
||||
// Get the points
|
||||
if ( GetAttachment( iSmokeAttachment, vecSmoke, angSmoke ) )
|
||||
{
|
||||
AngleVectors( angSmoke, &vecSmokeDir);
|
||||
|
||||
float r, g, b;
|
||||
r = g = b = random->RandomFloat( 16, 92 );
|
||||
|
||||
// Smoke
|
||||
CSmartPtr<CObjectSmokeParticles> pSmokeEmitter = CObjectSmokeParticles::Create( "DrawRunningEffects 1" );
|
||||
pSmokeEmitter->SetSortOrigin( vecSmoke );
|
||||
ObjectSmokeParticle *pParticle = (ObjectSmokeParticle *) pSmokeEmitter->AddParticle( sizeof(ObjectSmokeParticle), g_Mat_DustPuff[1], vecSmoke );
|
||||
if ( pParticle )
|
||||
{
|
||||
pParticle->m_flLifetime = 0.0f;
|
||||
pParticle->m_flDieTime = random->RandomFloat( 2.0f, 3.0f );
|
||||
pParticle->m_uchStartSize = random->RandomFloat( 2, 3 );
|
||||
pParticle->m_uchEndSize = random->RandomFloat( 5, 10 );
|
||||
dir[0] = vecSmokeDir[0] + random->RandomFloat( -0.1f, 0.1f );
|
||||
dir[1] = vecSmokeDir[1] + random->RandomFloat( -0.1f, 0.1f );
|
||||
dir[2] = vecSmokeDir[2] + random->RandomFloat( -0.1f, 0.1f );
|
||||
pParticle->m_vecVelocity = dir * random->RandomFloat( 30.0f, 40.0f );
|
||||
pParticle->m_uchStartAlpha = random->RandomFloat( 128,255 );
|
||||
pParticle->m_uchEndAlpha = 0;
|
||||
pParticle->m_flRoll = random->RandomFloat( 180, 360 );
|
||||
pParticle->m_flRollDelta = random->RandomFloat( -1, 1 );
|
||||
pParticle->m_uchColor[0] = r;
|
||||
pParticle->m_uchColor[1] = g;
|
||||
pParticle->m_uchColor[2] = b;
|
||||
pParticle->m_vecAcceleration = Vector(0,0,10);
|
||||
}
|
||||
}
|
||||
|
||||
// Sparks
|
||||
for ( float flSparks = flDamaged - 0.3; flSparks > 0; flSparks -= 0.3 )
|
||||
{
|
||||
// Get random spark attachment point
|
||||
iSparkAttachment = LookupRandomAttachment( "r_spark" );
|
||||
if ( GetAttachment( iSparkAttachment, vecSpark, angSpark ) )
|
||||
{
|
||||
g_pEffects->Sparks( vecSpark );
|
||||
}
|
||||
}
|
||||
|
||||
m_flNextEffect = gpGlobals->curtime + random->RandomFloat( 0.05, 0.1 );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Effects created while the object's building itself
|
||||
//-----------------------------------------------------------------------------
|
||||
void C_BaseObject::DrawBuildEffects( void )
|
||||
{
|
||||
m_flNextEffect = gpGlobals->curtime + 10;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Effects created when the object's damaged
|
||||
//-----------------------------------------------------------------------------
|
||||
void C_BaseObject::DrawDamageEffects( void )
|
||||
{
|
||||
if ( !GetMaxHealth() )
|
||||
return;
|
||||
|
||||
// Get the overall damage percentage
|
||||
float flDamaged = 1.0 - ((float)GetHealth() / (float)GetMaxHealth());
|
||||
|
||||
// Damage attachment points
|
||||
int iSmokeAttachment, iFireAttachment, iSparkAttachment;
|
||||
Vector vecSmoke, vecFire, vecSpark, vecSmokeDir, dir;
|
||||
QAngle angSmoke, angFire, angSpark;
|
||||
|
||||
// HACK: Calculate a random origin
|
||||
// This can go away when we require all objects to have damage attachment points
|
||||
Vector vecOrigin;
|
||||
CollisionProp()->RandomPointInBounds( vec3_origin, Vector( 1, 1, 1 ), &vecOrigin );
|
||||
|
||||
// Look for damage points
|
||||
iSmokeAttachment = LookupRandomAttachment( "d_smoke" );
|
||||
iFireAttachment = LookupRandomAttachment( "d_fire" );
|
||||
|
||||
// Get the points, and if we can't find 'em, use the random origin
|
||||
if ( GetAttachment( iSmokeAttachment, vecSmoke, angSmoke ) )
|
||||
{
|
||||
AngleVectors( angSmoke, &vecSmokeDir );
|
||||
}
|
||||
else
|
||||
{
|
||||
vecSmoke = vecOrigin;
|
||||
vecSmokeDir = Vector(0,0,1);
|
||||
}
|
||||
if ( !GetAttachment( iFireAttachment, vecFire, angFire ) )
|
||||
{
|
||||
vecFire = vecOrigin;
|
||||
angFire = QAngle(0,0,0);
|
||||
}
|
||||
|
||||
float r, g, b;
|
||||
r = g = b = random->RandomFloat( 16, 92 );
|
||||
|
||||
// Smoke
|
||||
CSmartPtr<CSimpleEmitter> pSmokeEmitter = CSimpleEmitter::Create( "DrawDamageEffects 1" );
|
||||
pSmokeEmitter->SetSortOrigin( vecSmoke );
|
||||
SimpleParticle *pParticle = (SimpleParticle *) pSmokeEmitter->AddParticle( sizeof(SimpleParticle), g_Mat_DustPuff[1], vecSmoke );
|
||||
if ( pParticle )
|
||||
{
|
||||
pParticle->m_flLifetime = 0.0f;
|
||||
pParticle->m_flDieTime = random->RandomFloat( 2.0f, 3.0f );
|
||||
pParticle->m_uchStartSize = MAX( 1, 20 * flDamaged );
|
||||
pParticle->m_uchEndSize = MAX( 10, 80 * flDamaged );
|
||||
dir[0] = vecSmokeDir[0] + random->RandomFloat( -0.2f, 0.2f );
|
||||
dir[1] = vecSmokeDir[1] + random->RandomFloat( -0.2f, 0.2f );
|
||||
dir[2] = vecSmokeDir[2] + random->RandomFloat( -0.2f, 0.2f );
|
||||
pParticle->m_vecVelocity = dir * random->RandomFloat( 60.0f, 80.0f );
|
||||
pParticle->m_uchStartAlpha = 255;
|
||||
pParticle->m_uchEndAlpha = 0;
|
||||
pParticle->m_flRoll = random->RandomFloat( 180, 360 );
|
||||
pParticle->m_flRollDelta = random->RandomFloat( -1, 1 );
|
||||
pParticle->m_uchColor[0] = r;
|
||||
pParticle->m_uchColor[1] = g;
|
||||
pParticle->m_uchColor[2] = b;
|
||||
}
|
||||
|
||||
// If we're really hurt, start burning
|
||||
if ( flDamaged > 0.25 )
|
||||
{
|
||||
CSmartPtr<CObjectFireParticles> pFireEmitter = CObjectFireParticles::Create( "DrawDamageEffects 1" );
|
||||
pFireEmitter->SetSortOrigin( vecFire );
|
||||
PMaterialHandle hSphereMaterial = pFireEmitter->GetPMaterial( "sprites/floorflame" );
|
||||
ObjectFireParticle *pParticle = (ObjectFireParticle *) pFireEmitter->AddParticle( sizeof(ObjectFireParticle), hSphereMaterial, vecFire );
|
||||
if ( pParticle )
|
||||
{
|
||||
pParticle->m_hParent = this;
|
||||
pParticle->m_iAttachmentPoint = iFireAttachment;
|
||||
|
||||
pParticle->m_flLifetime = 0.0f;
|
||||
pParticle->m_flDieTime = 1.0;
|
||||
pParticle->m_uchStartSize = MAX( 5, 30 * (flDamaged - 0.25) );
|
||||
pParticle->m_uchEndSize = pParticle->m_uchStartSize;
|
||||
pParticle->m_vecVelocity = Vector(0,0,1);
|
||||
pParticle->m_uchStartAlpha = 255;
|
||||
pParticle->m_uchEndAlpha = 255;
|
||||
pParticle->m_flRoll = 0;
|
||||
pParticle->m_flRollDelta = 0;
|
||||
}
|
||||
}
|
||||
|
||||
// Sparks
|
||||
for ( float flSparks = flDamaged - 0.3; flSparks > 0; flSparks -= 0.3 )
|
||||
{
|
||||
// Get random spark attachment point
|
||||
iSparkAttachment = LookupRandomAttachment( "d_spark" );
|
||||
if ( !GetAttachment( iSparkAttachment, vecSpark, angSpark ) )
|
||||
{
|
||||
vecSpark = vecOrigin;
|
||||
angSpark = QAngle(0,0,0);
|
||||
}
|
||||
|
||||
g_pEffects->Sparks( vecSpark );
|
||||
}
|
||||
|
||||
m_flNextEffect = gpGlobals->curtime + random->RandomFloat( 0.2, 0.5 );
|
||||
}
|
||||
|
||||
//============================================================================================================
|
||||
// POWER PROXY
|
||||
//============================================================================================================
|
||||
class CObjectPowerProxy : public CResultProxy
|
||||
{
|
||||
public:
|
||||
bool Init( IMaterial *pMaterial, KeyValues *pKeyValues );
|
||||
void OnBind( void *pC_BaseEntity );
|
||||
|
||||
private:
|
||||
CFloatInput m_Factor;
|
||||
};
|
||||
|
||||
bool CObjectPowerProxy::Init( IMaterial *pMaterial, KeyValues *pKeyValues )
|
||||
{
|
||||
if (!CResultProxy::Init( pMaterial, pKeyValues ))
|
||||
return false;
|
||||
|
||||
if (!m_Factor.Init( pMaterial, pKeyValues, "scale", 1 ))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void CObjectPowerProxy::OnBind( void *pRenderable )
|
||||
{
|
||||
// Find the view angle between the player and this entity....
|
||||
IClientRenderable *pRend = (IClientRenderable *)pRenderable;
|
||||
C_BaseEntity *pEntity = pRend->GetIClientUnknown()->GetBaseEntity();
|
||||
C_BaseObject *pObject = dynamic_cast<C_BaseObject*>(pEntity);
|
||||
if (!pObject)
|
||||
return;
|
||||
|
||||
int iPowered = pObject->IsPowered();
|
||||
|
||||
SetFloatResult( iPowered * m_Factor.GetFloat() );
|
||||
}
|
||||
|
||||
EXPOSE_INTERFACE( CObjectPowerProxy, IMaterialProxy, "ObjectPower" IMATERIAL_PROXY_INTERFACE_VERSION );
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Control screen
|
||||
//-----------------------------------------------------------------------------
|
||||
class CBasicControlPanel : public CObjectControlPanel
|
||||
{
|
||||
DECLARE_CLASS( CBasicControlPanel, CObjectControlPanel );
|
||||
|
||||
public:
|
||||
CBasicControlPanel( vgui::Panel *parent, const char *panelName );
|
||||
};
|
||||
|
||||
|
||||
DECLARE_VGUI_SCREEN_FACTORY( CBasicControlPanel, "basic_control_panel" );
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Constructor:
|
||||
//-----------------------------------------------------------------------------
|
||||
CBasicControlPanel::CBasicControlPanel( vgui::Panel *parent, const char *panelName )
|
||||
: BaseClass( parent, "CBasicControlPanel" )
|
||||
{
|
||||
}
|
||||
@@ -0,0 +1,223 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose: Clients CBaseObject
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================//
|
||||
|
||||
#ifndef C_BASEOBJECT_H
|
||||
#define C_BASEOBJECT_H
|
||||
#ifdef _WIN32
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include "baseobject_shared.h"
|
||||
#include <vgui_controls/Panel.h>
|
||||
#include <vgui_controls/Label.h>
|
||||
#include "vgui_healthbar.h"
|
||||
#include "commanderoverlay.h"
|
||||
#include "hud_minimap.h"
|
||||
#include "particlemgr.h"
|
||||
#include "particle_prototype.h"
|
||||
#include "particle_util.h"
|
||||
#include "c_basecombatcharacter.h"
|
||||
#include "ihasbuildpoints.h"
|
||||
|
||||
class C_BaseTFPlayer;
|
||||
|
||||
// Max Length of ID Strings
|
||||
#define MAX_ID_STRING 256
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
class C_BaseObject : public C_BaseCombatCharacter, public IHasBuildPoints
|
||||
{
|
||||
DECLARE_CLASS( C_BaseObject, C_BaseCombatCharacter );
|
||||
public:
|
||||
DECLARE_CLIENTCLASS();
|
||||
DECLARE_ENTITY_PANEL();
|
||||
DECLARE_MINIMAP_PANEL();
|
||||
|
||||
C_BaseObject();
|
||||
~C_BaseObject( void );
|
||||
|
||||
virtual bool IsBaseObject( void ) const { return true; }
|
||||
virtual bool IsAnUpgrade(void ) const { return false; }
|
||||
virtual bool IsAVehicle( void ) const { return false; }
|
||||
|
||||
virtual void SetType( int iObjectType );
|
||||
|
||||
virtual void AddEntity();
|
||||
virtual void Select( void );
|
||||
|
||||
void SetActivity( Activity act );
|
||||
Activity GetActivity( ) const;
|
||||
void SetObjectSequence( int sequence );
|
||||
virtual void OnActivityChanged( Activity act );
|
||||
|
||||
virtual void PreDataUpdate( DataUpdateType_t updateType );
|
||||
virtual void PostDataUpdate( DataUpdateType_t updateType );
|
||||
virtual void OnDataChanged( DataUpdateType_t updateType );
|
||||
virtual void Release( void );
|
||||
|
||||
virtual int GetHealth() const { return m_iHealth; }
|
||||
void SetHealth( int health ) { m_iHealth = health; }
|
||||
virtual int GetMaxHealth() const { return m_iMaxHealth; }
|
||||
int GetObjectFlags( void ) { return m_fObjectFlags; }
|
||||
void SetObjectFlags( int flags ) { m_fObjectFlags = flags; }
|
||||
|
||||
// Derive to customize an object's attached version
|
||||
virtual void SetupAttachedVersion( void ) { return; }
|
||||
virtual void SetupUnattachedVersion( void ) { return; }
|
||||
virtual void OnLostPower( void ) { return; };
|
||||
|
||||
virtual const char *GetTargetDescription( void ) const;
|
||||
virtual char *GetIDString( void );
|
||||
virtual bool IsValidIDTarget( void );
|
||||
|
||||
void AttemptToGoActive( void );
|
||||
virtual bool ShouldBeActive( void );
|
||||
virtual void OnGoActive( void );
|
||||
virtual void OnGoInactive( void );
|
||||
|
||||
virtual void SetDormant( bool bDormant );
|
||||
|
||||
void SendClientCommand( const char *pCmd );
|
||||
|
||||
virtual void FireEvent( const Vector& origin, const QAngle& angles, int event, const char *options );
|
||||
|
||||
// Builder preview...
|
||||
void ActivateYawPreview( bool enable );
|
||||
void PreviewYaw( float yaw );
|
||||
bool IsPreviewingYaw() const;
|
||||
|
||||
// This is called to get the initial builder yaw...
|
||||
virtual float GetInitialBuilderYaw();
|
||||
|
||||
virtual void RecalculateIDString( void );
|
||||
|
||||
int GetType() const { return m_iObjectType; }
|
||||
bool IsOwnedByLocalPlayer() const;
|
||||
C_BaseTFPlayer *GetOwner();
|
||||
|
||||
// Are we under attack?
|
||||
bool IsUnderAttack( );
|
||||
|
||||
virtual int DrawModel( int flags );
|
||||
virtual bool IsIdentityBrush( void );
|
||||
|
||||
// Effects
|
||||
void DrawRunningEffects( void );
|
||||
void DrawBuildEffects( void );
|
||||
void DrawDamageEffects( void );
|
||||
|
||||
// Deterioration
|
||||
bool IsDeteriorating( void ) { return m_bDeteriorating; };
|
||||
|
||||
float GetPercentageConstructed( void ) { return m_flPercentageConstructed; }
|
||||
|
||||
bool IsPlacing( void ) const { return m_bPlacing; }
|
||||
bool IsBuilding( void ) const { return m_bBuilding; }
|
||||
|
||||
virtual void FinishedBuilding( void ) { return; }
|
||||
|
||||
virtual bool OffsetObjectOrigin( Vector& origin );
|
||||
|
||||
virtual const char* GetStatusName() const;
|
||||
|
||||
// Object Previews
|
||||
void HighlightBuildPoints( int flags );
|
||||
|
||||
public:
|
||||
// Client/Server shared build point code
|
||||
void CreateBuildPoints( void );
|
||||
void AddAndParseBuildPoint( int iAttachmentNumber, KeyValues *pkvBuildPoint );
|
||||
virtual int AddBuildPoint( int iAttachmentNum );
|
||||
virtual void AddValidObjectToBuildPoint( int iPoint, int iObjectType );
|
||||
virtual CBaseObject *GetBuildPointObject( int iPoint );
|
||||
bool IsBuiltOnAttachment( void ) { return (m_hBuiltOnEntity != NULL); }
|
||||
void AttachObjectToObject( CBaseEntity *pEntity, int iPoint, Vector &vecOrigin );
|
||||
CBaseObject *GetParentObject( void );
|
||||
void SetBuildPointPassenger( int iPoint, int iPassenger );
|
||||
int GetBuildPointPassenger( int iPoint ) const;
|
||||
|
||||
// Build points
|
||||
CUtlVector<BuildPoint_t> m_BuildPoints;
|
||||
|
||||
// Power
|
||||
bool IsPowered( void );
|
||||
virtual bool CanPowerupEver( int iPowerup );
|
||||
virtual bool CanPowerupNow( int iPowerup );
|
||||
|
||||
bool IsDisabled( void ) { return m_bDisabled; }
|
||||
|
||||
virtual float GetSapperAttachTime( void );
|
||||
|
||||
// IHasBuildPoints
|
||||
public:
|
||||
virtual int GetNumBuildPoints( void ) const;
|
||||
virtual bool GetBuildPoint( int iPoint, Vector &vecOrigin, QAngle &vecAngles );
|
||||
virtual int GetBuildPointAttachmentIndex( int iPoint ) const;
|
||||
virtual bool CanBuildObjectOnBuildPoint( int iPoint, int iObjectType );
|
||||
virtual void SetObjectOnBuildPoint( int iPoint, CBaseObject *pObject );
|
||||
virtual float GetMaxSnapDistance( int iBuildPoint );
|
||||
virtual bool ShouldCheckForMovement( void ) { return true; }
|
||||
virtual int GetNumObjectsOnMe( void );
|
||||
virtual CBaseEntity *GetFirstObjectOnMe( void );
|
||||
virtual CBaseObject *GetObjectOfTypeOnMe( int iObjectType );
|
||||
virtual void RemoveAllObjects( void );
|
||||
virtual int FindObjectOnBuildPoint( CBaseObject *pObject );
|
||||
virtual void GetExitPoint( CBaseEntity *pPlayer, int iPoint, Vector *pAbsOrigin, QAngle *pAbsAngles );
|
||||
|
||||
virtual bool TestHitboxes( const Ray_t &ray, unsigned int fContentsMask, trace_t& tr );
|
||||
|
||||
protected:
|
||||
char m_szIDString[ MAX_ID_STRING ];
|
||||
|
||||
private:
|
||||
enum
|
||||
{
|
||||
YAW_PREVIEW_OFF = 0,
|
||||
YAW_PREVIEW_ON,
|
||||
YAW_PREVIEW_WAITING_FOR_UPDATE
|
||||
};
|
||||
|
||||
Activity m_Activity;
|
||||
|
||||
int m_fObjectFlags;
|
||||
float m_fYawPreview;
|
||||
char m_YawPreviewState;
|
||||
CHandle< C_BaseTFPlayer > m_hOldOwner;
|
||||
CHandle< C_BaseTFPlayer > m_hBuilder;
|
||||
bool m_bWasActive;
|
||||
int m_iOldHealth;
|
||||
bool m_bHasSapper;
|
||||
bool m_bOldSapper;
|
||||
int m_iObjectType;
|
||||
int m_iHealth;
|
||||
int m_iMaxHealth;
|
||||
bool m_bWasBuilding;
|
||||
bool m_bBuilding;
|
||||
bool m_bPlacing;
|
||||
bool m_bDeteriorating;
|
||||
bool m_bDisabled;
|
||||
float m_flPercentageConstructed;
|
||||
EHANDLE m_hBuiltOnEntity;
|
||||
|
||||
CHealthBarPanel *m_pHealthBar;
|
||||
vgui::Label *m_pNameLabel;
|
||||
float m_flDamageFlash; // Used to flash the panel when the object takes damage
|
||||
int m_iFlashes;
|
||||
|
||||
float m_flAttackTime;
|
||||
CMaterialReference m_ThermalMaterial;
|
||||
|
||||
// Effects
|
||||
float m_flNextEffect;
|
||||
|
||||
private:
|
||||
C_BaseObject( const C_BaseObject & ); // not defined, not accessible
|
||||
};
|
||||
|
||||
#endif // C_BASEOBJECT_H
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,386 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================//
|
||||
|
||||
#if !defined( C_BASETFPLAYER_H )
|
||||
#define C_BASETFPLAYER_H
|
||||
#ifdef _WIN32
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include "tf_vehicleshared.h"
|
||||
#include "c_baseplayer.h"
|
||||
#include "CommanderOverlay.h"
|
||||
#include "hud_minimap.h"
|
||||
#include "hud_targetreticle.h"
|
||||
#include "c_tfplayerlocaldata.h"
|
||||
#include "particlemgr.h"
|
||||
#include "particle_prototype.h"
|
||||
#include "particle_util.h"
|
||||
#include "tf_playeranimstate.h"
|
||||
|
||||
class C_VehicleTeleportStation;
|
||||
class CViewSetup;
|
||||
class IMaterial;
|
||||
class C_Order;
|
||||
class C_BaseObject;
|
||||
class C_PlayerClass;
|
||||
class CPersonalShieldEffect;
|
||||
class CBasePredictedWeapon;
|
||||
class C_BaseViewModel;
|
||||
class CUserCmd;
|
||||
class C_WeaponCombatShield;
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Client Side TF Player entity
|
||||
//-----------------------------------------------------------------------------
|
||||
class C_BaseTFPlayer : public C_BasePlayer
|
||||
{
|
||||
public:
|
||||
DECLARE_CLASS( C_BaseTFPlayer, C_BasePlayer );
|
||||
DECLARE_CLIENTCLASS();
|
||||
DECLARE_ENTITY_PANEL();
|
||||
DECLARE_MINIMAP_PANEL();
|
||||
DECLARE_PREDICTABLE();
|
||||
|
||||
C_BaseTFPlayer();
|
||||
virtual ~C_BaseTFPlayer();
|
||||
|
||||
private:
|
||||
void Clear(); // Clear all elements.
|
||||
|
||||
public:
|
||||
bool IsHidden() const;
|
||||
bool IsDamageBoosted() const;
|
||||
|
||||
bool HasNamedTechnology( const char *name );
|
||||
|
||||
float LastAttackTime() const { return m_flLastAttackTime; }
|
||||
void SetLastAttackTime( float flTime ) { m_flLastAttackTime = flTime; }
|
||||
|
||||
// Return this client's C_BaseTFPlayer pointer
|
||||
static C_BaseTFPlayer* GetLocalPlayer( void )
|
||||
{
|
||||
return ( static_cast< C_BaseTFPlayer * >( C_BasePlayer::GetLocalPlayer() ) );
|
||||
}
|
||||
|
||||
virtual void ClientThink( void );
|
||||
virtual void OnPreDataChanged( DataUpdateType_t updateType );
|
||||
virtual void OnDataChanged( DataUpdateType_t updateType );
|
||||
virtual void PreDataUpdate( DataUpdateType_t updateType );
|
||||
virtual void PostDataUpdate( DataUpdateType_t updateType );
|
||||
virtual void ReceiveMessage( int classID, bf_read &msg );
|
||||
virtual void Release( void );
|
||||
|
||||
virtual void ItemPostFrame( void );
|
||||
|
||||
virtual bool ShouldDraw();
|
||||
virtual int DrawModel( int flags );
|
||||
|
||||
virtual void SetDormant( bool bDormant );
|
||||
|
||||
virtual void GetBoneControllers(float controllers[MAXSTUDIOBONES]);
|
||||
|
||||
virtual int GetRenderTeamNumber( void );
|
||||
virtual void ComputeFxBlend( void );
|
||||
virtual bool IsTransparent( void );
|
||||
|
||||
// Called by the view model if its rendering is being overridden.
|
||||
virtual bool ViewModel_IsTransparent( void );
|
||||
|
||||
virtual bool IsOverridingViewmodel( void );
|
||||
virtual int DrawOverriddenViewmodel( C_BaseViewModel *pViewmodel, int flags );
|
||||
virtual void CreateMove( float flInputSampleTime, CUserCmd *pCmd );
|
||||
virtual float GetDefaultAnimSpeed( void );
|
||||
|
||||
int GetClass( void );
|
||||
|
||||
// Called when not in tactical mode. Allows view to be overriden for things like driving a tank.
|
||||
void OverrideView( CViewSetup *pSetup );
|
||||
|
||||
// Called when not in tactical mode. Allows view model drawing to be disabled for things like driving a tank.
|
||||
bool ShouldDrawViewModel();
|
||||
|
||||
void GetTargetDescription( char *pDest, int bufferSize );
|
||||
|
||||
// Orders
|
||||
void SetPersonalOrder( C_Order *pOrder );
|
||||
void RemoveOrderTarget();
|
||||
|
||||
// Resources
|
||||
int GetBankResources( void );
|
||||
|
||||
// Objects
|
||||
void SetSelectedObject( C_BaseObject *pObject );
|
||||
C_BaseObject *GetSelectedObject( void );
|
||||
int GetNumObjects( int iObjectType );
|
||||
int GetObjectCount( void );
|
||||
C_BaseObject *GetObject( int index );
|
||||
|
||||
// Targets
|
||||
void Add_Target( C_BaseEntity *pTarget, const char *sName );
|
||||
void Remove_Target( C_BaseEntity *pTarget );
|
||||
void Remove_Target( CTargetReticle *pTargetReticle );
|
||||
|
||||
void UpdateTargetReticles( void );
|
||||
|
||||
bool IsUsingThermalVision( void ) const;
|
||||
|
||||
// Weapon handling
|
||||
virtual bool IsAllowedToSwitchWeapons( void );
|
||||
virtual bool Weapon_ShouldSetLast( CBaseCombatWeapon *pOldWeapon, CBaseCombatWeapon *pNewWeapon );
|
||||
virtual bool Weapon_ShouldSelectItem( CBaseCombatWeapon *pWeapon );
|
||||
virtual C_BaseCombatWeapon *GetActiveWeaponForSelection( void );
|
||||
virtual C_BaseCombatWeapon *GetLastWeaponBeforeObject( void ) { return m_hLastWeaponBeforeObject; }
|
||||
|
||||
virtual C_BaseAnimating* GetRenderedWeaponModel();
|
||||
|
||||
// ID Target
|
||||
void SetIDEnt( C_BaseEntity *pEntity );
|
||||
int GetIDTarget( void ) const;
|
||||
void UpdateIDTarget( void );
|
||||
|
||||
bool IsKnockedDown( void ) const;
|
||||
void CheckKnockdownState( void );
|
||||
bool CheckKnockdownAngleOverride( void ) const;
|
||||
void SetKnockdownAngles( const QAngle& ang );
|
||||
void GetKnockdownAngles( QAngle& outAngles );
|
||||
float GetKnockdownViewheightAdjust( void ) const;
|
||||
|
||||
// Team handling
|
||||
virtual void TeamChange( int iNewTeam );
|
||||
|
||||
// Camouflage effect
|
||||
virtual bool IsCamouflaged( void );
|
||||
virtual float GetCamouflageAmount( void );
|
||||
virtual float ComputeCamoEffectAmount( void ); // 0 - visible, 1 = invisible
|
||||
virtual int ComputeCamoAlpha( void );
|
||||
virtual void CheckCamoDampening( void );
|
||||
virtual void SetCamoDampening( float amount );
|
||||
virtual float GetDampeningAmount( void );
|
||||
virtual void CheckCameraMovement( void );
|
||||
|
||||
IMaterial *GetCamoMaterial( void );
|
||||
virtual float GetMovementCamoSuppression( void );
|
||||
virtual void CheckMovementCamoSuppression( void );
|
||||
virtual void SetMovementCamoSuppression( float amount );
|
||||
|
||||
// Adrenalin
|
||||
void CheckAdrenalin( void );
|
||||
|
||||
void CheckLastMovement( void );
|
||||
float GetLastMoveTime( void );
|
||||
float GetOverlayAlpha( void );
|
||||
|
||||
float GetLastDamageTime( void ) const;
|
||||
float GetLastGainHealthTime( void ) const;
|
||||
|
||||
// Powerups
|
||||
virtual void PowerupStart( int iPowerup, bool bInitial );
|
||||
virtual void PowerupEnd( int iPowerup );
|
||||
|
||||
// Sniper
|
||||
bool IsDeployed( void );
|
||||
bool IsDeploying( void );
|
||||
bool IsUnDeploying( void );
|
||||
|
||||
virtual void AddEntity( void );
|
||||
|
||||
// Vertification
|
||||
inline bool HasClass( void ) { return GetPlayerClass() != NULL; }
|
||||
|
||||
bool IsClass( TFClass iClass );
|
||||
|
||||
|
||||
virtual int GetMaxHealth() const { return m_iMaxHealth; }
|
||||
|
||||
bool ClassProxyUpdate( int nClassID );
|
||||
|
||||
// Should this object cast shadows?
|
||||
virtual ShadowType_t ShadowCastType();
|
||||
|
||||
// Prediction stuff
|
||||
virtual void PreThink( void );
|
||||
virtual void PostThink( void );
|
||||
|
||||
// Combat prototyping
|
||||
bool IsBlocking( void ) const { return m_bIsBlocking; }
|
||||
bool IsParrying( void ) const { return m_bIsParrying; }
|
||||
void SetBlocking( bool bBlocking ) { m_bIsBlocking = bBlocking; }
|
||||
void SetParrying( bool bParrying ) { m_bIsParrying = bParrying; }
|
||||
|
||||
// Vehicles
|
||||
void SetVehicleRole( int nRole );
|
||||
bool CanGetInVehicle( void );
|
||||
|
||||
// Returns true if we're in a vehicle and it's mounted on another vehicle
|
||||
// (ie: are we in a manned gun that's mounted on a tank).
|
||||
bool IsVehicleMounted() const;
|
||||
|
||||
virtual bool IsUseableEntity( CBaseEntity *pEntity );
|
||||
|
||||
// Shared Client / Server code
|
||||
public:
|
||||
bool IsHittingShield( const Vector &vecVelocity, float *flDamage );
|
||||
C_WeaponCombatShield *GetCombatShield( void );
|
||||
virtual void PainSound( void );
|
||||
|
||||
public:
|
||||
// Data for only the local player
|
||||
CTFPlayerLocalData m_TFLocal;
|
||||
|
||||
// Accessors...
|
||||
const QAngle& DeployedAngles() const { return m_vecDeployedAngles; }
|
||||
int ZoneState() const { return m_iCurrentZoneState; }
|
||||
float CamouflageAmount() const { return m_flCamouflageAmount; }
|
||||
int PlayerClass() const { return m_iPlayerClass; }
|
||||
C_PlayerClass *GetPlayerClass();
|
||||
C_Order *PersonalOrder() { return m_hPersonalOrder; }
|
||||
C_BaseEntity *SpawnPoint() { return m_hSpawnPoint.Get(); }
|
||||
|
||||
C_VehicleTeleportStation* GetSelectedMCV() const;
|
||||
|
||||
// Object sapper placement handling
|
||||
//float m_flSapperAttachmentFinishTime;
|
||||
//float m_flSapperAttachmentStartTime;
|
||||
//CHandle< CGrenadeObjectSapper > m_hSapper;
|
||||
//CHandle< CBaseObject > m_hSappedObject;
|
||||
CHealthBarPanel *m_pSapperAttachmentStatus;
|
||||
|
||||
private:
|
||||
C_BaseTFPlayer( const C_BaseTFPlayer & );
|
||||
|
||||
// Client-side obstacle avoidance
|
||||
void PerformClientSideObstacleAvoidance( float flFrameTime, CUserCmd *pCmd );
|
||||
|
||||
float m_flLastAttackTime;
|
||||
|
||||
EHANDLE m_hSelectedMCV;
|
||||
|
||||
// Weapon used before switching to an object placement
|
||||
CHandle<C_BaseCombatWeapon> m_hLastWeaponBeforeObject;
|
||||
|
||||
float m_flCamouflageAmount;
|
||||
|
||||
// Movement.
|
||||
Vector m_vecPosDelta;
|
||||
|
||||
enum { MOMENTUM_MAXSIZE = 10 };
|
||||
float m_aMomentum[MOMENTUM_MAXSIZE];
|
||||
int m_iMomentumHead;
|
||||
|
||||
// Player Class
|
||||
int m_iPlayerClass;
|
||||
C_AllPlayerClasses m_PlayerClasses;
|
||||
|
||||
// Spawn location...
|
||||
EHANDLE m_hSpawnPoint;
|
||||
|
||||
// Orders
|
||||
CHandle< C_Order > m_hSelectedOrder;
|
||||
CHandle< C_Order > m_hPersonalOrder;
|
||||
int m_iSelectedTarget;
|
||||
int m_iPersonalTarget;
|
||||
CUtlVector< CTargetReticle * > m_aTargetReticles; // A list of entities to show target reticles for
|
||||
|
||||
// Objects
|
||||
CHandle< C_BaseObject > m_hSelectedObject;
|
||||
|
||||
int m_iLastHealth;
|
||||
|
||||
bool m_bIsBlocking;
|
||||
bool m_bIsParrying;
|
||||
|
||||
bool m_bUnderAttack;
|
||||
int m_iMaxHealth;
|
||||
bool m_bDeployed;
|
||||
bool m_bDeploying;
|
||||
bool m_bUnDeploying;
|
||||
QAngle m_vecDeployedAngles;
|
||||
int m_iCurrentZoneState;
|
||||
int m_TFPlayerFlags;
|
||||
|
||||
int m_nOldTacticalView;
|
||||
int m_nOldPlayerClass;
|
||||
|
||||
float m_flNextUseCheck;
|
||||
|
||||
bool m_bOldThermalVision;
|
||||
bool m_bOldAttachingSapper;
|
||||
|
||||
bool m_bOldKnockDownState;
|
||||
float m_flStartKnockdown;
|
||||
float m_flEndKnockdown;
|
||||
QAngle m_vecOriginalViewAngles;
|
||||
QAngle m_vecCurrentKnockdownAngles;
|
||||
QAngle m_vecKnockDownGoalAngles;
|
||||
bool m_bKnockdownOverrideAngles;
|
||||
float m_flKnockdownViewheightAdjust;
|
||||
|
||||
CPlayerAnimState m_PlayerAnimState;
|
||||
|
||||
// For sniper hiding
|
||||
float m_flLastMoveTime;
|
||||
Vector m_vecLastOrigin;
|
||||
|
||||
// For material proxies
|
||||
float m_flLastDamageTime;
|
||||
float m_flLastGainHealthTime;
|
||||
|
||||
IMaterial *m_pThermalMaterial;
|
||||
IMaterial *m_pCamoEffectMaterial;
|
||||
|
||||
// Camouflage
|
||||
float m_flDampeningAmount;
|
||||
float m_flGoalDampeningAmount;
|
||||
float m_flDampeningStayoutTime;
|
||||
|
||||
// Suppression of camo based on movement
|
||||
float m_flMovementCamoSuppression;
|
||||
float m_flGoalMovementCamoSuppressionAmount;
|
||||
float m_flMovementCamoSuppressionStayoutTime;
|
||||
|
||||
// Adrenalin
|
||||
float m_flNextAdrenalinEffect;
|
||||
bool m_bFadingIn;
|
||||
|
||||
// ID Target
|
||||
int m_iIDEntIndex;
|
||||
|
||||
CMaterialReference m_BoostMaterial;
|
||||
CMaterialReference m_EMPMaterial;
|
||||
float m_BoostModelAngles[3];
|
||||
|
||||
// Personal shield effects.
|
||||
CUtlLinkedList<CPersonalShieldEffect*, int> m_PersonalShieldEffects;
|
||||
|
||||
CHandle< C_WeaponCombatShield > m_hWeaponCombatShield;
|
||||
|
||||
// No one should call this
|
||||
C_BaseTFPlayer& operator=( const C_BaseTFPlayer& src );
|
||||
|
||||
friend void RecvProxy_PlayerClass( const CRecvProxyData *pData, void *pStruct, void *pOut );
|
||||
|
||||
|
||||
friend class CTFPrediction;
|
||||
};
|
||||
|
||||
int GetLocalPlayerClass( void );
|
||||
bool IsLocalPlayerClass( int iClass );
|
||||
bool IsLocalPlayerInTactical( );
|
||||
inline C_BaseTFPlayer *ToBaseTFPlayer( C_BaseEntity *pEntity )
|
||||
{
|
||||
if ( !pEntity || !pEntity->IsPlayer() )
|
||||
return NULL;
|
||||
|
||||
#if _DEBUG
|
||||
return dynamic_cast<C_BaseTFPlayer *>( pEntity );
|
||||
#else
|
||||
return static_cast<C_BaseTFPlayer *>( pEntity );
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif // C_BASETFPLAYER_H
|
||||
@@ -0,0 +1,67 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $Workfile: $
|
||||
// $Date: $
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
// $Log: $
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================//
|
||||
#include "cbase.h"
|
||||
#include "c_controlzone.h"
|
||||
#include "mapdata.h"
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
C_ControlZone::C_ControlZone()
|
||||
{
|
||||
m_nZoneNumber = 0;
|
||||
|
||||
m_pShowTriggers = cvar->FindVar("showtriggers");
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
C_ControlZone::~C_ControlZone()
|
||||
{
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Are we using showtriggers?
|
||||
// Output : Returns true on success, false on failure.
|
||||
//-----------------------------------------------------------------------------
|
||||
bool C_ControlZone::ShouldDraw()
|
||||
{
|
||||
if ( !m_pShowTriggers )
|
||||
return false;
|
||||
|
||||
return m_pShowTriggers->GetInt() != 0 ? true : false;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Update global map state based on data received
|
||||
// Input : bnewentity -
|
||||
//-----------------------------------------------------------------------------
|
||||
void C_ControlZone::OnDataChanged( DataUpdateType_t updateType )
|
||||
{
|
||||
BaseClass::OnDataChanged( updateType );
|
||||
|
||||
CMapZones *zone;
|
||||
if ( m_nZoneNumber < 1 ||
|
||||
m_nZoneNumber > MAX_ZONES )
|
||||
return;
|
||||
|
||||
zone = &MapData().m_Zones[ m_nZoneNumber -1 ];
|
||||
zone->m_nControllingTeam = GetTeamNumber();
|
||||
}
|
||||
|
||||
IMPLEMENT_CLIENTCLASS_DT(C_ControlZone, DT_ControlZone, CControlZone)
|
||||
RecvPropInt( RECVINFO(m_nZoneNumber )),
|
||||
END_RECV_TABLE()
|
||||
|
||||
|
||||
@@ -0,0 +1,39 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $Workfile: $
|
||||
// $Date: $
|
||||
// $NoKeywords: $
|
||||
//=============================================================================//
|
||||
|
||||
#if !defined( C_CONTROLZONE_H )
|
||||
#define C_CONTROLZONE_H
|
||||
#ifdef _WIN32
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
class ConVar;
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Client side rep of control zone entity ( trigger, so not usually visible )
|
||||
//-----------------------------------------------------------------------------
|
||||
class C_ControlZone : public C_BaseEntity
|
||||
{
|
||||
public:
|
||||
DECLARE_CLASS( C_ControlZone, C_BaseEntity );
|
||||
DECLARE_CLIENTCLASS();
|
||||
|
||||
C_ControlZone();
|
||||
virtual ~C_ControlZone();
|
||||
|
||||
virtual bool ShouldDraw();
|
||||
virtual void OnDataChanged( DataUpdateType_t updateType );
|
||||
|
||||
public:
|
||||
int m_nZoneNumber;
|
||||
|
||||
private:
|
||||
const ConVar *m_pShowTriggers;
|
||||
};
|
||||
|
||||
#endif // C_CONTROLZONE_H
|
||||
@@ -0,0 +1,35 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================//
|
||||
#include "cbase.h"
|
||||
#include "c_demo_entities.h"
|
||||
|
||||
|
||||
IMPLEMENT_CLIENTCLASS_DT(C_Cycler_TF2Commando, DT_Cycler_TF2Commando, CCycler_TF2Commando)
|
||||
RecvPropInt( RECVINFO(m_bShieldActive) ),
|
||||
RecvPropFloat( RECVINFO(m_flShieldRaiseTime) ),
|
||||
RecvPropFloat( RECVINFO(m_flShieldLowerTime) ),
|
||||
END_RECV_TABLE()
|
||||
|
||||
C_Cycler_TF2Commando::C_Cycler_TF2Commando()
|
||||
{
|
||||
}
|
||||
|
||||
float C_Cycler_TF2Commando::GetShieldRaiseTime() const
|
||||
{
|
||||
return m_bShieldActive ? gpGlobals->curtime - m_flShieldRaiseTime : 0.0f;
|
||||
}
|
||||
|
||||
float C_Cycler_TF2Commando::GetShieldLowerTime() const
|
||||
{
|
||||
return !m_bShieldActive ? gpGlobals->curtime - m_flShieldLowerTime : 0.0f;
|
||||
}
|
||||
|
||||
bool C_Cycler_TF2Commando::IsShieldActive() const
|
||||
{
|
||||
return m_bShieldActive;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,36 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================//
|
||||
|
||||
#ifndef C_DEMO_ENTITIES_H
|
||||
#define C_DEMO_ENTITIES_H
|
||||
|
||||
#include "c_ai_basenpc.h"
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
class C_Cycler_TF2Commando : public C_AI_BaseNPC
|
||||
{
|
||||
DECLARE_CLASS( C_Cycler_TF2Commando, C_AI_BaseNPC );
|
||||
public:
|
||||
DECLARE_CLIENTCLASS();
|
||||
|
||||
C_Cycler_TF2Commando();
|
||||
|
||||
float GetShieldRaiseTime() const;
|
||||
float GetShieldLowerTime() const;
|
||||
bool IsShieldActive() const;
|
||||
|
||||
private:
|
||||
C_Cycler_TF2Commando( const C_Cycler_TF2Commando& );
|
||||
|
||||
bool m_bShieldActive;
|
||||
float m_flShieldRaiseTime;
|
||||
float m_flShieldLowerTime;
|
||||
};
|
||||
|
||||
#endif // C_DEMO_ENTITIES_H
|
||||
@@ -0,0 +1,179 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose: Client's Meteor
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================//
|
||||
#include "cbase.h"
|
||||
#include "c_effect_shootingstar.h"
|
||||
#include "clienteffectprecachesystem.h"
|
||||
|
||||
//=============================================================================
|
||||
//
|
||||
// Shooting Star Spawner Functionality
|
||||
//
|
||||
|
||||
IMPLEMENT_CLIENTCLASS_DT( C_ShootingStarSpawner, DT_ShootingStarSpawner, CShootingStarSpawner )
|
||||
RecvPropFloat( RECVINFO( m_flSpawnInterval ) ),
|
||||
END_RECV_TABLE()
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
C_ShootingStarSpawner::C_ShootingStarSpawner( void )
|
||||
{
|
||||
SetNextClientThink( gpGlobals->curtime + m_flSpawnInterval );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void C_ShootingStarSpawner::ClientThink( void )
|
||||
{
|
||||
// Spawn a number of shooting stars.
|
||||
SpawnShootingStars();
|
||||
|
||||
// Randomly generate a next think time.
|
||||
SetNextClientThink( gpGlobals->curtime + random->RandomFloat( 0.25, m_flSpawnInterval ) );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void C_ShootingStarSpawner::SpawnShootingStars( void )
|
||||
{
|
||||
C_ShootingStar *pShootingStar = new C_ShootingStar;
|
||||
if ( pShootingStar )
|
||||
{
|
||||
// In Space.
|
||||
pShootingStar->SetFriction( 1.0f );
|
||||
pShootingStar->SetGravity( 0.0f );
|
||||
|
||||
// Randomize the velocity. -- This isn't right, but works for the test!
|
||||
Vector vecVelocity;
|
||||
vecVelocity.x = ( GetAbsAngles().x ) * random->RandomFloat( 1.0f, 10.0f );
|
||||
vecVelocity.y = ( GetAbsAngles().y ) * random->RandomFloat( 1.0f, 10.0f );
|
||||
vecVelocity.z = ( GetAbsAngles().z ) * random->RandomFloat( 1.0f, 10.0f );
|
||||
|
||||
pShootingStar->Init( GetAbsOrigin(), vecVelocity, random->RandomFloat( 10.0f, 100.0f ), random->RandomFloat( 10.0f, 30.0f ) );
|
||||
}
|
||||
}
|
||||
|
||||
//=============================================================================
|
||||
//
|
||||
// Shooting Star Functionality
|
||||
//
|
||||
|
||||
//Precahce the effects
|
||||
CLIENTEFFECT_REGISTER_BEGIN( PrecacheEffectShootingStars )
|
||||
CLIENTEFFECT_MATERIAL( "effects/redflare" )
|
||||
CLIENTEFFECT_REGISTER_END()
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Constructor
|
||||
//-----------------------------------------------------------------------------
|
||||
C_ShootingStar::C_ShootingStar( void ) : CSimpleEmitter( "ShootingStar" )
|
||||
{
|
||||
m_flScale = 1.0f;
|
||||
SetDynamicallyAllocated( false );
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Destructor
|
||||
//-----------------------------------------------------------------------------
|
||||
C_ShootingStar::~C_ShootingStar( void )
|
||||
{
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Destructor
|
||||
//-----------------------------------------------------------------------------
|
||||
void C_ShootingStar::Init( const Vector vecOrigin, const Vector vecVelocity, int nSize,
|
||||
float flLifeTime )
|
||||
{
|
||||
// Set the sort origin.
|
||||
SetSortOrigin( vecOrigin );
|
||||
|
||||
// Create the initial particle and set the data.
|
||||
SimpleParticle *pParticle = ( SimpleParticle* )AddParticle( sizeof( SimpleParticle ), GetPMaterial( "effects/redflare" ), vecOrigin );
|
||||
if ( pParticle )
|
||||
{
|
||||
pParticle->m_vecVelocity = vecVelocity;
|
||||
|
||||
pParticle->m_uchColor[0] = pParticle->m_uchColor[1] = pParticle->m_uchColor[2] = 255;
|
||||
|
||||
pParticle->m_flRoll = random->RandomInt( 0, 360 );
|
||||
pParticle->m_flRollDelta = random->RandomFloat( 1.0f, 4.0f );
|
||||
|
||||
pParticle->m_flLifetime = 0.0f;
|
||||
pParticle->m_flDieTime = flLifeTime;
|
||||
|
||||
pParticle->m_uchStartAlpha = 255;
|
||||
pParticle->m_uchEndAlpha = 0;
|
||||
pParticle->m_uchStartSize = nSize;
|
||||
pParticle->m_uchEndSize = ( nSize / 3 );
|
||||
}
|
||||
|
||||
int iParticle = m_aParticles.AddToTail();
|
||||
m_aParticles[iParticle] = pParticle;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Destructor
|
||||
//-----------------------------------------------------------------------------
|
||||
void C_ShootingStar::Destroy( void )
|
||||
{
|
||||
// Destroy shooting star particles.
|
||||
int nParticleCount = m_aParticles.Count();
|
||||
for ( int iParticle = ( nParticleCount - 1 ); iParticle >= 0; iParticle-- )
|
||||
{
|
||||
SimpleParticle *pParticle = m_aParticles[iParticle];
|
||||
m_aParticles.Remove( iParticle );
|
||||
CSimpleEmitter::NotifyDestroyParticle( pParticle );
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void C_ShootingStar::SetSortOrigin( const Vector &vSortOrigin )
|
||||
{
|
||||
CSimpleEmitter::SetSortOrigin( vSortOrigin );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
// Input : timeDelta -
|
||||
//-----------------------------------------------------------------------------
|
||||
void C_ShootingStar::Update( float timeDelta )
|
||||
{
|
||||
// Parent update.
|
||||
CSimpleEmitter::Update( timeDelta );
|
||||
|
||||
// Don't update if the console is down.
|
||||
if ( timeDelta <= 0.0f )
|
||||
return;
|
||||
|
||||
// Are we still alive? Get the tail of the shooting star (last valid index)
|
||||
// and test.
|
||||
int nParticleCount = m_aParticles.Count();
|
||||
if ( nParticleCount <= 0 )
|
||||
return;
|
||||
|
||||
SimpleParticle *pParticle = m_aParticles[nParticleCount-1];
|
||||
if ( pParticle->m_flLifetime >= pParticle->m_flDieTime )
|
||||
{
|
||||
Destroy();
|
||||
return;
|
||||
}
|
||||
|
||||
// Update the particles lifetime.
|
||||
pParticle->m_flLifetime += timeDelta;
|
||||
|
||||
// Update the particle position.
|
||||
pParticle->m_Pos += ( pParticle->m_vecVelocity * timeDelta );
|
||||
|
||||
SetLocalOrigin( pParticle->m_Pos );
|
||||
SetSortOrigin( GetAbsOrigin() );
|
||||
}
|
||||
@@ -0,0 +1,72 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose: Client's Meteor
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================//
|
||||
|
||||
#ifndef C_EFFECT_SHOOTINGSTAR_H
|
||||
#define C_EFFECT_SHOOTINGSTAR_H
|
||||
#pragma once
|
||||
|
||||
#include "c_baseanimating.h"
|
||||
#include "particles_simple.h"
|
||||
|
||||
class C_ShootingStar;
|
||||
|
||||
//=============================================================================
|
||||
//
|
||||
// Client-side shooting star spawner.
|
||||
//
|
||||
class C_ShootingStarSpawner : public C_BaseEntity
|
||||
{
|
||||
DECLARE_CLASS( C_ShootingStarSpawner, C_BaseEntity );
|
||||
|
||||
public:
|
||||
|
||||
DECLARE_CLIENTCLASS();
|
||||
|
||||
C_ShootingStarSpawner();
|
||||
|
||||
void ClientThink( void );
|
||||
void SpawnShootingStars( void );
|
||||
|
||||
public:
|
||||
|
||||
float m_flSpawnInterval; // How often do I spawn meteors?
|
||||
};
|
||||
|
||||
|
||||
//=============================================================================
|
||||
//
|
||||
// Shooting Star Effect
|
||||
//
|
||||
class C_ShootingStar : public C_BaseAnimating, CSimpleEmitter
|
||||
{
|
||||
DECLARE_CLASS( C_ShootingStar, C_BaseAnimating );
|
||||
|
||||
public:
|
||||
|
||||
C_ShootingStar( );
|
||||
~C_ShootingStar( void );
|
||||
|
||||
void Init( const Vector vecOrigin, const Vector vecVelocity, int nSize, float flLifeTime );
|
||||
void Destroy( void );
|
||||
|
||||
void Update( float timeDelta );
|
||||
|
||||
public:
|
||||
|
||||
float m_flScale;
|
||||
|
||||
private:
|
||||
|
||||
void SetSortOrigin( const Vector &vSortOrigin );
|
||||
|
||||
private:
|
||||
C_ShootingStar( const C_ShootingStar & );
|
||||
|
||||
CUtlVector<SimpleParticle*> m_aParticles;
|
||||
};
|
||||
|
||||
#endif // C_EFFECT_SHOOTINGSTAR_H
|
||||
@@ -0,0 +1,85 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================//
|
||||
#include "cbase.h"
|
||||
#include "c_entity_burn_effect.h"
|
||||
|
||||
|
||||
#define NUM_BURN_PARTICLES_PER_SEC 50
|
||||
|
||||
|
||||
|
||||
IMPLEMENT_CLIENTCLASS_DT( C_EntityBurnEffect, DT_EntityBurnEffect, CEntityBurnEffect )
|
||||
RecvPropInt( RECVINFO( m_hBurningEntity ) )
|
||||
END_RECV_TABLE()
|
||||
|
||||
|
||||
|
||||
C_EntityBurnEffect::C_EntityBurnEffect()
|
||||
{
|
||||
m_pEmitter = CSimpleEmitter::Create( "Entity burn effect" );
|
||||
if ( m_pEmitter.IsValid() )
|
||||
{
|
||||
m_hFireMaterial = m_pEmitter->GetPMaterial( "particle/fire" );
|
||||
}
|
||||
else
|
||||
{
|
||||
m_hFireMaterial = INVALID_MATERIAL_HANDLE;
|
||||
}
|
||||
m_Timer.Init( NUM_BURN_PARTICLES_PER_SEC );
|
||||
}
|
||||
|
||||
|
||||
void C_EntityBurnEffect::OnDataChanged( DataUpdateType_t updateType )
|
||||
{
|
||||
if ( updateType == DATA_UPDATE_CREATED )
|
||||
{
|
||||
SetNextClientThink( CLIENT_THINK_ALWAYS );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void C_EntityBurnEffect::ClientThink()
|
||||
{
|
||||
if ( !m_pEmitter.IsValid() || IsDormant() )
|
||||
return;
|
||||
|
||||
// Add some burning particles to our target entity.
|
||||
C_BaseEntity *pEnt = ClientEntityList().GetBaseEntity( m_hBurningEntity );
|
||||
if ( !pEnt )
|
||||
return;
|
||||
|
||||
float dt = gpGlobals->frametime;
|
||||
while ( m_Timer.NextEvent( dt ) )
|
||||
{
|
||||
Vector vDims = (pEnt->WorldAlignMaxs() - pEnt->WorldAlignMins()) * 0.5f;
|
||||
Vector vCenter = pEnt->GetAbsOrigin() + pEnt->WorldAlignMins() + vDims;
|
||||
Vector vPos = vCenter + vDims * RandomVector( -0.7, 0.7 );
|
||||
|
||||
float flLifetime = 1;
|
||||
float flRadius = 3;
|
||||
unsigned char uchColor[4] = { 255, 100, 0, 100 };
|
||||
|
||||
SimpleParticle *pParticle = m_pEmitter->AddSimpleParticle( m_hFireMaterial, vPos, flLifetime, flRadius );
|
||||
if ( pParticle )
|
||||
{
|
||||
pParticle->m_uchColor[0] = uchColor[0];
|
||||
pParticle->m_uchColor[1] = uchColor[1];
|
||||
pParticle->m_uchColor[2] = uchColor[2];
|
||||
|
||||
pParticle->m_uchEndAlpha = 0;
|
||||
pParticle->m_uchStartAlpha = uchColor[3];
|
||||
|
||||
pParticle->m_vecVelocity.x = RandomFloat( -2, 2 );
|
||||
pParticle->m_vecVelocity.y = RandomFloat( -2, 2 );
|
||||
pParticle->m_vecVelocity.z = RandomFloat( 3, 29 );
|
||||
|
||||
// Pick up some velocity from the burning guy running around.
|
||||
pParticle->m_vecVelocity += pEnt->GetAbsVelocity() * 0.6;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,44 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================//
|
||||
|
||||
#ifndef C_ENTITY_BURN_EFFECT_H
|
||||
#define C_ENTITY_BURN_EFFECT_H
|
||||
#ifdef _WIN32
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include "c_baseentity.h"
|
||||
#include "particle_util.h"
|
||||
#include "particles_simple.h"
|
||||
|
||||
class C_EntityBurnEffect : public C_BaseEntity
|
||||
{
|
||||
public:
|
||||
|
||||
DECLARE_CLASS( C_EntityBurnEffect, C_BaseEntity );
|
||||
DECLARE_CLIENTCLASS();
|
||||
|
||||
C_EntityBurnEffect();
|
||||
|
||||
|
||||
// Overrides.
|
||||
public:
|
||||
|
||||
virtual void OnDataChanged( DataUpdateType_t updateType );
|
||||
virtual void ClientThink();
|
||||
|
||||
|
||||
private:
|
||||
int m_hBurningEntity; // todo: this should be an ehandle but base networkables aren't setup for ehandles yet.
|
||||
|
||||
TimedEvent m_Timer;
|
||||
CSmartPtr<CSimpleEmitter> m_pEmitter;
|
||||
PMaterialHandle m_hFireMaterial;
|
||||
};
|
||||
|
||||
|
||||
#endif // C_ENTITY_BURN_EFFECT_H
|
||||
@@ -0,0 +1,651 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================//
|
||||
#include "cbase.h"
|
||||
#include "C_Env_Meteor.h"
|
||||
#include "fx_explosion.h"
|
||||
#include "tempentity.h"
|
||||
#include "c_tracer.h"
|
||||
|
||||
//=============================================================================
|
||||
//
|
||||
// Meteor Factory Functions
|
||||
//
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//-----------------------------------------------------------------------------
|
||||
void C_MeteorFactory::CreateMeteor( int nID, int iType,
|
||||
const Vector &vecPosition, const Vector &vecDirection,
|
||||
float flSpeed, float flStartTime, float flDamageRadius,
|
||||
const Vector &vecTriggerMins, const Vector &vecTriggerMaxs )
|
||||
{
|
||||
C_EnvMeteor::Create( nID, iType, vecPosition, vecDirection, flSpeed, flStartTime, flDamageRadius,
|
||||
vecTriggerMins, vecTriggerMaxs );
|
||||
}
|
||||
|
||||
|
||||
//=============================================================================
|
||||
//
|
||||
// Meteor Spawner Functions
|
||||
//
|
||||
|
||||
void RecvProxy_MeteorTargetPositions( const CRecvProxyData *pData, void *pStruct, void *pOut )
|
||||
{
|
||||
CEnvMeteorSpawnerShared *pSpawner = ( CEnvMeteorSpawnerShared* )pStruct;
|
||||
pSpawner->m_aTargets[pData->m_iElement].m_vecPosition.x = pData->m_Value.m_Vector[0];
|
||||
pSpawner->m_aTargets[pData->m_iElement].m_vecPosition.y = pData->m_Value.m_Vector[1];
|
||||
pSpawner->m_aTargets[pData->m_iElement].m_vecPosition.z = pData->m_Value.m_Vector[2];
|
||||
}
|
||||
|
||||
void RecvProxy_MeteorTargetRadii( const CRecvProxyData *pData, void *pStruct, void *pOut )
|
||||
{
|
||||
CEnvMeteorSpawnerShared *pSpawner = ( CEnvMeteorSpawnerShared* )pStruct;
|
||||
pSpawner->m_aTargets[pData->m_iElement].m_flRadius = pData->m_Value.m_Float;
|
||||
}
|
||||
|
||||
void RecvProxyArrayLength_MeteorTargets( void *pStruct, int objectID, int currentArrayLength )
|
||||
{
|
||||
CEnvMeteorSpawnerShared *pSpawner = ( CEnvMeteorSpawnerShared* )pStruct;
|
||||
if ( pSpawner->m_aTargets.Count() < currentArrayLength )
|
||||
{
|
||||
pSpawner->m_aTargets.SetSize( currentArrayLength );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
BEGIN_RECV_TABLE_NOBASE( CEnvMeteorSpawnerShared, DT_EnvMeteorSpawnerShared )
|
||||
// Setup (read from) Worldcraft.
|
||||
RecvPropInt ( RECVINFO( m_iMeteorType ) ),
|
||||
RecvPropInt ( RECVINFO( m_bSkybox ) ),
|
||||
RecvPropFloat ( RECVINFO( m_flMinSpawnTime ) ),
|
||||
RecvPropFloat ( RECVINFO( m_flMaxSpawnTime ) ),
|
||||
RecvPropInt ( RECVINFO( m_nMinSpawnCount ) ),
|
||||
RecvPropInt ( RECVINFO( m_nMaxSpawnCount ) ),
|
||||
RecvPropFloat ( RECVINFO( m_flMinSpeed ) ),
|
||||
RecvPropFloat ( RECVINFO( m_flMaxSpeed ) ),
|
||||
|
||||
// Setup through Init.
|
||||
RecvPropFloat ( RECVINFO( m_flStartTime ) ),
|
||||
RecvPropInt ( RECVINFO( m_nRandomSeed ) ),
|
||||
RecvPropVector ( RECVINFO( m_vecMinBounds ) ),
|
||||
RecvPropVector ( RECVINFO( m_vecMaxBounds ) ),
|
||||
RecvPropVector ( RECVINFO( m_vecTriggerMins ) ),
|
||||
RecvPropVector ( RECVINFO( m_vecTriggerMaxs ) ),
|
||||
|
||||
// Target List
|
||||
RecvPropArray2( RecvProxyArrayLength_MeteorTargets,
|
||||
RecvPropVector( "meteortargetposition_array_element", 0, 0, 0, RecvProxy_MeteorTargetPositions ),
|
||||
16, 0, "meteortargetposition_array" ),
|
||||
|
||||
RecvPropArray2( RecvProxyArrayLength_MeteorTargets,
|
||||
RecvPropFloat( "meteortargetradius_array_element", 0, 0, 0, RecvProxy_MeteorTargetRadii ),
|
||||
16, 0, "meteortargetradius_array" )
|
||||
END_RECV_TABLE()
|
||||
|
||||
// This table encodes the CBaseEntity data.
|
||||
IMPLEMENT_CLIENTCLASS_DT( C_EnvMeteorSpawner, DT_EnvMeteorSpawner, CEnvMeteorSpawner )
|
||||
RecvPropDataTable ( RECVINFO_DT( m_SpawnerShared ), 0, &REFERENCE_RECV_TABLE( DT_EnvMeteorSpawnerShared ) ),
|
||||
RecvPropInt ( RECVINFO( m_fDisabled ) ),
|
||||
END_RECV_TABLE()
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//-----------------------------------------------------------------------------
|
||||
C_EnvMeteorSpawner::C_EnvMeteorSpawner()
|
||||
{
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//-----------------------------------------------------------------------------
|
||||
void C_EnvMeteorSpawner::OnDataChanged( DataUpdateType_t updateType )
|
||||
{
|
||||
// Initialize the client side spawner.
|
||||
m_SpawnerShared.Init( &m_Factory, m_SpawnerShared.m_nRandomSeed, m_SpawnerShared.m_flStartTime,
|
||||
m_SpawnerShared.m_vecMinBounds, m_SpawnerShared.m_vecMaxBounds,
|
||||
m_SpawnerShared.m_vecTriggerMins, m_SpawnerShared.m_vecTriggerMaxs );
|
||||
|
||||
// Set the next think to be the next spawn interval.
|
||||
if ( !m_fDisabled )
|
||||
{
|
||||
SetNextClientThink( m_SpawnerShared.m_flNextSpawnTime );
|
||||
}
|
||||
}
|
||||
|
||||
#if 0
|
||||
// Will probably be used later!!
|
||||
//-----------------------------------------------------------------------------
|
||||
//-----------------------------------------------------------------------------
|
||||
void C_EnvMeteorSpawner::ReceiveMessage( int classID, bf_read &msg )
|
||||
{
|
||||
if ( classID != GetClientClass()->m_ClassID )
|
||||
{
|
||||
// message is for subclass
|
||||
BaseClass::ReceiveMessage( classID, msg );
|
||||
return;
|
||||
}
|
||||
|
||||
m_SpawnerShared.m_flStartTime = msg.ReadLong();
|
||||
m_SpawnerShared.m_flNextSpawnTime = msg.ReadLong();
|
||||
SetNextClientThink( m_SpawnerShared.m_flNextSpawnTime );
|
||||
}
|
||||
#endif
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//-----------------------------------------------------------------------------
|
||||
void C_EnvMeteorSpawner::ClientThink( void )
|
||||
{
|
||||
SetNextClientThink( m_SpawnerShared.MeteorThink( gpGlobals->curtime ) );
|
||||
}
|
||||
|
||||
//=============================================================================
|
||||
//
|
||||
// Meteor Tail Functions
|
||||
//
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//-----------------------------------------------------------------------------
|
||||
C_EnvMeteorHead::C_EnvMeteorHead()
|
||||
{
|
||||
m_vecPos.Init();
|
||||
m_vecPrevPos.Init();
|
||||
|
||||
m_flParticleScale = 1.0f;
|
||||
|
||||
m_pSmokeEmitter = NULL;
|
||||
m_flSmokeSpawnInterval = 0.0f;
|
||||
m_hSmokeMaterial = INVALID_MATERIAL_HANDLE;
|
||||
m_flSmokeLifetime = 2.5f;
|
||||
m_bEmitSmoke = true;
|
||||
|
||||
m_hFlareMaterial = INVALID_MATERIAL_HANDLE;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//-----------------------------------------------------------------------------
|
||||
C_EnvMeteorHead::~C_EnvMeteorHead()
|
||||
{
|
||||
Destroy();
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//-----------------------------------------------------------------------------
|
||||
void C_EnvMeteorHead::Start( const Vector &vecOrigin, const Vector &vecDirection )
|
||||
{
|
||||
// Emitters.
|
||||
m_pSmokeEmitter = CSimpleEmitter::Create( "MeteorTrail" );
|
||||
// m_pFireEmitter = CSimpleEmitter::Create( "MeteorFire" );
|
||||
if ( !m_pSmokeEmitter /*|| !m_pFireEmitter*/ )
|
||||
return;
|
||||
|
||||
// Smoke
|
||||
m_pSmokeEmitter->SetSortOrigin( vecOrigin );
|
||||
m_hSmokeMaterial = m_pSmokeEmitter->GetPMaterial( "particle/SmokeStack" );
|
||||
Assert( m_hSmokeMaterial != INVALID_MATERIAL_HANDLE );
|
||||
|
||||
// Fire
|
||||
// m_pFireEmitter->SetSortOrigin( vecOrigin );
|
||||
// m_hFireMaterial = m_pFireEmitter->GetPMaterial( "particle/particle_fire" );
|
||||
// Assert( m_hFireMaterial != INVALID_MATERIAL_HANDLE );
|
||||
|
||||
// Flare
|
||||
// m_hFlareMaterial = m_ParticleEffect.FindOrAddMaterial( "effects/redflare" );
|
||||
|
||||
VectorCopy( vecDirection, m_vecDirection );
|
||||
VectorCopy( vecOrigin, m_vecPos );
|
||||
|
||||
m_bInitThink = true;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//-----------------------------------------------------------------------------
|
||||
void C_EnvMeteorHead::Destroy( void )
|
||||
{
|
||||
m_pSmokeEmitter = NULL;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//-----------------------------------------------------------------------------
|
||||
void C_EnvMeteorHead::MeteorHeadThink( const Vector &vecOrigin, float flTime )
|
||||
{
|
||||
if ( m_bInitThink )
|
||||
{
|
||||
VectorCopy( vecOrigin, m_vecPrevPos );
|
||||
m_bInitThink = false;
|
||||
}
|
||||
|
||||
// Update the position of the emitters.
|
||||
VectorCopy( vecOrigin, m_vecPos );
|
||||
|
||||
// Update Smoke
|
||||
if ( m_pSmokeEmitter.IsValid() && m_bEmitSmoke )
|
||||
{
|
||||
m_pSmokeEmitter->SetSortOrigin( m_vecPos );
|
||||
|
||||
// Get distance covered
|
||||
Vector vecDelta;
|
||||
VectorSubtract( m_vecPos, m_vecPrevPos, vecDelta );
|
||||
float flLength = vecDelta.Length();
|
||||
|
||||
int nParticleCount = flLength / 35.0f;
|
||||
if ( nParticleCount < 1 )
|
||||
{
|
||||
nParticleCount = 1;
|
||||
}
|
||||
|
||||
flLength /= nParticleCount;
|
||||
|
||||
Vector vecPos;
|
||||
for( int iParticle = 0; iParticle < nParticleCount; ++iParticle )
|
||||
{
|
||||
vecPos = m_vecPrevPos + ( m_vecDirection * ( flLength * iParticle ) );
|
||||
|
||||
// Add some noise to the position.
|
||||
Vector vecPosOffset;
|
||||
vecPosOffset.Random( -m_flSmokeSpawnRadius, m_flSmokeSpawnRadius );
|
||||
VectorAdd( vecPosOffset, vecPos, vecPosOffset );
|
||||
|
||||
|
||||
SimpleParticle *pParticle = ( SimpleParticle* )m_pSmokeEmitter->AddParticle( sizeof( SimpleParticle ),
|
||||
m_hSmokeMaterial,
|
||||
vecPosOffset );
|
||||
if ( pParticle )
|
||||
{
|
||||
pParticle->m_flLifetime = 0.0f;
|
||||
pParticle->m_flDieTime = m_flSmokeLifetime;
|
||||
|
||||
// Add just a little movement.
|
||||
pParticle->m_vecVelocity.Random( -5.0f, 5.0f );
|
||||
|
||||
pParticle->m_uchColor[0] = 255.0f;
|
||||
pParticle->m_uchColor[1] = 255.0f;
|
||||
pParticle->m_uchColor[2] = 255.0f;
|
||||
|
||||
|
||||
pParticle->m_uchStartSize = 70 * m_flParticleScale;
|
||||
pParticle->m_uchEndSize = 25 * m_flParticleScale;
|
||||
|
||||
float flAlpha = random->RandomFloat( 0.5f, 1.0f );
|
||||
pParticle->m_uchStartAlpha = flAlpha * 255;
|
||||
pParticle->m_uchEndAlpha = 0;
|
||||
|
||||
pParticle->m_flRoll = random->RandomInt( 0, 360 );
|
||||
pParticle->m_flRollDelta = random->RandomFloat( -1.0f, 1.0f );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Update Fire
|
||||
// if ( m_pFireEmitter && m_bEmitFire )
|
||||
// {
|
||||
// }
|
||||
|
||||
// Flare
|
||||
|
||||
// Save off position.
|
||||
VectorCopy( m_vecPos, m_vecPrevPos );
|
||||
}
|
||||
|
||||
//=============================================================================
|
||||
//
|
||||
// Meteor Tail Functions
|
||||
//
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//-----------------------------------------------------------------------------
|
||||
C_EnvMeteorTail::C_EnvMeteorTail()
|
||||
{
|
||||
m_TailMaterialHandle = INVALID_MATERIAL_HANDLE;
|
||||
|
||||
m_pParticleMgr = NULL;
|
||||
m_pParticle = NULL;
|
||||
|
||||
m_flFadeTime = 0.5f;
|
||||
m_flWidth = 3.0f;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//-----------------------------------------------------------------------------
|
||||
C_EnvMeteorTail::~C_EnvMeteorTail()
|
||||
{
|
||||
Destroy();
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//-----------------------------------------------------------------------------
|
||||
void C_EnvMeteorTail::Start( const Vector &vecOrigin, const Vector &vecDirection,
|
||||
float flSpeed )
|
||||
{
|
||||
// Set the particle manager.
|
||||
m_pParticleMgr = ParticleMgr();
|
||||
m_pParticleMgr->AddEffect( &m_ParticleEffect, this );
|
||||
m_TailMaterialHandle = m_ParticleEffect.FindOrAddMaterial( "particle/guidedplasmaprojectile" );
|
||||
m_pParticle = m_ParticleEffect.AddParticle( sizeof( StandardParticle_t ), m_TailMaterialHandle );
|
||||
if ( m_pParticle )
|
||||
{
|
||||
m_pParticle->m_Pos = vecOrigin;
|
||||
}
|
||||
|
||||
VectorCopy( vecDirection, m_vecDirection );
|
||||
m_flSpeed = flSpeed;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//-----------------------------------------------------------------------------
|
||||
void C_EnvMeteorTail::Destroy( void )
|
||||
{
|
||||
if ( m_pParticleMgr )
|
||||
{
|
||||
m_pParticleMgr->RemoveEffect( &m_ParticleEffect );
|
||||
m_pParticleMgr = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//-----------------------------------------------------------------------------
|
||||
void C_EnvMeteorTail::DrawFragment( ParticleDraw* pDraw,
|
||||
const Vector &vecStart, const Vector &vecDelta,
|
||||
const Vector4D &vecStartColor, const Vector4D &vecEndColor,
|
||||
float flStartV, float flEndV )
|
||||
{
|
||||
if( !pDraw->GetMeshBuilder() )
|
||||
return;
|
||||
|
||||
// Clip the fragment.
|
||||
Vector vecVerts[4];
|
||||
if ( !Tracer_ComputeVerts( vecStart, vecDelta, m_flWidth, vecVerts ) )
|
||||
return;
|
||||
|
||||
// NOTE: Gotta get the winding right so it's not backface culled
|
||||
// (we need to turn of backface culling for these bad boys)
|
||||
CMeshBuilder* pMeshBuilder = pDraw->GetMeshBuilder();
|
||||
|
||||
pMeshBuilder->Position3f( vecVerts[0].x, vecVerts[0].y, vecVerts[0].z );
|
||||
pMeshBuilder->TexCoord2f( 0, 0.0f, flStartV );
|
||||
pMeshBuilder->Color4fv( vecStartColor.Base() );
|
||||
pMeshBuilder->AdvanceVertex();
|
||||
|
||||
pMeshBuilder->Position3f( vecVerts[1].x, vecVerts[1].y, vecVerts[1].z );
|
||||
pMeshBuilder->TexCoord2f( 0, 1.0f, flStartV );
|
||||
pMeshBuilder->Color4fv( vecStartColor.Base() );
|
||||
pMeshBuilder->AdvanceVertex();
|
||||
|
||||
pMeshBuilder->Position3f( vecVerts[3].x, vecVerts[3].y, vecVerts[3].z );
|
||||
pMeshBuilder->TexCoord2f( 0, 1.0f, flEndV );
|
||||
pMeshBuilder->Color4fv( vecEndColor.Base() );
|
||||
pMeshBuilder->AdvanceVertex();
|
||||
|
||||
pMeshBuilder->Position3f( vecVerts[2].x, vecVerts[2].y, vecVerts[2].z );
|
||||
pMeshBuilder->TexCoord2f( 0, 0.0f, flEndV );
|
||||
pMeshBuilder->Color4fv( vecEndColor.Base() );
|
||||
pMeshBuilder->AdvanceVertex();
|
||||
}
|
||||
|
||||
void C_EnvMeteorTail::SimulateParticles( CParticleSimulateIterator *pIterator )
|
||||
{
|
||||
Particle *pParticle = (Particle*)pIterator->GetFirst();
|
||||
while ( pParticle )
|
||||
{
|
||||
// Update the particle position.
|
||||
pParticle->m_Pos = GetLocalOrigin();
|
||||
|
||||
pParticle = (Particle*)pIterator->GetNext();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void C_EnvMeteorTail::RenderParticles( CParticleRenderIterator *pIterator )
|
||||
{
|
||||
const Particle *pParticle = (const Particle *)pIterator->GetFirst();
|
||||
while ( pParticle )
|
||||
{
|
||||
// Now draw the tail fragments...
|
||||
Vector4D vecStartColor( 1.0f, 1.0f, 1.0f, 1.0f );
|
||||
Vector4D vecEndColor( 1.0f, 1.0f, 1.0f, 0.0f );
|
||||
Vector vecDelta, vecStartPos, vecEndPos;
|
||||
|
||||
// Calculate the tail.
|
||||
Vector vecTailEnd;
|
||||
vecTailEnd = GetLocalOrigin() + ( m_vecDirection * -m_flSpeed );
|
||||
|
||||
// Transform particles into camera space.
|
||||
TransformParticle( m_pParticleMgr->GetModelView(), GetLocalOrigin(), vecStartPos );
|
||||
TransformParticle( m_pParticleMgr->GetModelView(), vecTailEnd, vecEndPos );
|
||||
float sortKey = vecStartPos.z;
|
||||
|
||||
// Draw the tail fragment.
|
||||
VectorSubtract( vecStartPos, vecEndPos, vecDelta );
|
||||
DrawFragment( pIterator->GetParticleDraw(), vecEndPos, vecDelta, vecEndColor, vecStartColor,
|
||||
1.0f - vecEndColor[3], 1.0f - vecStartColor[3] );
|
||||
|
||||
pParticle = (const Particle *)pIterator->GetNext( sortKey );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//=============================================================================
|
||||
//
|
||||
// Meteor Functions
|
||||
//
|
||||
|
||||
static g_MeteorCounter = 0;
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//-----------------------------------------------------------------------------
|
||||
C_EnvMeteor::C_EnvMeteor()
|
||||
{
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//-----------------------------------------------------------------------------
|
||||
C_EnvMeteor::~C_EnvMeteor()
|
||||
{
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//-----------------------------------------------------------------------------
|
||||
void C_EnvMeteor::ClientThink( void )
|
||||
{
|
||||
// Get the current time.
|
||||
float flTime = gpGlobals->curtime;
|
||||
|
||||
// Update the meteor.
|
||||
if ( m_Meteor.IsInSkybox( flTime ) )
|
||||
{
|
||||
if ( m_Meteor.m_nLocation == METEOR_LOCATION_WORLD )
|
||||
{
|
||||
WorldToSkyboxThink( flTime );
|
||||
}
|
||||
else
|
||||
{
|
||||
SkyboxThink( flTime );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( m_Meteor.m_nLocation == METEOR_LOCATION_SKYBOX )
|
||||
{
|
||||
SkyboxToWorldThink( flTime );
|
||||
}
|
||||
else
|
||||
{
|
||||
WorldThink( flTime );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//-----------------------------------------------------------------------------
|
||||
void C_EnvMeteor::SkyboxThink( float flTime )
|
||||
{
|
||||
float flDeltaTime = flTime - m_Meteor.m_flStartTime;
|
||||
if ( flDeltaTime > METEOR_MAX_LIFETIME )
|
||||
{
|
||||
Destroy( this );
|
||||
return;
|
||||
}
|
||||
|
||||
// Check to see if the object is passive or not - act accordingly!
|
||||
if ( !m_Meteor.IsPassive( flTime ) )
|
||||
{
|
||||
// Update meteor position.
|
||||
Vector origin;
|
||||
m_Meteor.GetPositionAtTime( flTime, origin );
|
||||
SetLocalOrigin( origin );
|
||||
|
||||
// Update the position of the tail effect.
|
||||
m_TailEffect.SetLocalOrigin( GetLocalOrigin() );
|
||||
m_HeadEffect.MeteorHeadThink( GetLocalOrigin(), flTime );
|
||||
}
|
||||
|
||||
// Add the entity to the active list - update!
|
||||
AddEntity();
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//-----------------------------------------------------------------------------
|
||||
void C_EnvMeteor::WorldToSkyboxThink( float flTime )
|
||||
{
|
||||
// Move the meteor from the world into the skybox.
|
||||
m_Meteor.ConvertFromWorldToSkybox();
|
||||
|
||||
// Destroy the head effect. Recreate it.
|
||||
m_HeadEffect.Destroy();
|
||||
m_HeadEffect.Start( m_Meteor.m_vecStartPosition, m_vecTravelDir );
|
||||
m_HeadEffect.SetSmokeEmission( true );
|
||||
m_HeadEffect.SetParticleScale( 1.0f / 16.0f );
|
||||
m_HeadEffect.m_bInitThink = true;
|
||||
|
||||
// Update to world model.
|
||||
SetModel( "models/props/common/meteorites/meteor05.mdl" );
|
||||
|
||||
// Update the meteor position (move into the skybox!)
|
||||
SetLocalOrigin( m_Meteor.m_vecStartPosition );
|
||||
|
||||
// Update (think).
|
||||
SkyboxThink( flTime );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//-----------------------------------------------------------------------------
|
||||
void C_EnvMeteor::SkyboxToWorldThink( float flTime )
|
||||
{
|
||||
// Move the meteor from the skybox into the world.
|
||||
m_Meteor.ConvertFromSkyboxToWorld();
|
||||
|
||||
// Destroy the head effect. Recreate it.
|
||||
m_HeadEffect.Destroy();
|
||||
m_HeadEffect.Start( m_Meteor.m_vecStartPosition, m_vecTravelDir );
|
||||
m_HeadEffect.SetSmokeEmission( true );
|
||||
m_HeadEffect.SetParticleScale( 1.0f );
|
||||
m_HeadEffect.m_bInitThink = true;
|
||||
|
||||
// Update to world model.
|
||||
SetModel( "models/props/common/meteorites/meteor04.mdl" );
|
||||
|
||||
SetLocalOrigin( m_Meteor.m_vecStartPosition );
|
||||
|
||||
// Update (think).
|
||||
WorldThink( flTime );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//-----------------------------------------------------------------------------
|
||||
void C_EnvMeteor::WorldThink( float flTime )
|
||||
{
|
||||
// Update meteor position.
|
||||
Vector vecEndPosition;
|
||||
m_Meteor.GetPositionAtTime( flTime, vecEndPosition );
|
||||
|
||||
// m_Meteor must return the end position in world space for the trace to work.
|
||||
Assert( GetMoveParent() == NULL );
|
||||
|
||||
// Msg( "Client: Time = %lf, Position: %4.2f %4.2f %4.2f\n", flTime, vecEndPosition.x, vecEndPosition.y, vecEndPosition.z );
|
||||
|
||||
// Check to see if we struck the world. If so, cause an explosion.
|
||||
trace_t trace;
|
||||
|
||||
Vector vecMin, vecMax;
|
||||
GetRenderBounds( vecMin, vecMax );
|
||||
|
||||
// NOTE: This code works only if we aren't in hierarchy!!!
|
||||
Assert( !GetMoveParent() );
|
||||
|
||||
CTraceFilterWorldOnly traceFilter;
|
||||
UTIL_TraceHull( GetAbsOrigin(), vecEndPosition, vecMin, vecMax,
|
||||
MASK_SOLID_BRUSHONLY, &traceFilter, &trace );
|
||||
|
||||
// Collision.
|
||||
if ( ( trace.fraction < 1.0f ) && !( trace.surface.flags & SURF_SKY ) )
|
||||
{
|
||||
// Move up to the end.
|
||||
Vector vecEnd = GetAbsOrigin() + ( ( vecEndPosition - GetAbsOrigin() ) * trace.fraction );
|
||||
|
||||
// Create an explosion effect!
|
||||
BaseExplosionEffect().Create( vecEnd, 10, 32, TE_EXPLFLAG_NONE );
|
||||
|
||||
// Debugging Info!!!!
|
||||
// debugoverlay->AddBoxOverlay( vecEnd, Vector( -10, -10, -10 ), Vector( 10, 10, 10 ), QAngle( 0.0f, 0.0f, 0.0f ), 255, 0, 0, 0, 100 );
|
||||
|
||||
Destroy( this );
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Move to the end.
|
||||
SetLocalOrigin( vecEndPosition );
|
||||
}
|
||||
|
||||
m_TailEffect.SetLocalOrigin( GetLocalOrigin() );
|
||||
m_HeadEffect.MeteorHeadThink( GetLocalOrigin(), flTime );
|
||||
|
||||
// Add the entity to the active list - update!
|
||||
AddEntity();
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//-----------------------------------------------------------------------------
|
||||
C_EnvMeteor *C_EnvMeteor::Create( int nID, int iMeteorType, const Vector &vecOrigin,
|
||||
const Vector &vecDirection, float flSpeed, float flStartTime,
|
||||
float flDamageRadius,
|
||||
const Vector &vecTriggerMins, const Vector &vecTriggerMaxs )
|
||||
{
|
||||
C_EnvMeteor *pMeteor = new C_EnvMeteor;
|
||||
if ( pMeteor )
|
||||
{
|
||||
pMeteor->m_Meteor.Init( nID, flStartTime, METEOR_PASSIVE_TIME, vecOrigin, vecDirection, flSpeed, flDamageRadius,
|
||||
vecTriggerMins, vecTriggerMaxs );
|
||||
|
||||
// Initialize the meteor.
|
||||
pMeteor->InitializeAsClientEntity( "models/props/common/meteorites/meteor05.mdl", RENDER_GROUP_OPAQUE_ENTITY );
|
||||
|
||||
// Handle forward simulation.
|
||||
if ( ( pMeteor->m_Meteor.m_flStartTime + METEOR_MAX_LIFETIME ) < gpGlobals->curtime )
|
||||
{
|
||||
Destroy( pMeteor );
|
||||
}
|
||||
|
||||
// Meteor Head and Tail
|
||||
pMeteor->SetTravelDirection( vecDirection );
|
||||
|
||||
pMeteor->m_HeadEffect.SetSmokeEmission( true );
|
||||
pMeteor->m_HeadEffect.Start( vecOrigin, vecDirection );
|
||||
pMeteor->m_HeadEffect.SetParticleScale( 1.0f / 16.0f );
|
||||
|
||||
pMeteor->m_TailEffect.Start( vecOrigin, vecDirection, flSpeed );
|
||||
|
||||
pMeteor->SetNextClientThink( CLIENT_THINK_ALWAYS );
|
||||
}
|
||||
|
||||
return pMeteor;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//-----------------------------------------------------------------------------
|
||||
void C_EnvMeteor::Destroy( C_EnvMeteor *pMeteor )
|
||||
{
|
||||
Assert( pMeteor->GetClientHandle() != INVALID_CLIENTENTITY_HANDLE );
|
||||
ClientThinkList()->AddToDeleteList( pMeteor->GetClientHandle() );
|
||||
}
|
||||
@@ -0,0 +1,189 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================//
|
||||
|
||||
#ifndef C_ENV_METEOR_H
|
||||
#define C_ENV_METEOR_H
|
||||
#pragma once
|
||||
|
||||
#include "utlvector.h"
|
||||
#include "env_meteor_shared.h"
|
||||
#include "baseparticleentity.h"
|
||||
#include "c_effect_shootingstar.h"
|
||||
|
||||
//=============================================================================
|
||||
//
|
||||
// Client-side Meteor Factory Class
|
||||
//
|
||||
class C_MeteorFactory : public IMeteorFactory
|
||||
{
|
||||
public:
|
||||
|
||||
void CreateMeteor( int nID, int iType, const Vector &vecPosition,
|
||||
const Vector &vecDirection, float flSpeed, float flStartTime,
|
||||
float flDamageRadius,
|
||||
const Vector &vecTriggerMins, const Vector &vecTriggerMaxs );
|
||||
};
|
||||
|
||||
//=============================================================================
|
||||
//
|
||||
// Meteor Spawner Class
|
||||
//
|
||||
class C_EnvMeteorSpawner : public C_BaseEntity
|
||||
{
|
||||
public:
|
||||
|
||||
DECLARE_CLASS( C_EnvMeteorSpawner, C_BaseEntity );
|
||||
|
||||
DECLARE_CLIENTCLASS();
|
||||
|
||||
C_EnvMeteorSpawner();
|
||||
|
||||
// Will more than likely be used for meteor input(s) later!
|
||||
// void ReceiveMessage( const char *msgname, int length, void *data );
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
// Networking
|
||||
//-------------------------------------------------------------------------
|
||||
void OnDataChanged( DataUpdateType_t updateType );
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
// Think
|
||||
//-------------------------------------------------------------------------
|
||||
void ClientThink( void );
|
||||
|
||||
private:
|
||||
|
||||
C_MeteorFactory m_Factory;
|
||||
CEnvMeteorSpawnerShared m_SpawnerShared;
|
||||
bool m_fDisabled;
|
||||
};
|
||||
|
||||
|
||||
//=============================================================================
|
||||
//
|
||||
// Meteor Tail Class - Effect
|
||||
//
|
||||
class C_EnvMeteorHead
|
||||
{
|
||||
public:
|
||||
|
||||
C_EnvMeteorHead();
|
||||
~C_EnvMeteorHead();
|
||||
|
||||
void Start( const Vector &vecOrigin, const Vector &vecDirection );
|
||||
void Destroy( void );
|
||||
|
||||
void MeteorHeadThink( const Vector &vecOrigin, float flTime );
|
||||
|
||||
void SetSmokeEmission( bool bEmit ) { m_bEmitSmoke = bEmit; }
|
||||
bool EmitSmoke( void ) { return m_bEmitSmoke; }
|
||||
|
||||
void SetParticleScale( float flScale ) { m_flParticleScale = flScale; }
|
||||
|
||||
bool m_bInitThink;
|
||||
|
||||
private:
|
||||
|
||||
Vector m_vecPos;
|
||||
Vector m_vecPrevPos;
|
||||
Vector m_vecDirection;
|
||||
|
||||
float m_flParticleScale;
|
||||
|
||||
CSmartPtr<CSimpleEmitter> m_pSmokeEmitter;
|
||||
float m_flSmokeSpawnInterval;
|
||||
float m_flSmokeSpawnRadius;
|
||||
PMaterialHandle m_hSmokeMaterial;
|
||||
float m_flSmokeLifetime; // How long do the particles live?
|
||||
bool m_bEmitSmoke;
|
||||
|
||||
PMaterialHandle m_hFlareMaterial;
|
||||
};
|
||||
|
||||
//=============================================================================
|
||||
//
|
||||
// Meteor Tail Class - Effect
|
||||
//
|
||||
class C_EnvMeteorTail : public C_BaseParticleEntity
|
||||
{
|
||||
public:
|
||||
|
||||
DECLARE_CLASS( C_EnvMeteorTail, C_BaseParticleEntity );
|
||||
|
||||
C_EnvMeteorTail();
|
||||
~C_EnvMeteorTail();
|
||||
|
||||
void Start( const Vector &vecOrigin, const Vector &vecDirection, float flSpeed );
|
||||
void Destroy( void );
|
||||
virtual void RenderParticles( CParticleRenderIterator *pIterator );
|
||||
virtual void SimulateParticles( CParticleSimulateIterator *pIterator );
|
||||
|
||||
//protected:
|
||||
|
||||
void DrawFragment( ParticleDraw* pDraw, const Vector &vecStart, const Vector &vecDelta,
|
||||
const Vector4D &vecStartColor, const Vector4D &vecEndColor,
|
||||
float flStartV, float flEndV );
|
||||
|
||||
CParticleMgr *m_pParticleMgr;
|
||||
Particle *m_pParticle;
|
||||
|
||||
PMaterialHandle m_TailMaterialHandle;
|
||||
|
||||
// Properties.
|
||||
float m_flFadeTime;
|
||||
float m_flWidth;
|
||||
float m_flSpeed;
|
||||
Vector m_vecDirection;
|
||||
|
||||
private:
|
||||
C_EnvMeteorTail( const C_EnvMeteorTail & );
|
||||
};
|
||||
|
||||
//=============================================================================
|
||||
//
|
||||
// Meteor Class (Client-side only!)
|
||||
//
|
||||
class C_EnvMeteor : public C_BaseAnimating
|
||||
{
|
||||
public:
|
||||
|
||||
DECLARE_CLASS( C_EnvMeteor, C_BaseAnimating );
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
// Initialization/Destruction
|
||||
//-------------------------------------------------------------------------
|
||||
C_EnvMeteor();
|
||||
~C_EnvMeteor();
|
||||
static C_EnvMeteor *Create( int nID, int iMeteorType, const Vector &vecOrigin,
|
||||
const Vector &vecDirection, float flSpeed, float flStartTime,
|
||||
float flDamageRadius,
|
||||
const Vector &vecTriggerMins, const Vector &vecTriggerMaxs );
|
||||
static void Destroy( C_EnvMeteor *pMeteor );
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
// Think
|
||||
//-------------------------------------------------------------------------
|
||||
void ClientThink( void );
|
||||
void SkyboxThink( float flTime );
|
||||
void WorldThink( float flTime );
|
||||
void WorldToSkyboxThink( float flTime );
|
||||
void SkyboxToWorldThink( float flTime );
|
||||
|
||||
void SetTravelDirection( const Vector &vecDir ) { m_vecTravelDir = vecDir; }
|
||||
|
||||
private:
|
||||
C_EnvMeteor( const C_EnvMeteor & );
|
||||
|
||||
CEnvMeteorShared m_Meteor;
|
||||
|
||||
// Effects
|
||||
Vector m_vecTravelDir;
|
||||
C_EnvMeteorHead m_HeadEffect;
|
||||
C_EnvMeteorTail m_TailEffect;
|
||||
};
|
||||
|
||||
#endif // C_ENV_METEOR_H
|
||||
@@ -0,0 +1,42 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose: A place where vehicles can be built
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================//
|
||||
#include "cbase.h"
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: A place where vehicles can be built
|
||||
//-----------------------------------------------------------------------------
|
||||
class C_FuncConstructionYard : public C_BaseEntity
|
||||
{
|
||||
DECLARE_CLASS( C_FuncConstructionYard, C_BaseEntity );
|
||||
public:
|
||||
DECLARE_CLIENTCLASS();
|
||||
// DECLARE_MINIMAP_PANEL();
|
||||
|
||||
C_FuncConstructionYard();
|
||||
const char *GetTargetDescription( void ) const;
|
||||
};
|
||||
|
||||
|
||||
IMPLEMENT_CLIENTCLASS_DT(C_FuncConstructionYard, DT_FuncConstructionYard, CFuncConstructionYard)
|
||||
END_RECV_TABLE()
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
C_FuncConstructionYard::C_FuncConstructionYard()
|
||||
{
|
||||
// CONSTRUCT_MINIMAP_PANEL( "minimap_construction_yard", MINIMAP_RESOURCE_ZONES );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
const char *C_FuncConstructionYard::GetTargetDescription( void ) const
|
||||
{
|
||||
return "Construction Yard";
|
||||
}
|
||||
|
||||
@@ -0,0 +1,263 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose: Client's CResourceZone.
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================//
|
||||
#include "cbase.h"
|
||||
#include "engine/IEngineSound.h"
|
||||
#include "c_func_resource.h"
|
||||
#include "techtree.h"
|
||||
#include "fx.h"
|
||||
#include "fx_sparks.h"
|
||||
|
||||
// memdbgon must be the last include file in a .cpp file!!!
|
||||
#include "tier0/memdbgon.h"
|
||||
|
||||
// Chunk movement
|
||||
#define CHUNK_FLECK_MIN_SPEED 25.0f
|
||||
#define CHUNK_FLECK_MAX_SPEED 100.0f
|
||||
#define CHUNK_FLECK_GRAVITY 800.0f
|
||||
#define CHUNK_FLECK_DAMPEN 0.3f
|
||||
#define CHUNK_FLECK_ANGULAR_SPRAY 0.8f
|
||||
|
||||
IMPLEMENT_CLIENTCLASS_DT(C_ResourceZone, DT_ResourceZone, CResourceZone)
|
||||
RecvPropFloat(RECVINFO(m_flClientResources)),
|
||||
RecvPropInt(RECVINFO(m_nResourcesLeft)),
|
||||
END_RECV_TABLE()
|
||||
|
||||
LINK_ENTITY_TO_CLASS( trigger_resourcezone, C_ResourceZone );
|
||||
BEGIN_PREDICTION_DATA( C_ResourceZone )
|
||||
END_PREDICTION_DATA();
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
C_ResourceZone::C_ResourceZone()
|
||||
{
|
||||
CONSTRUCT_MINIMAP_PANEL( "minimap_resource_zone", MINIMAP_RESOURCE_ZONES );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Add, remove object from the panel
|
||||
//-----------------------------------------------------------------------------
|
||||
void C_ResourceZone::SetDormant( bool bDormant )
|
||||
{
|
||||
BaseClass::SetDormant( bDormant );
|
||||
ENTITY_PANEL_ACTIVATE( "resourcezone", (!bDormant && m_flClientResources > 0) );
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void C_ResourceZone::OnDataChanged( DataUpdateType_t updateType )
|
||||
{
|
||||
BaseClass::OnDataChanged( updateType );
|
||||
|
||||
if ( updateType == DATA_UPDATE_CREATED )
|
||||
{
|
||||
SetNextClientThink( gpGlobals->curtime + 1.0 );
|
||||
}
|
||||
|
||||
// If I've just dried up, remove me from the minimap
|
||||
if ( m_flClientResources <= 0 )
|
||||
{
|
||||
ENTITY_PANEL_ACTIVATE( "resourcezone", false );
|
||||
DESTRUCT_MINIMAP_PANEL();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
const char *C_ResourceZone::GetTargetDescription( void ) const
|
||||
{
|
||||
return "Resource Zone";
|
||||
}
|
||||
|
||||
|
||||
//==========================================================================================================
|
||||
// Resource Spawner
|
||||
//==========================================================================================================
|
||||
IMPLEMENT_CLIENTCLASS_DT(C_ResourceSpawner, DT_ResourceSpawner, CResourceSpawner)
|
||||
RecvPropInt(RECVINFO(m_bActive)),
|
||||
END_RECV_TABLE()
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
C_ResourceSpawner::C_ResourceSpawner( void )
|
||||
{
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void C_ResourceSpawner::OnDataChanged( DataUpdateType_t updateType )
|
||||
{
|
||||
BaseClass::OnDataChanged( updateType );
|
||||
|
||||
if ( updateType == DATA_UPDATE_CREATED )
|
||||
{
|
||||
SetNextClientThink( gpGlobals->curtime + random->RandomFloat( 2.0, 4.0 ) );
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Receive a spawn message from the server
|
||||
//-----------------------------------------------------------------------------
|
||||
void C_ResourceSpawner::ReceiveMessage( int classID, bf_read &msg )
|
||||
{
|
||||
if ( classID != GetClientClass()->m_ClassID )
|
||||
{
|
||||
// message is for subclass
|
||||
BaseClass::ReceiveMessage( classID, msg );
|
||||
return;
|
||||
}
|
||||
|
||||
// Make some particles
|
||||
SpawnEffect( true );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void C_ResourceSpawner::ClientThink( void )
|
||||
{
|
||||
SetNextClientThink( gpGlobals->curtime + random->RandomFloat( 2.0, 10.0 ) );
|
||||
|
||||
// Don't do random puffs if I'm not active
|
||||
if ( !m_bActive )
|
||||
return;
|
||||
|
||||
// Occasionally spurt as if I was making a chunk
|
||||
if ( random->RandomInt(0, 20) == 5 )
|
||||
{
|
||||
SpawnEffect( true );
|
||||
}
|
||||
else
|
||||
{
|
||||
SpawnEffect( false );
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Particle effects created when we spawn a chunk
|
||||
//-----------------------------------------------------------------------------
|
||||
void C_ResourceSpawner::SpawnEffect( bool bSpawningChunk )
|
||||
{
|
||||
Vector normal = Vector(0,0,1);
|
||||
Vector offset = GetAbsOrigin() + (normal * 16);
|
||||
Vector dir;
|
||||
|
||||
float r = sResourceColor.r;
|
||||
float g = sResourceColor.g;
|
||||
float b = sResourceColor.b;
|
||||
|
||||
// Play a random puff sound
|
||||
if ( bSpawningChunk )
|
||||
{
|
||||
EmitSound( "ResourceSpawner.BigPuff" );
|
||||
}
|
||||
else
|
||||
{
|
||||
EmitSound( "ResourceSpawner.Puff" );
|
||||
}
|
||||
|
||||
// Chunks o'dirt
|
||||
CSmartPtr<CFleckParticles> fleckEmitter = CFleckParticles::Create( "SpawnEffect 1", offset, Vector(5,5,5) );
|
||||
if ( !fleckEmitter )
|
||||
return;
|
||||
|
||||
// Setup our collision information
|
||||
fleckEmitter->m_ParticleCollision.Setup( offset, &normal, CHUNK_FLECK_ANGULAR_SPRAY, CHUNK_FLECK_MIN_SPEED, CHUNK_FLECK_MAX_SPEED, CHUNK_FLECK_GRAVITY, CHUNK_FLECK_DAMPEN );
|
||||
|
||||
int numFlecks;
|
||||
if ( bSpawningChunk )
|
||||
numFlecks = random->RandomInt( 48, 64 );
|
||||
else
|
||||
numFlecks = random->RandomInt( 1, 3 );
|
||||
|
||||
// Dump out flecks
|
||||
int i;
|
||||
for ( i = 0; i < numFlecks; i++ )
|
||||
{
|
||||
FleckParticle *pParticle = (FleckParticle *) fleckEmitter->AddParticle( sizeof(FleckParticle), g_Mat_Fleck_Cement[random->RandomInt(0,1)], offset );
|
||||
|
||||
if ( pParticle == NULL )
|
||||
break;
|
||||
|
||||
pParticle->m_flLifetime = 0.0f;
|
||||
pParticle->m_flDieTime = random->RandomFloat(3.0f,5.0f);
|
||||
|
||||
if ( bSpawningChunk )
|
||||
{
|
||||
pParticle->m_uchSize = random->RandomInt( 4, 8 );
|
||||
dir[0] = normal[0] + random->RandomFloat( -CHUNK_FLECK_ANGULAR_SPRAY, CHUNK_FLECK_ANGULAR_SPRAY );
|
||||
dir[1] = normal[1] + random->RandomFloat( -CHUNK_FLECK_ANGULAR_SPRAY, CHUNK_FLECK_ANGULAR_SPRAY );
|
||||
dir[2] = normal[2] + random->RandomFloat( -CHUNK_FLECK_ANGULAR_SPRAY, CHUNK_FLECK_ANGULAR_SPRAY );
|
||||
pParticle->m_vecVelocity = dir * ( random->RandomFloat( CHUNK_FLECK_MIN_SPEED, CHUNK_FLECK_MAX_SPEED ) * ( 9 - pParticle->m_uchSize ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
pParticle->m_uchSize = random->RandomInt( 2, 4 );
|
||||
dir[0] = normal[0] + (random->RandomFloat( -CHUNK_FLECK_ANGULAR_SPRAY, CHUNK_FLECK_ANGULAR_SPRAY ) * 0.5);
|
||||
dir[1] = normal[1] + (random->RandomFloat( -CHUNK_FLECK_ANGULAR_SPRAY, CHUNK_FLECK_ANGULAR_SPRAY ) * 0.5);
|
||||
dir[2] = normal[2] + (random->RandomFloat( -CHUNK_FLECK_ANGULAR_SPRAY, CHUNK_FLECK_ANGULAR_SPRAY ) * 0.5);
|
||||
pParticle->m_vecVelocity = dir * ( random->RandomFloat( CHUNK_FLECK_MIN_SPEED, CHUNK_FLECK_MAX_SPEED ) * 3);
|
||||
}
|
||||
|
||||
pParticle->m_flRoll = random->RandomFloat( 0, 360 );
|
||||
pParticle->m_flRollDelta = random->RandomFloat( 0, 360 );
|
||||
|
||||
pParticle->m_uchColor[0] = r;
|
||||
pParticle->m_uchColor[1] = g;
|
||||
pParticle->m_uchColor[2] = b;
|
||||
}
|
||||
|
||||
|
||||
// Create a couple of big, floating smoke clouds
|
||||
if ( bSpawningChunk || random->RandomInt(0,10) == 0 )
|
||||
{
|
||||
CSmartPtr<CSimpleEmitter> pSmokeEmitter = CSimpleEmitter::Create( "SpawnEffect 2" );
|
||||
pSmokeEmitter->SetSortOrigin( offset );
|
||||
int iSmokeClouds = 2;
|
||||
if ( !bSpawningChunk )
|
||||
iSmokeClouds = 1;
|
||||
for ( i = 0; i < iSmokeClouds; i++ )
|
||||
{
|
||||
SimpleParticle *pParticle = (SimpleParticle *) pSmokeEmitter->AddParticle( sizeof(SimpleParticle), g_Mat_DustPuff[1], offset );
|
||||
if ( pParticle == NULL )
|
||||
break;
|
||||
|
||||
pParticle->m_flLifetime = 0.0f;
|
||||
pParticle->m_flDieTime = random->RandomFloat( 2.0f, 3.0f );
|
||||
|
||||
if ( bSpawningChunk )
|
||||
{
|
||||
pParticle->m_uchStartSize = 32;
|
||||
pParticle->m_uchEndSize = 128;
|
||||
}
|
||||
else
|
||||
{
|
||||
pParticle->m_uchStartSize = 16;
|
||||
pParticle->m_uchEndSize = 64;
|
||||
}
|
||||
|
||||
dir[0] = normal[0] + random->RandomFloat( -0.4f, 0.4f );
|
||||
dir[1] = normal[1] + random->RandomFloat( -0.4f, 0.4f );
|
||||
dir[2] = normal[2] + random->RandomFloat( 0, 0.6f );
|
||||
pParticle->m_vecVelocity = dir * random->RandomFloat( 2.0f, 24.0f )*(i+1);
|
||||
pParticle->m_uchStartAlpha = 160;
|
||||
pParticle->m_uchEndAlpha = 0;
|
||||
pParticle->m_flRoll = random->RandomFloat( 180, 360 );
|
||||
pParticle->m_flRollDelta = random->RandomFloat( -1, 1 );
|
||||
|
||||
pParticle->m_uchColor[0] = r;
|
||||
pParticle->m_uchColor[1] = g;
|
||||
pParticle->m_uchColor[2] = b;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,57 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose: Client's CObjectSentrygun
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================//
|
||||
|
||||
#ifndef C_FUNC_RESOURCE_H
|
||||
#define C_FUNC_RESOURCE_H
|
||||
|
||||
#include "commanderoverlay.h"
|
||||
#include "hud_minimap.h"
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: A resource zone
|
||||
//-----------------------------------------------------------------------------
|
||||
class C_ResourceZone : public C_BaseEntity
|
||||
{
|
||||
DECLARE_CLASS( C_ResourceZone, C_BaseEntity );
|
||||
public:
|
||||
DECLARE_PREDICTABLE();
|
||||
DECLARE_CLIENTCLASS();
|
||||
DECLARE_ENTITY_PANEL();
|
||||
DECLARE_MINIMAP_PANEL();
|
||||
|
||||
C_ResourceZone();
|
||||
virtual void SetDormant( bool bDormant );
|
||||
virtual void OnDataChanged( DataUpdateType_t updateType );
|
||||
const char *GetTargetDescription( void ) const;
|
||||
|
||||
public:
|
||||
float m_flClientResources; // Amount of resources left
|
||||
int m_nResourcesLeft;
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: A resource chunk spawning point in a resource zone
|
||||
//-----------------------------------------------------------------------------
|
||||
class C_ResourceSpawner : public C_BaseAnimating
|
||||
{
|
||||
DECLARE_CLASS( C_ResourceSpawner, C_BaseAnimating );
|
||||
public:
|
||||
DECLARE_CLIENTCLASS();
|
||||
|
||||
C_ResourceSpawner();
|
||||
virtual void OnDataChanged( DataUpdateType_t updateType );
|
||||
virtual void ReceiveMessage( int classID, bf_read &msg );
|
||||
virtual void SpawnEffect( bool bSpawningChunk );
|
||||
virtual void ClientThink( void );
|
||||
|
||||
public:
|
||||
bool m_bActive;
|
||||
};
|
||||
|
||||
#endif // C_FUNC_RESOURCE_H
|
||||
|
||||
@@ -0,0 +1,350 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================//
|
||||
#include "cbase.h"
|
||||
#include "c_gasoline_blob.h"
|
||||
#include "gasoline_shared.h"
|
||||
#include "engine/IEngineSound.h"
|
||||
#include "clienteffectprecachesystem.h"
|
||||
|
||||
static CUtlLinkedList<C_GasolineBlob*, int> g_GasolineBlobs;
|
||||
|
||||
// If multiple blobs are within this distance to each other, then only one will
|
||||
// play a sound.
|
||||
#define BLOB_SOUND_RELATED_DISTANCE 600
|
||||
|
||||
|
||||
#define PUDDLE_START_SIZE 35
|
||||
#define PUDDLE_END_SIZE 65
|
||||
#define PUDDLE_GROW_TIME 0.5
|
||||
|
||||
#define PUDDLE_FADE_TIME 1.0
|
||||
|
||||
|
||||
CLIENTEFFECT_REGISTER_BEGIN( PrecacheGasolineBlob )
|
||||
CLIENTEFFECT_MATERIAL( "decals/puddle" )
|
||||
CLIENTEFFECT_REGISTER_END()
|
||||
|
||||
// ------------------------------------------------------------------------------------------------ //
|
||||
// CGasolineEmitter.
|
||||
// ------------------------------------------------------------------------------------------------ //
|
||||
|
||||
CSmartPtr<CGasolineEmitter> CGasolineEmitter::Create( C_GasolineBlob *pBlob )
|
||||
{
|
||||
CGasolineEmitter *pEmitter = new CGasolineEmitter;
|
||||
|
||||
pEmitter->m_pBlob = pBlob;
|
||||
|
||||
pEmitter->m_hFireMaterial = pEmitter->GetPMaterial( "particle/fire" );
|
||||
pEmitter->m_hUnlitMaterial = pEmitter->GetPMaterial( "sprites/env_particles" );
|
||||
|
||||
pEmitter->m_Timer.Init( 40 );
|
||||
|
||||
return pEmitter;
|
||||
}
|
||||
|
||||
|
||||
void CGasolineEmitter::UpdateFire( float frametime )
|
||||
{
|
||||
float flLifetime = gpGlobals->curtime - m_pBlob->m_flCreateTime;
|
||||
|
||||
float litPercent = 1;
|
||||
if ( m_pBlob->IsLit() )
|
||||
{
|
||||
litPercent = 1 - (flLifetime / m_pBlob->m_flMaxLifetime);
|
||||
if ( litPercent <= 0 )
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// Don't show a burn effect for a blob that hasn't hit anything yet.
|
||||
// If you do, it tends to make the flamethrower effect look weird.
|
||||
if ( !m_pBlob->IsStopped() )
|
||||
return;
|
||||
|
||||
// Make a coordinate system in which to spawn the particles. It
|
||||
Vector vUp, vRight;
|
||||
vUp.Init();
|
||||
vRight.Init();
|
||||
if ( m_pBlob->IsStopped() )
|
||||
{
|
||||
QAngle angles;
|
||||
VectorAngles( m_pBlob->GetSurfaceNormal(), angles );
|
||||
AngleVectors( angles, NULL, &vRight, &vUp );
|
||||
}
|
||||
|
||||
PMaterialHandle hMaterial = m_hFireMaterial;
|
||||
float flParticleLifetime = 1;
|
||||
float flRadius = 7;
|
||||
unsigned char uchColor[4] = { 255, 128, 0, 128 };
|
||||
float flMaxZVel = 29;
|
||||
|
||||
|
||||
float curDelta = frametime;
|
||||
while ( m_Timer.NextEvent( curDelta ) )
|
||||
{
|
||||
// Based on how close we are to expiring, show less particles.
|
||||
if ( RandomFloat( 0, 1 ) > litPercent )
|
||||
continue;
|
||||
|
||||
Vector vPos = m_pBlob->GetAbsOrigin();
|
||||
if ( m_pBlob->IsStopped() )
|
||||
{
|
||||
float flAngle = RandomFloat( 0, M_PI * 2 );
|
||||
float flDist = RandomFloat( 0, GASOLINE_BLOB_RADIUS );
|
||||
vPos += vRight * (cos( flAngle ) * flDist);
|
||||
vPos += vUp * ( sin( flAngle ) * flDist );
|
||||
}
|
||||
else
|
||||
{
|
||||
vPos += RandomVector( -GASOLINE_BLOB_RADIUS, GASOLINE_BLOB_RADIUS );
|
||||
}
|
||||
|
||||
SimpleParticle *pParticle = AddSimpleParticle( hMaterial, vPos, flParticleLifetime, flRadius );
|
||||
if ( pParticle )
|
||||
{
|
||||
pParticle->m_uchColor[0] = uchColor[0];
|
||||
pParticle->m_uchColor[1] = uchColor[1];
|
||||
pParticle->m_uchColor[2] = uchColor[2];
|
||||
|
||||
pParticle->m_uchEndAlpha = 0;
|
||||
pParticle->m_uchStartAlpha = uchColor[3];
|
||||
|
||||
pParticle->m_vecVelocity.x = RandomFloat( -2, 2 );
|
||||
pParticle->m_vecVelocity.y = RandomFloat( -2, 2 );
|
||||
pParticle->m_vecVelocity.z = RandomFloat( 3, flMaxZVel );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// ------------------------------------------------------------------------------------------------ //
|
||||
// C_GasolineBlob.
|
||||
// ------------------------------------------------------------------------------------------------ //
|
||||
|
||||
IMPLEMENT_CLIENTCLASS_DT_NOBASE( C_GasolineBlob, DT_GasolineBlob, CGasolineBlob )
|
||||
RecvPropInt( RECVINFO( m_BlobFlags ) ),
|
||||
RecvPropVector( RECVINFO_NAME( m_vecNetworkOrigin, m_vecOrigin ) ),
|
||||
RecvPropInt( RECVINFO_NAME(m_hNetworkMoveParent, moveparent), 0, RecvProxy_IntToMoveParent ),
|
||||
RecvPropFloat( RECVINFO( m_flLitStartTime ) ),
|
||||
RecvPropFloat( RECVINFO( m_flCreateTime ) ),
|
||||
RecvPropFloat( RECVINFO( m_flMaxLifetime ) ),
|
||||
RecvPropInt( RECVINFO( m_iTeamNum ) ),
|
||||
RecvPropVector( RECVINFO( m_vSurfaceNormal ) )
|
||||
END_RECV_TABLE()
|
||||
|
||||
|
||||
C_GasolineBlob::C_GasolineBlob()
|
||||
{
|
||||
m_pEmitter = CGasolineEmitter::Create( this );
|
||||
m_vSurfaceNormal.Init();
|
||||
m_flLitStartTime = 0;
|
||||
m_bSoundOn = false;
|
||||
g_GasolineBlobs.AddToTail( this );
|
||||
m_flPuddleSize = PUDDLE_START_SIZE;
|
||||
m_flPuddleFade = 1;
|
||||
}
|
||||
|
||||
|
||||
C_GasolineBlob::~C_GasolineBlob()
|
||||
{
|
||||
g_GasolineBlobs.FindAndRemove( this );
|
||||
StopSound();
|
||||
|
||||
// If a bunch of nearby blobs weren't playing a sound because we were, have them start their sound now.
|
||||
FOR_EACH_LL( g_GasolineBlobs, i )
|
||||
{
|
||||
C_GasolineBlob *pBlob = g_GasolineBlobs[i];
|
||||
|
||||
if ( pBlob->IsSoundRelatedTo( this ) )
|
||||
pBlob->CheckStartSound();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool C_GasolineBlob::IsLit() const
|
||||
{
|
||||
return (m_BlobFlags & BLOBFLAG_LIT) != 0;
|
||||
}
|
||||
|
||||
|
||||
bool C_GasolineBlob::IsStopped() const
|
||||
{
|
||||
return (m_BlobFlags & BLOBFLAG_STOPPED) != 0;
|
||||
}
|
||||
|
||||
|
||||
const Vector& C_GasolineBlob::GetSurfaceNormal() const
|
||||
{
|
||||
return m_vSurfaceNormal;
|
||||
}
|
||||
|
||||
|
||||
float C_GasolineBlob::GetLitStartTime() const
|
||||
{
|
||||
return m_flLitStartTime;
|
||||
}
|
||||
|
||||
|
||||
void C_GasolineBlob::OnDataChanged( DataUpdateType_t type )
|
||||
{
|
||||
BaseClass::OnDataChanged( type );
|
||||
|
||||
if ( type == DATA_UPDATE_CREATED )
|
||||
{
|
||||
SetNextClientThink( CLIENT_THINK_ALWAYS );
|
||||
}
|
||||
|
||||
CheckStartSound();
|
||||
}
|
||||
|
||||
|
||||
void C_GasolineBlob::ClientThink()
|
||||
{
|
||||
if ( m_pEmitter.IsValid() )
|
||||
m_pEmitter->UpdateFire( gpGlobals->frametime );
|
||||
|
||||
// Grow the puddle a little.
|
||||
if ( IsStopped() )
|
||||
{
|
||||
if ( IsLit() )
|
||||
{
|
||||
// Fade out after we get lit.
|
||||
m_flPuddleFade -= gpGlobals->frametime / PUDDLE_FADE_TIME;
|
||||
m_flPuddleFade = MAX( m_flPuddleFade, 0 );
|
||||
}
|
||||
else
|
||||
{
|
||||
// Grow the puddle until it's at its max size.
|
||||
m_flPuddleSize += gpGlobals->frametime * ( PUDDLE_END_SIZE - PUDDLE_START_SIZE ) / PUDDLE_GROW_TIME;
|
||||
m_flPuddleSize = MIN( m_flPuddleSize, PUDDLE_END_SIZE );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool C_GasolineBlob::ShouldDraw()
|
||||
{
|
||||
return IsStopped() && (m_flPuddleFade > 0);
|
||||
}
|
||||
|
||||
|
||||
int C_GasolineBlob::DrawModel( int flags )
|
||||
{
|
||||
// Generate a basis.
|
||||
QAngle angles;
|
||||
VectorAngles( m_vSurfaceNormal, angles );
|
||||
|
||||
Vector vRight, vUp;
|
||||
AngleVectors( angles, NULL, &vRight, &vUp );
|
||||
|
||||
|
||||
float flAlpha = m_flPuddleFade * RemapVal( m_flPuddleSize, PUDDLE_START_SIZE, PUDDLE_END_SIZE, 0, 1 );
|
||||
if ( flAlpha <= 0 )
|
||||
return 0;
|
||||
|
||||
|
||||
// Draw the puddle.
|
||||
IMaterial *pMat = materials->FindMaterial( "decals/puddle", TEXTURE_GROUP_DECAL );
|
||||
IMesh *pMesh = materials->GetDynamicMesh( true, NULL, NULL, pMat );
|
||||
CMeshBuilder mb;
|
||||
mb.Begin( pMesh, MATERIAL_QUADS, 1 );
|
||||
|
||||
Vector v;
|
||||
|
||||
v = GetAbsOrigin() + m_vSurfaceNormal + vRight*m_flPuddleSize - vUp*m_flPuddleSize;
|
||||
mb.Position3f( v.x, v.y, v.z );
|
||||
mb.Color4f( 1, 1, 1, flAlpha );
|
||||
mb.Normal3f( VectorExpand( m_vSurfaceNormal ) );
|
||||
mb.TexCoord2f( 0, 1, 0 );
|
||||
mb.AdvanceVertex();
|
||||
|
||||
v = GetAbsOrigin() + m_vSurfaceNormal + vRight*m_flPuddleSize + vUp*m_flPuddleSize;
|
||||
mb.Position3f( v.x, v.y, v.z );
|
||||
mb.Color4f( 1, 1, 1, flAlpha );
|
||||
mb.Normal3f( VectorExpand( m_vSurfaceNormal ) );
|
||||
mb.TexCoord2f( 0, 1, 1 );
|
||||
mb.AdvanceVertex();
|
||||
|
||||
v = GetAbsOrigin() + m_vSurfaceNormal - vRight*m_flPuddleSize + vUp*m_flPuddleSize;
|
||||
mb.Position3f( v.x, v.y, v.z );
|
||||
mb.Color4f( 1, 1, 1, flAlpha );
|
||||
mb.Normal3f( VectorExpand( m_vSurfaceNormal ) );
|
||||
mb.TexCoord2f( 0, 0, 1 );
|
||||
mb.AdvanceVertex();
|
||||
|
||||
v = GetAbsOrigin() + m_vSurfaceNormal - vRight*m_flPuddleSize - vUp*m_flPuddleSize;
|
||||
mb.Position3f( v.x, v.y, v.z );
|
||||
mb.Color4f( 1, 1, 1, flAlpha );
|
||||
mb.Normal3f( VectorExpand( m_vSurfaceNormal ) );
|
||||
mb.TexCoord2f( 0, 0, 0 );
|
||||
mb.AdvanceVertex();
|
||||
|
||||
mb.End( false, true );
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
bool C_GasolineBlob::IsSoundRelatedTo( const C_GasolineBlob *pBlob ) const
|
||||
{
|
||||
return pBlob->GetAbsOrigin().DistTo( GetAbsOrigin() ) < BLOB_SOUND_RELATED_DISTANCE;
|
||||
}
|
||||
|
||||
|
||||
bool C_GasolineBlob::IsPlayingBurningSound() const
|
||||
{
|
||||
return m_bSoundOn;
|
||||
}
|
||||
|
||||
|
||||
void C_GasolineBlob::CheckStartSound()
|
||||
{
|
||||
if ( IsPlayingBurningSound() || (m_BlobFlags & BLOBFLAG_STOPPED) == 0 || !IsLit() )
|
||||
return;
|
||||
|
||||
|
||||
// First, make sure no nearby blob is playing the sound.
|
||||
FOR_EACH_LL( g_GasolineBlobs, i )
|
||||
{
|
||||
C_GasolineBlob *pBlob = g_GasolineBlobs[i];
|
||||
|
||||
if ( pBlob != this && pBlob->IsSoundRelatedTo( this ) )
|
||||
{
|
||||
// If it's already playing a sound, then don't start our sound.
|
||||
if ( pBlob->IsPlayingBurningSound() )
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
StartSound();
|
||||
}
|
||||
|
||||
|
||||
void C_GasolineBlob::StartSound()
|
||||
{
|
||||
if ( !m_bSoundOn )
|
||||
{
|
||||
EmitSound( "GasolineBlob.FlameSound" );
|
||||
|
||||
m_bSoundOn = true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void C_GasolineBlob::StopSound()
|
||||
{
|
||||
if ( m_bSoundOn )
|
||||
{
|
||||
BaseClass::StopSound( "GasolineBlob.FlameSound" );
|
||||
m_bSoundOn = false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,107 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================//
|
||||
|
||||
#ifndef C_GASOLINE_BLOB_H
|
||||
#define C_GASOLINE_BLOB_H
|
||||
#ifdef _WIN32
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
|
||||
#include "c_baseentity.h"
|
||||
#include "particles_simple.h"
|
||||
#include "particle_util.h"
|
||||
|
||||
|
||||
class C_GasolineBlob;
|
||||
|
||||
class CGasolineEmitter : public CSimpleEmitter
|
||||
{
|
||||
public:
|
||||
|
||||
static CSmartPtr<CGasolineEmitter> Create( C_GasolineBlob *pBlob );
|
||||
|
||||
void UpdateFire( float frametime );
|
||||
|
||||
|
||||
private:
|
||||
|
||||
CGasolineEmitter() : CSimpleEmitter( "Gasoline" ){}
|
||||
CGasolineEmitter( const CGasolineEmitter & );
|
||||
|
||||
|
||||
C_GasolineBlob *m_pBlob;
|
||||
|
||||
PMaterialHandle m_hFireMaterial;
|
||||
PMaterialHandle m_hUnlitMaterial;
|
||||
TimedEvent m_Timer;
|
||||
};
|
||||
|
||||
|
||||
class C_GasolineBlob : public C_BaseEntity
|
||||
{
|
||||
friend class CGasolineEmitter;
|
||||
|
||||
public:
|
||||
DECLARE_CLASS( C_GasolineBlob, C_BaseEntity );
|
||||
DECLARE_CLIENTCLASS();
|
||||
|
||||
|
||||
C_GasolineBlob();
|
||||
virtual ~C_GasolineBlob();
|
||||
|
||||
bool IsLit() const;
|
||||
bool IsStopped() const;
|
||||
const Vector& GetSurfaceNormal() const;
|
||||
float GetLitStartTime() const;
|
||||
|
||||
|
||||
// Overrides.
|
||||
public:
|
||||
|
||||
virtual void OnDataChanged( DataUpdateType_t type );
|
||||
virtual void ClientThink();
|
||||
virtual int DrawModel( int flags );
|
||||
virtual bool ShouldDraw();
|
||||
|
||||
|
||||
private:
|
||||
|
||||
// Returns true if the two blobs relate their sound, meaning one blob won't play
|
||||
// its sound if the other one is playing it.
|
||||
bool IsSoundRelatedTo( const C_GasolineBlob *pBlob ) const;
|
||||
|
||||
bool IsPlayingBurningSound() const;
|
||||
|
||||
// Starts the burning sound if no other flames are playing the sound nearby.
|
||||
void CheckStartSound();
|
||||
|
||||
// Make the burning sound.
|
||||
void StartSound();
|
||||
void StopSound();
|
||||
|
||||
|
||||
private:
|
||||
|
||||
bool m_bSoundOn;
|
||||
float m_flPuddleSize;
|
||||
float m_flPuddleFade;
|
||||
|
||||
CSmartPtr<CGasolineEmitter> m_pEmitter;
|
||||
|
||||
float m_flLitStartTime;
|
||||
|
||||
float m_flCreateTime;
|
||||
float m_flMaxLifetime;
|
||||
|
||||
Vector m_vSurfaceNormal;
|
||||
|
||||
int m_BlobFlags; // Combination of BLOBFLAG_ defines.
|
||||
};
|
||||
|
||||
|
||||
#endif // C_GASOLINE_BLOB_H
|
||||
@@ -0,0 +1,84 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================//
|
||||
#include "cbase.h"
|
||||
#include "hud.h"
|
||||
#include "grenade_base_empable.h"
|
||||
#include "particles_simple.h"
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Client side entity for the antipersonnel grenades
|
||||
//-----------------------------------------------------------------------------
|
||||
class C_GrenadeAntiPersonnel : public C_BaseEMPableGrenade
|
||||
{
|
||||
DECLARE_CLASS( C_GrenadeAntiPersonnel, C_BaseEMPableGrenade );
|
||||
public:
|
||||
DECLARE_CLIENTCLASS();
|
||||
|
||||
C_GrenadeAntiPersonnel();
|
||||
|
||||
virtual void OnDataChanged( DataUpdateType_t updateType );
|
||||
virtual void ClientThink( void );
|
||||
|
||||
public:
|
||||
C_GrenadeAntiPersonnel( const C_GrenadeAntiPersonnel & );
|
||||
};
|
||||
|
||||
IMPLEMENT_CLIENTCLASS_DT(C_GrenadeAntiPersonnel, DT_GrenadeAntiPersonnel, CGrenadeAntiPersonnel)
|
||||
END_RECV_TABLE()
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
C_GrenadeAntiPersonnel::C_GrenadeAntiPersonnel( void )
|
||||
{
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void C_GrenadeAntiPersonnel::OnDataChanged( DataUpdateType_t updateType )
|
||||
{
|
||||
BaseClass::OnDataChanged( updateType );
|
||||
|
||||
// Only think when sapping
|
||||
SetNextClientThink( CLIENT_THINK_ALWAYS );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Spawn effects if I'm sapping
|
||||
//-----------------------------------------------------------------------------
|
||||
void C_GrenadeAntiPersonnel::ClientThink( void )
|
||||
{
|
||||
// Fire smoke puffs out the side
|
||||
CSmartPtr<CSimpleEmitter> pSmokeEmitter = CSimpleEmitter::Create( "AntipersonnelGrenade::Effect" );
|
||||
pSmokeEmitter->SetSortOrigin( GetAbsOrigin() );
|
||||
int iSmokeClouds = random->RandomInt(1,2);
|
||||
for ( int i = 0; i < iSmokeClouds; i++ )
|
||||
{
|
||||
SimpleParticle *pParticle = (SimpleParticle *) pSmokeEmitter->AddParticle( sizeof(SimpleParticle), g_Mat_DustPuff[1], GetAbsOrigin() );
|
||||
if ( pParticle == NULL )
|
||||
return;
|
||||
|
||||
pParticle->m_flLifetime = 0.0f;
|
||||
pParticle->m_flDieTime = random->RandomFloat( 0.1f, 0.3f );
|
||||
|
||||
pParticle->m_uchStartSize = random->RandomFloat(2,5);
|
||||
pParticle->m_uchEndSize = pParticle->m_uchStartSize + 2;
|
||||
|
||||
pParticle->m_vecVelocity = vec3_origin;
|
||||
pParticle->m_uchStartAlpha = 255;
|
||||
pParticle->m_uchEndAlpha = 64;
|
||||
pParticle->m_flRoll = random->RandomFloat( 180, 360 );
|
||||
pParticle->m_flRollDelta = random->RandomFloat( -1, 1 );
|
||||
|
||||
pParticle->m_uchColor[0] = 50;
|
||||
pParticle->m_uchColor[1] = 250;
|
||||
pParticle->m_uchColor[2] = 50;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,109 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================//
|
||||
#include "cbase.h"
|
||||
#include "basegrenade_shared.h"
|
||||
#include "minimap_trace.h"
|
||||
#include "particles_simple.h"
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Client side entity for the ferry target items
|
||||
//-----------------------------------------------------------------------------
|
||||
class C_LimpetMine : public C_BaseGrenade
|
||||
{
|
||||
DECLARE_CLASS( C_LimpetMine, C_BaseGrenade );
|
||||
public:
|
||||
DECLARE_CLIENTCLASS();
|
||||
DECLARE_MINIMAP_PANEL();
|
||||
|
||||
C_LimpetMine();
|
||||
|
||||
virtual void OnDataChanged( DataUpdateType_t updateType );
|
||||
virtual void ClientThink( void );
|
||||
|
||||
public:
|
||||
C_LimpetMine( const C_LimpetMine & );
|
||||
|
||||
private:
|
||||
bool m_bLive;
|
||||
};
|
||||
|
||||
IMPLEMENT_CLIENTCLASS_DT(C_LimpetMine, DT_LimpetMine, CLimpetMine)
|
||||
RecvPropInt(RECVINFO(m_bLive)),
|
||||
END_RECV_TABLE()
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
C_LimpetMine::C_LimpetMine( void )
|
||||
{
|
||||
CONSTRUCT_MINIMAP_PANEL( "minimap_limpet", MINIMAP_OBJECTS );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void C_LimpetMine::OnDataChanged( DataUpdateType_t updateType )
|
||||
{
|
||||
BaseClass::OnDataChanged( updateType );
|
||||
|
||||
// Only think when live
|
||||
if ( m_bLive )
|
||||
{
|
||||
SetNextClientThink( CLIENT_THINK_ALWAYS );
|
||||
}
|
||||
else
|
||||
{
|
||||
SetNextClientThink( CLIENT_THINK_NEVER );
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Spawn effects if I'm live
|
||||
//-----------------------------------------------------------------------------
|
||||
void C_LimpetMine::ClientThink( void )
|
||||
{
|
||||
if ( !InLocalTeam() )
|
||||
return;
|
||||
|
||||
Vector up;
|
||||
GetVectors( NULL, NULL, &up );
|
||||
up *= 8.0f;
|
||||
Vector vecOrg = GetAbsOrigin() + up;
|
||||
|
||||
// Make a single sprite
|
||||
CSmartPtr<CSimpleEmitter> pSmokeEmitter = CSimpleEmitter::Create( "C_LimpetMine::Effect" );
|
||||
pSmokeEmitter->SetSortOrigin( vecOrg );
|
||||
PMaterialHandle hSphereMaterial = g_Mat_DustPuff[0];
|
||||
SimpleParticle *pParticle = (SimpleParticle *) pSmokeEmitter->AddParticle( sizeof(SimpleParticle), hSphereMaterial, vecOrg );
|
||||
if ( pParticle == NULL )
|
||||
return;
|
||||
|
||||
pParticle->m_flLifetime = 0.0f;
|
||||
pParticle->m_flDieTime = 0.1f;
|
||||
pParticle->m_uchStartSize = RandomInt(4,6);
|
||||
pParticle->m_uchEndSize = pParticle->m_uchStartSize;
|
||||
pParticle->m_vecVelocity = vec3_origin;
|
||||
pParticle->m_uchStartAlpha = 255;
|
||||
pParticle->m_uchEndAlpha = 255;
|
||||
pParticle->m_flRoll = random->RandomFloat( 180, 360 );
|
||||
pParticle->m_flRollDelta = random->RandomFloat( -1, 1 );
|
||||
|
||||
if ( InLocalTeam() )
|
||||
{
|
||||
pParticle->m_uchColor[0] = 0;
|
||||
pParticle->m_uchColor[1] = 255;
|
||||
pParticle->m_uchColor[2] = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
pParticle->m_uchColor[0] = 255;
|
||||
pParticle->m_uchColor[1] = 50;
|
||||
pParticle->m_uchColor[2] = 50;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,82 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================//
|
||||
#include "cbase.h"
|
||||
#include "hud.h"
|
||||
#include "basegrenade_shared.h"
|
||||
#include "IEffects.h"
|
||||
#include "c_baseplayer.h"
|
||||
|
||||
extern ConVar lod_effect_distance;
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Client side entity for the ferry target items
|
||||
//-----------------------------------------------------------------------------
|
||||
class C_GrenadeObjectSapper : public C_BaseGrenade
|
||||
{
|
||||
DECLARE_CLASS( C_GrenadeObjectSapper, C_BaseGrenade );
|
||||
public:
|
||||
DECLARE_CLIENTCLASS();
|
||||
|
||||
C_GrenadeObjectSapper();
|
||||
|
||||
virtual void OnDataChanged( DataUpdateType_t updateType );
|
||||
virtual void ClientThink( void );
|
||||
|
||||
public:
|
||||
C_GrenadeObjectSapper( const C_GrenadeObjectSapper & );
|
||||
|
||||
bool m_bSapping;
|
||||
float m_flNextEffectTime;
|
||||
};
|
||||
|
||||
IMPLEMENT_CLIENTCLASS_DT(C_GrenadeObjectSapper, DT_GrenadeObjectSapper, CGrenadeObjectSapper)
|
||||
RecvPropInt(RECVINFO(m_bSapping)),
|
||||
END_RECV_TABLE()
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
C_GrenadeObjectSapper::C_GrenadeObjectSapper( void )
|
||||
{
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void C_GrenadeObjectSapper::OnDataChanged( DataUpdateType_t updateType )
|
||||
{
|
||||
BaseClass::OnDataChanged( updateType );
|
||||
|
||||
// Only think when sapping
|
||||
if ( m_bSapping )
|
||||
{
|
||||
SetNextClientThink( CLIENT_THINK_ALWAYS );
|
||||
m_flNextEffectTime = gpGlobals->curtime;
|
||||
}
|
||||
else
|
||||
{
|
||||
SetNextClientThink( CLIENT_THINK_NEVER );
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Spawn effects if I'm sapping
|
||||
//-----------------------------------------------------------------------------
|
||||
void C_GrenadeObjectSapper::ClientThink( void )
|
||||
{
|
||||
if ( m_flNextEffectTime < gpGlobals->curtime )
|
||||
{
|
||||
// Haxory LOD
|
||||
C_BasePlayer *pPlayer = C_BasePlayer::GetLocalPlayer();
|
||||
if ( (GetAbsOrigin() - pPlayer->GetAbsOrigin()).LengthSqr() < lod_effect_distance.GetFloat() )
|
||||
{
|
||||
g_pEffects->Sparks( GetAbsOrigin() );
|
||||
}
|
||||
|
||||
m_flNextEffectTime = gpGlobals->curtime + 0.3;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,83 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================//
|
||||
#include "cbase.h"
|
||||
#include "hud.h"
|
||||
#include "particles_simple.h"
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Client side entity for the antipersonnel grenades
|
||||
//-----------------------------------------------------------------------------
|
||||
class C_GrenadeRocket : public C_BaseAnimating
|
||||
{
|
||||
DECLARE_CLASS( C_GrenadeRocket, C_BaseAnimating );
|
||||
public:
|
||||
DECLARE_CLIENTCLASS();
|
||||
|
||||
C_GrenadeRocket();
|
||||
|
||||
virtual void OnDataChanged( DataUpdateType_t updateType );
|
||||
virtual void ClientThink( void );
|
||||
|
||||
public:
|
||||
C_GrenadeRocket( const C_GrenadeRocket & );
|
||||
};
|
||||
|
||||
IMPLEMENT_CLIENTCLASS_DT(C_GrenadeRocket, DT_GrenadeRocket, CGrenadeRocket)
|
||||
END_RECV_TABLE()
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
C_GrenadeRocket::C_GrenadeRocket( void )
|
||||
{
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void C_GrenadeRocket::OnDataChanged( DataUpdateType_t updateType )
|
||||
{
|
||||
BaseClass::OnDataChanged( updateType );
|
||||
|
||||
// Only think when sapping
|
||||
SetNextClientThink( CLIENT_THINK_ALWAYS );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Spawn effects if I'm sapping
|
||||
//-----------------------------------------------------------------------------
|
||||
void C_GrenadeRocket::ClientThink( void )
|
||||
{
|
||||
// Fire smoke puffs out the side
|
||||
CSmartPtr<CSimpleEmitter> pSmokeEmitter = CSimpleEmitter::Create( "C_GrenadeRocket::Effect" );
|
||||
pSmokeEmitter->SetSortOrigin( GetAbsOrigin() );
|
||||
int iSmokeClouds = random->RandomInt(1,2);
|
||||
for ( int i = 0; i < iSmokeClouds; i++ )
|
||||
{
|
||||
SimpleParticle *pParticle = (SimpleParticle *) pSmokeEmitter->AddParticle( sizeof(SimpleParticle), g_Mat_DustPuff[1], GetAbsOrigin() );
|
||||
if ( pParticle == NULL )
|
||||
return;
|
||||
|
||||
pParticle->m_flLifetime = 0.0f;
|
||||
pParticle->m_flDieTime = random->RandomFloat( 0.1f, 0.3f );
|
||||
|
||||
pParticle->m_uchStartSize = 10;
|
||||
pParticle->m_uchEndSize = pParticle->m_uchStartSize + 2;
|
||||
|
||||
pParticle->m_vecVelocity = GetAbsVelocity();
|
||||
pParticle->m_uchStartAlpha = 255;
|
||||
pParticle->m_uchEndAlpha = 64;
|
||||
pParticle->m_flRoll = random->RandomFloat( 180, 360 );
|
||||
pParticle->m_flRollDelta = random->RandomFloat( -1, 1 );
|
||||
|
||||
pParticle->m_uchColor[0] = 50;
|
||||
pParticle->m_uchColor[1] = 250;
|
||||
pParticle->m_uchColor[2] = 50;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,95 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================//
|
||||
#include "cbase.h"
|
||||
#include "hud.h"
|
||||
#include "particles_simple.h"
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Client side entity for the harpoon
|
||||
//-----------------------------------------------------------------------------
|
||||
class C_Harpoon : public C_BaseAnimating
|
||||
{
|
||||
DECLARE_CLASS( C_Harpoon, C_BaseAnimating );
|
||||
public:
|
||||
DECLARE_CLIENTCLASS();
|
||||
|
||||
C_Harpoon();
|
||||
|
||||
virtual void OnDataChanged( DataUpdateType_t updateType );
|
||||
virtual void GetAimEntOrigin( IClientEntity *pAttachedTo, Vector *pOrigin, QAngle *pAngles );
|
||||
|
||||
public:
|
||||
C_Harpoon( const C_Harpoon & );
|
||||
|
||||
private:
|
||||
// Impaling
|
||||
Vector m_vecOffset;
|
||||
QAngle m_angOffset;
|
||||
};
|
||||
|
||||
IMPLEMENT_CLIENTCLASS_DT(C_Harpoon, DT_Harpoon, CHarpoon)
|
||||
RecvPropVector( RECVINFO(m_vecOffset) ),
|
||||
RecvPropVector( RECVINFO(m_angOffset) ),
|
||||
END_RECV_TABLE()
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
C_Harpoon::C_Harpoon( void )
|
||||
{
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void C_Harpoon::OnDataChanged( DataUpdateType_t updateType )
|
||||
{
|
||||
BaseClass::OnDataChanged( updateType );
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Returns the attachment render origin + origin
|
||||
//-----------------------------------------------------------------------------
|
||||
void C_Harpoon::GetAimEntOrigin( IClientEntity *pAttachedTo, Vector *pOrigin, QAngle *pAngles )
|
||||
{
|
||||
C_BaseAnimating *pEnt = dynamic_cast< C_BaseAnimating * >( pAttachedTo->GetBaseEntity() );
|
||||
if (!pEnt)
|
||||
return;
|
||||
|
||||
float controllers[MAXSTUDIOBONES];
|
||||
pEnt->GetBoneControllers(controllers);
|
||||
|
||||
float headcontroller = controllers[ 0 ];
|
||||
|
||||
// Compute angles as well, since parent uses bone controller for rotation
|
||||
|
||||
// Convert 0 - 1 to angles
|
||||
float renderYaw = -180.0f + 360.0f * headcontroller;
|
||||
|
||||
matrix3x4_t matrix;
|
||||
|
||||
// Convert roll/pitch only to matrix
|
||||
AngleMatrix( pEnt->GetAbsAngles(), matrix );
|
||||
|
||||
// Convert desired yaw to vector
|
||||
QAngle anglesRotated( 0, renderYaw, 0 );
|
||||
Vector forward;
|
||||
AngleVectors( anglesRotated, &forward );
|
||||
|
||||
Vector rotatedForward;
|
||||
|
||||
// Rotate desired yaw vector by roll/pitch matrix
|
||||
VectorRotate( forward, matrix, rotatedForward );
|
||||
|
||||
// Convert rotated vector back to orientation
|
||||
VectorAngles( rotatedForward, *pAngles );
|
||||
//*pAngles -= m_angOffset;
|
||||
|
||||
// HACK: Until we have a proper bone solution, hack the origin for all moving objects
|
||||
*pOrigin = pEnt->WorldSpaceCenter( );
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================//
|
||||
#include "cbase.h"
|
||||
#include "c_hint_events.h"
|
||||
#include "c_tf_hints.h"
|
||||
#include "c_tf_hintmanager.h"
|
||||
#include <KeyValues.h>
|
||||
#include "c_baseobject.h"
|
||||
|
||||
|
||||
void GlobalHintEvent( C_HintEvent_Base *pEvent )
|
||||
{
|
||||
// Call the static registered functions for each hint type.
|
||||
for ( int i=0; i < GetNumHintDatas(); i++ )
|
||||
{
|
||||
CHintData *pData = GetHintData( i );
|
||||
if ( pData && pData->m_pEventFn )
|
||||
pData->m_pEventFn( pData, pEvent );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void HintEventFn_BuildObject( CHintData *pData, C_HintEvent_Base *pEvent )
|
||||
{
|
||||
if ( pEvent->GetType() == HINTEVENT_OBJECT_BUILT_BY_LOCAL_PLAYER )
|
||||
{
|
||||
C_BaseObject *pObj = ((C_HintEvent_ObjectBuiltByLocalPlayer*)pEvent)->m_pObject;
|
||||
|
||||
if ( pObj->GetType() == pData->m_ObjectType )
|
||||
{
|
||||
// Ok, they just built the object that any hints of this type are referring to, so disable
|
||||
// all further hints of this type.
|
||||
KeyValues *pkvStats = GetHintDisplayStats();
|
||||
if ( pkvStats )
|
||||
{
|
||||
KeyValues *pkvStatSection = pkvStats->FindKey( pData->name, true );
|
||||
if ( pkvStatSection )
|
||||
{
|
||||
pkvStatSection->SetString( "times_shown", VarArgs( "%i", 100 ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,62 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================//
|
||||
|
||||
#ifndef C_HINT_EVENTS_H
|
||||
#define C_HINT_EVENTS_H
|
||||
#ifdef _WIN32
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
|
||||
class CHintData;
|
||||
|
||||
|
||||
typedef enum
|
||||
{
|
||||
HINTEVENT_OBJECT_BUILT_BY_LOCAL_PLAYER=0 // C_HintEvent_ObjectBuiltByLocalPlayer
|
||||
} HintEventType;
|
||||
|
||||
|
||||
// All hint events derive from this.
|
||||
class C_HintEvent_Base
|
||||
{
|
||||
public:
|
||||
// Find out what kind of event this is.
|
||||
virtual HintEventType GetType() = 0;
|
||||
};
|
||||
|
||||
|
||||
// Fire a global hint event. It goes to all hint types so they can determine if
|
||||
// they want to react.
|
||||
void GlobalHintEvent( C_HintEvent_Base *pEvent );
|
||||
|
||||
|
||||
// Hint callbacks for each type of hint.
|
||||
void HintEventFn_BuildObject( CHintData *pData, C_HintEvent_Base *pEvent );
|
||||
|
||||
|
||||
|
||||
// This notifies the hint system that an object has been built by the local player so
|
||||
// it can disable all further hints referring to objects of this type.
|
||||
class C_BaseObject;
|
||||
|
||||
class C_HintEvent_ObjectBuiltByLocalPlayer : public C_HintEvent_Base
|
||||
{
|
||||
public:
|
||||
C_HintEvent_ObjectBuiltByLocalPlayer( C_BaseObject *pObj )
|
||||
{
|
||||
m_pObject = pObj;
|
||||
}
|
||||
|
||||
virtual HintEventType GetType() { return HINTEVENT_OBJECT_BUILT_BY_LOCAL_PLAYER; }
|
||||
|
||||
public:
|
||||
C_BaseObject *m_pObject; // The object just built.
|
||||
};
|
||||
|
||||
|
||||
#endif // C_HINT_EVENTS_H
|
||||
@@ -0,0 +1,196 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
//=============================================================================//
|
||||
#include "cbase.h"
|
||||
#include "tf_shareddefs.h"
|
||||
#include "c_info_act.h"
|
||||
#include "hud_timer.h"
|
||||
|
||||
// memdbgon must be the last include file in a .cpp file!!!
|
||||
#include "tier0/memdbgon.h"
|
||||
|
||||
// We may get act begin messages for acts we haven't yet received entities for (usually during connection)
|
||||
// We store the current act in this, and if an act arrives matching it, we start that act.
|
||||
static int g_iCurrentActNumber = -1;
|
||||
static float g_flActStartTime;
|
||||
|
||||
CHandle<C_InfoAct> g_hCurrentAct;
|
||||
|
||||
IMPLEMENT_CLIENTCLASS_DT(C_InfoAct, DT_InfoAct, CInfoAct)
|
||||
RecvPropInt( RECVINFO(m_iActNumber) ),
|
||||
RecvPropInt( RECVINFO(m_spawnflags) ),
|
||||
RecvPropFloat( RECVINFO(m_flActTimeLimit) ),
|
||||
RecvPropInt(RECVINFO(m_nRespawn1Team1Time) ),
|
||||
RecvPropInt(RECVINFO(m_nRespawn1Team2Time) ),
|
||||
RecvPropInt(RECVINFO(m_nRespawn2Team1Time) ),
|
||||
RecvPropInt(RECVINFO(m_nRespawn2Team2Time) ),
|
||||
RecvPropInt(RECVINFO(m_nRespawnTeam1Delay) ),
|
||||
RecvPropInt(RECVINFO(m_nRespawnTeam2Delay) ),
|
||||
END_RECV_TABLE()
|
||||
|
||||
typedef CHandle<C_InfoAct> ActHandle_t;
|
||||
CUtlVector< ActHandle_t > g_hActs;
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
C_InfoAct::C_InfoAct()
|
||||
{
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
C_InfoAct::~C_InfoAct()
|
||||
{
|
||||
ActHandle_t hAct;
|
||||
hAct = this;
|
||||
g_hActs.FindAndRemove( hAct );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void C_InfoAct::OnPreDataChanged( DataUpdateType_t updateType )
|
||||
{
|
||||
BaseClass::OnPreDataChanged( updateType );
|
||||
m_flPreviousTimeLimit = m_flActTimeLimit;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void C_InfoAct::OnDataChanged( DataUpdateType_t updateType )
|
||||
{
|
||||
ActHandle_t hAct;
|
||||
hAct = this;
|
||||
if ( g_hActs.Find( hAct ) == g_hActs.InvalidIndex() )
|
||||
{
|
||||
g_hActs.AddToTail( hAct );
|
||||
|
||||
// Is this act the one that's supposed to be going?
|
||||
if ( GetActNumber() == g_iCurrentActNumber )
|
||||
{
|
||||
StartAct( g_flActStartTime );
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Timer changed?
|
||||
if ( g_hCurrentAct == this )
|
||||
{
|
||||
if ( m_flPreviousTimeLimit != m_flActTimeLimit )
|
||||
{
|
||||
CHudTimer *timer = GET_HUDELEMENT( CHudTimer );
|
||||
if ( timer )
|
||||
{
|
||||
timer->SetFixedTimer( m_flStartTime, m_flActTimeLimit );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
BaseClass::OnDataChanged( updateType );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void C_InfoAct::StartAct( float flStartTime )
|
||||
{
|
||||
g_hCurrentAct = this;
|
||||
m_flStartTime = flStartTime;
|
||||
|
||||
CHudTimer *timer = GET_HUDELEMENT( CHudTimer );
|
||||
if ( timer )
|
||||
{
|
||||
timer->SetFixedTimer( m_flStartTime, m_flActTimeLimit );
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
bool C_InfoAct::IsAWaitingAct( void )
|
||||
{
|
||||
return (m_spawnflags & SF_ACT_WAITINGFORGAMESTART) != 0;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// PReturns the respawn time remaining
|
||||
//-----------------------------------------------------------------------------
|
||||
float C_InfoAct::RespawnTimeRemaining( int nTeam, int nTimer ) const
|
||||
{
|
||||
if ((g_hCurrentAct != this) || (nTeam == 0))
|
||||
return 0;
|
||||
|
||||
int nTimerTime;
|
||||
float flTimeDelta = gpGlobals->curtime - m_flStartTime;
|
||||
if (flTimeDelta <= 0)
|
||||
return 0;
|
||||
|
||||
if (nTeam == 1)
|
||||
{
|
||||
nTimerTime = (nTimer == 1) ? m_nRespawn1Team1Time : m_nRespawn2Team1Time;
|
||||
flTimeDelta -= m_nRespawnTeam1Delay;
|
||||
}
|
||||
else
|
||||
{
|
||||
nTimerTime = (nTimer == 1) ? m_nRespawn1Team2Time : m_nRespawn2Team2Time;
|
||||
flTimeDelta -= m_nRespawnTeam2Delay;
|
||||
}
|
||||
|
||||
if (nTimerTime <= 0)
|
||||
return 0.0f;
|
||||
|
||||
// This case takes care of the initial spawn delay time...
|
||||
if (flTimeDelta < 0)
|
||||
{
|
||||
return nTimerTime - flTimeDelta;
|
||||
}
|
||||
|
||||
int nFactor = flTimeDelta / nTimerTime;
|
||||
return nTimerTime - (flTimeDelta - nFactor * nTimerTime);
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Server's told us to start an act
|
||||
//-----------------------------------------------------------------------------
|
||||
void StartAct( int iActNumber, float flStartTime )
|
||||
{
|
||||
g_iCurrentActNumber = iActNumber;
|
||||
g_flActStartTime = flStartTime;
|
||||
|
||||
// Find the act
|
||||
for ( int i = 0; i < g_hActs.Size(); i++ )
|
||||
{
|
||||
if ( g_hActs[i] && g_hActs[i]->GetActNumber() == iActNumber )
|
||||
{
|
||||
g_hActs[i]->StartAct( flStartTime );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
int GetCurrentActNumber( void )
|
||||
{
|
||||
if ( g_hCurrentAct )
|
||||
return g_hCurrentAct->GetActNumber();
|
||||
return ACT_NONE_SPECIFIED;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Return true if the current act (if any) is a waiting act.
|
||||
//-----------------------------------------------------------------------------
|
||||
bool CurrentActIsAWaitingAct( void )
|
||||
{
|
||||
if ( g_hCurrentAct )
|
||||
return g_hCurrentAct->IsAWaitingAct();
|
||||
|
||||
return false;
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
//=============================================================================//
|
||||
|
||||
#ifndef C_INFO_ACT_H
|
||||
#define C_INFO_ACT_H
|
||||
#ifdef _WIN32
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#define ACT_NONE_SPECIFIED -1
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Map entity that defines an act
|
||||
//-----------------------------------------------------------------------------
|
||||
class C_InfoAct : public C_BaseEntity
|
||||
{
|
||||
DECLARE_CLASS( C_InfoAct, C_BaseEntity );
|
||||
public:
|
||||
C_InfoAct();
|
||||
~C_InfoAct();
|
||||
|
||||
DECLARE_CLIENTCLASS();
|
||||
|
||||
virtual void OnPreDataChanged( DataUpdateType_t updateType );
|
||||
virtual void OnDataChanged( DataUpdateType_t updateType );
|
||||
|
||||
void StartAct( float flStartTime );
|
||||
|
||||
int GetActNumber( void ) { return m_iActNumber; }
|
||||
bool IsAWaitingAct( void );
|
||||
|
||||
float RespawnTimeRemaining( int nTeam, int nTimer ) const;
|
||||
|
||||
private:
|
||||
int m_iActNumber;
|
||||
int m_spawnflags;
|
||||
float m_flActTimeLimit;
|
||||
int m_nRespawn1Team1Time;
|
||||
int m_nRespawn1Team2Time;
|
||||
int m_nRespawn2Team1Time;
|
||||
int m_nRespawn2Team2Time;
|
||||
int m_nRespawnTeam1Delay;
|
||||
int m_nRespawnTeam2Delay;
|
||||
float m_flStartTime;
|
||||
float m_flPreviousTimeLimit;
|
||||
};
|
||||
|
||||
extern CHandle<C_InfoAct> g_hCurrentAct;
|
||||
void StartAct( int iActNumber, float flStartTime );
|
||||
int GetCurrentActNumber( void );
|
||||
bool CurrentActIsAWaitingAct( void );
|
||||
|
||||
#endif // C_INFO_ACT_H
|
||||
@@ -0,0 +1,51 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================//
|
||||
#include "cbase.h"
|
||||
#include "hud_technologytreedoc.h"
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
class C_InfoCustomTechnology : public C_BaseEntity
|
||||
{
|
||||
DECLARE_CLASS( C_InfoCustomTechnology, C_BaseEntity );
|
||||
public:
|
||||
DECLARE_CLIENTCLASS();
|
||||
|
||||
C_InfoCustomTechnology( void );
|
||||
virtual void SetDormant( bool bDormant );
|
||||
|
||||
public:
|
||||
// Sent via datatable
|
||||
char m_szTechTreeFile[128];
|
||||
};
|
||||
|
||||
IMPLEMENT_CLIENTCLASS_DT(C_InfoCustomTechnology, DT_InfoCustomTechnology, CInfoCustomTechnology)
|
||||
RecvPropString(RECVINFO(m_szTechTreeFile)),
|
||||
END_RECV_TABLE()
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
C_InfoCustomTechnology::C_InfoCustomTechnology( void )
|
||||
{
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Whenever we enter the PVS, add ourselves to the tech tree. This will
|
||||
// only happen when the player joins a new team.
|
||||
//-----------------------------------------------------------------------------
|
||||
void C_InfoCustomTechnology::SetDormant( bool bDormant )
|
||||
{
|
||||
if ( IsDormant() && !bDormant )
|
||||
{
|
||||
// Tell the techtree to add the file to it's list of technologies
|
||||
GetTechnologyTreeDoc().AddTechnologyFile( m_szTechTreeFile );
|
||||
}
|
||||
|
||||
BaseClass::SetDormant( bDormant );
|
||||
}
|
||||
@@ -0,0 +1,109 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================//
|
||||
#include "cbase.h"
|
||||
#include "hud.h"
|
||||
#include "c_ai_basenpc.h"
|
||||
#include "IEffects.h"
|
||||
#include "particles_simple.h"
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Client side entity for the NPC Bug hole
|
||||
//-----------------------------------------------------------------------------
|
||||
class C_Maker_Bughole : public C_BaseEntity
|
||||
{
|
||||
DECLARE_CLASS( C_Maker_Bughole, C_BaseEntity );
|
||||
public:
|
||||
DECLARE_CLIENTCLASS();
|
||||
|
||||
C_Maker_Bughole();
|
||||
|
||||
virtual void OnDataChanged( DataUpdateType_t updateType );
|
||||
virtual void ClientThink( void );
|
||||
void SpawnEffect( void );
|
||||
|
||||
public:
|
||||
C_Maker_Bughole( const C_Maker_Bughole & );
|
||||
|
||||
float m_flNextEffectTime;
|
||||
};
|
||||
|
||||
IMPLEMENT_CLIENTCLASS_DT(C_Maker_Bughole, DT_Maker_Bughole, CMaker_Bughole)
|
||||
END_RECV_TABLE()
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
C_Maker_Bughole::C_Maker_Bughole( void )
|
||||
{
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void C_Maker_Bughole::OnDataChanged( DataUpdateType_t updateType )
|
||||
{
|
||||
BaseClass::OnDataChanged( updateType );
|
||||
|
||||
if ( updateType == DATA_UPDATE_CREATED )
|
||||
{
|
||||
SetNextClientThink( CLIENT_THINK_ALWAYS );
|
||||
m_flNextEffectTime = gpGlobals->curtime;
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Spawn effects if I'm sapping
|
||||
//-----------------------------------------------------------------------------
|
||||
void C_Maker_Bughole::ClientThink( void )
|
||||
{
|
||||
if ( m_flNextEffectTime < gpGlobals->curtime )
|
||||
{
|
||||
SpawnEffect();
|
||||
m_flNextEffectTime = gpGlobals->curtime + random->RandomFloat( 0.5, 1.0 );
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Particle effects created when we spawn a chunk
|
||||
//-----------------------------------------------------------------------------
|
||||
void C_Maker_Bughole::SpawnEffect( void )
|
||||
{
|
||||
Vector normal = Vector(0,0,-1);
|
||||
Vector offset = GetAbsOrigin() + (normal * 16);
|
||||
Vector dir;
|
||||
|
||||
// Create a couple of big, floating smoke clouds
|
||||
CSmartPtr<CSimpleEmitter> pSmokeEmitter = CSimpleEmitter::Create( "C_Maker_Bughole::SpawnEffect" );
|
||||
pSmokeEmitter->SetSortOrigin( offset );
|
||||
int iSmokeClouds = random->RandomInt(2,5);
|
||||
for ( int i = 0; i < iSmokeClouds; i++ )
|
||||
{
|
||||
SimpleParticle *pParticle = (SimpleParticle *) pSmokeEmitter->AddParticle( sizeof(SimpleParticle), g_Mat_DustPuff[1], offset );
|
||||
if ( pParticle == NULL )
|
||||
return;
|
||||
|
||||
pParticle->m_flLifetime = 0.0f;
|
||||
pParticle->m_flDieTime = random->RandomFloat( 2.0f, 3.0f );
|
||||
|
||||
pParticle->m_uchStartSize = 8;
|
||||
pParticle->m_uchEndSize = 48;
|
||||
|
||||
dir[0] = normal[0] + random->RandomFloat( -0.4f, 0.4f );
|
||||
dir[1] = normal[1] + random->RandomFloat( -0.4f, 0.4f );
|
||||
dir[2] = normal[2] + random->RandomFloat( 0, 0.6f );
|
||||
pParticle->m_vecVelocity = dir * random->RandomFloat( 8.0f, 20.0f )*(i+1);
|
||||
pParticle->m_uchStartAlpha = 255;
|
||||
pParticle->m_uchEndAlpha = 0;
|
||||
pParticle->m_flRoll = random->RandomFloat( 180, 360 );
|
||||
pParticle->m_flRollDelta = random->RandomFloat( -1, 1 );
|
||||
|
||||
float flColor = random->RandomFloat( 0,64 );
|
||||
pParticle->m_uchColor[0] = 100 + flColor;
|
||||
pParticle->m_uchColor[1] = 50 + flColor;
|
||||
pParticle->m_uchColor[2] = flColor;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,110 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
//=============================================================================//
|
||||
|
||||
#include "cbase.h"
|
||||
#include "c_obj_barbed_wire.h"
|
||||
|
||||
|
||||
IMPLEMENT_CLIENTCLASS_DT( C_ObjectBarbedWire, DT_ObjectBarbedWire, CObjectBarbedWire )
|
||||
RecvPropEHandle( RECVINFO( m_hConnectedTo ) )
|
||||
END_RECV_TABLE()
|
||||
|
||||
|
||||
ConVar obj_barbed_wire_hang_dist( "obj_barbed_wire_hang_dist", "20" );
|
||||
|
||||
|
||||
C_ObjectBarbedWire::C_ObjectBarbedWire()
|
||||
{
|
||||
m_vLastConnectedOrigin.Init( -999999999, -999999999, -999999999 );
|
||||
m_vLastOrigin = m_vLastConnectedOrigin;
|
||||
}
|
||||
|
||||
|
||||
C_ObjectBarbedWire::~C_ObjectBarbedWire()
|
||||
{
|
||||
// Get rid of our rope if necessary.
|
||||
if ( m_hRope )
|
||||
{
|
||||
m_hRope->Release();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void C_ObjectBarbedWire::OnDataChanged( DataUpdateType_t type )
|
||||
{
|
||||
if ( m_hConnectedTo != m_hLastConnectedTo )
|
||||
{
|
||||
m_hLastConnectedTo = m_hConnectedTo;
|
||||
|
||||
// Get rid of any old rope we had.
|
||||
int iAttachment = LookupAttachment( "wire_attachment" );
|
||||
|
||||
// Create or delete our rope?
|
||||
if ( m_hConnectedTo )
|
||||
{
|
||||
if ( !m_hRope )
|
||||
{
|
||||
|
||||
m_hRope = C_RopeKeyframe::Create(
|
||||
this,
|
||||
m_hConnectedTo,
|
||||
iAttachment,
|
||||
iAttachment,
|
||||
3,
|
||||
"sprites/physbeam"
|
||||
);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( m_hRope )
|
||||
{
|
||||
m_hRope->Release();
|
||||
m_hRope = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
// Update rope parameters.
|
||||
if ( m_hRope )
|
||||
{
|
||||
int r, g, b, a;
|
||||
CMapTeamColors *team = &MapData().m_TeamColors[ GetTeamNumber() ];
|
||||
team->m_clrTeam.GetColor( r, g, b, a );
|
||||
m_hRope->SetColorMod( Vector( r / 255.0f, g / 255.0f, b / 255.0f ) );
|
||||
|
||||
m_hRope->SetEndEntity( m_hConnectedTo );
|
||||
m_hRope->SetRopeFlags( ROPE_SIMULATE | ROPE_BARBED );
|
||||
}
|
||||
}
|
||||
|
||||
BaseClass::OnDataChanged( type );
|
||||
}
|
||||
|
||||
|
||||
void C_ObjectBarbedWire::Spawn()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void C_ObjectBarbedWire::ClientThink()
|
||||
{
|
||||
if ( m_hConnectedTo && m_hRope )
|
||||
{
|
||||
if ( m_vLastOrigin != GetAbsOrigin() || m_vLastConnectedOrigin != m_hConnectedTo->GetAbsOrigin() )
|
||||
{
|
||||
m_hRope->SetupHangDistance( obj_barbed_wire_hang_dist.GetFloat() );
|
||||
|
||||
m_vLastOrigin = GetAbsOrigin();
|
||||
m_vLastConnectedOrigin = m_hConnectedTo->GetAbsOrigin();
|
||||
}
|
||||
}
|
||||
|
||||
SetNextClientThink( gpGlobals->curtime + 0.1f );
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,46 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
//=============================================================================//
|
||||
|
||||
#ifndef C_OBJ_BARBED_WIRE_H
|
||||
#define C_OBJ_BARBED_WIRE_H
|
||||
#ifdef _WIN32
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
|
||||
#include "c_baseobject.h"
|
||||
#include "c_rope.h"
|
||||
|
||||
|
||||
class C_ObjectBarbedWire : public C_BaseObject
|
||||
{
|
||||
public:
|
||||
DECLARE_CLASS( C_ObjectBarbedWire, C_BaseObject );
|
||||
DECLARE_CLIENTCLASS();
|
||||
|
||||
C_ObjectBarbedWire();
|
||||
~C_ObjectBarbedWire();
|
||||
|
||||
virtual void OnDataChanged( DataUpdateType_t type );
|
||||
|
||||
virtual void Spawn();
|
||||
virtual void ClientThink();
|
||||
|
||||
|
||||
private:
|
||||
C_ObjectBarbedWire( C_ObjectBarbedWire& ) {}
|
||||
|
||||
CHandle<C_ObjectBarbedWire> m_hConnectedTo;
|
||||
CHandle<C_ObjectBarbedWire> m_hLastConnectedTo;
|
||||
CHandle<C_RopeKeyframe> m_hRope;
|
||||
|
||||
// Used to determine when to recalculate the hang distance.
|
||||
Vector m_vLastOrigin;
|
||||
Vector m_vLastConnectedOrigin;
|
||||
};
|
||||
|
||||
|
||||
#endif // C_OBJ_BARBED_WIRE_H
|
||||
@@ -0,0 +1,122 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================//
|
||||
#include "cbase.h"
|
||||
#include "c_obj_base_manned_gun.h"
|
||||
#include "hudelement.h"
|
||||
#include "tf_movedata.h"
|
||||
#include "bone_setup.h"
|
||||
#include "hud_ammo.h"
|
||||
#include "vgui_bitmapbutton.h"
|
||||
|
||||
extern ConVar mannedgun_usethirdperson;
|
||||
|
||||
//=================================================================================================
|
||||
// Control Screen
|
||||
//=================================================================================================
|
||||
|
||||
DECLARE_VGUI_SCREEN_FACTORY( CMannedPlasmagunControlPanel, "manned_plasmagun_control_panel" );
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Constructor:
|
||||
//-----------------------------------------------------------------------------
|
||||
CMannedPlasmagunControlPanel::CMannedPlasmagunControlPanel( vgui::Panel *parent, const char *panelName )
|
||||
: BaseClass( parent, "CMannedPlasmagunControlPanel" )
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Initialization
|
||||
//-----------------------------------------------------------------------------
|
||||
bool CMannedPlasmagunControlPanel::Init( KeyValues* pKeyValues, VGuiScreenInitData_t* pInitData )
|
||||
{
|
||||
m_pMannedLabel = new vgui::Label( this, "MannedReadout", "" );
|
||||
m_pOccupyButton = new CBitmapButton( this, "OccupyButton", "Occupy" );
|
||||
|
||||
if (!BaseClass::Init(pKeyValues, pInitData))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Frame-based update
|
||||
//-----------------------------------------------------------------------------
|
||||
void CMannedPlasmagunControlPanel::OnTick()
|
||||
{
|
||||
BaseClass::OnTick();
|
||||
|
||||
C_BaseObject *pObj = GetOwningObject();
|
||||
if (!pObj)
|
||||
return;
|
||||
|
||||
Assert( dynamic_cast<C_ObjectBaseMannedGun*>(pObj) );
|
||||
C_ObjectBaseMannedGun *pGun = static_cast<C_ObjectBaseMannedGun*>(pObj);
|
||||
|
||||
char buf[256];
|
||||
// Update the currently manned player label
|
||||
if ( pGun->GetDriverPlayer() )
|
||||
{
|
||||
Q_snprintf( buf, sizeof( buf ), "Manned by %s", pGun->GetDriverPlayer()->GetPlayerName() );
|
||||
m_pMannedLabel->SetText( buf );
|
||||
m_pMannedLabel->SetVisible( true );
|
||||
}
|
||||
else
|
||||
{
|
||||
m_pMannedLabel->SetVisible( false );
|
||||
}
|
||||
|
||||
// Update the get in button
|
||||
if ( pGun->GetDriverPlayer() )
|
||||
{
|
||||
// Owners can boot other players to get in
|
||||
if ( pGun->GetOwner() == C_BaseTFPlayer::GetLocalPlayer() && C_BaseTFPlayer::GetLocalPlayer() != pGun->GetDriverPlayer() )
|
||||
{
|
||||
Q_snprintf( buf, sizeof( buf ), "Get In (Ejecting %s)", pGun->GetDriverPlayer()->GetPlayerName() );
|
||||
m_pMannedLabel->SetText( buf );
|
||||
m_pOccupyButton->SetEnabled( true );
|
||||
}
|
||||
else
|
||||
{
|
||||
// Disable the button
|
||||
m_pOccupyButton->SetEnabled( false );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
m_pOccupyButton->SetText( "Get In" );
|
||||
m_pOccupyButton->SetEnabled( true );
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Handle clicking on the Occupy button
|
||||
//-----------------------------------------------------------------------------
|
||||
void CMannedPlasmagunControlPanel::GetInGun( void )
|
||||
{
|
||||
C_BaseObject *pObj = GetOwningObject();
|
||||
if (pObj)
|
||||
{
|
||||
pObj->SendClientCommand( "toggle_use" );
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Button click handlers
|
||||
//-----------------------------------------------------------------------------
|
||||
void CMannedPlasmagunControlPanel::OnCommand( const char *command )
|
||||
{
|
||||
if (!Q_strnicmp(command, "Occupy", 7))
|
||||
{
|
||||
GetInGun();
|
||||
return;
|
||||
}
|
||||
|
||||
BaseClass::OnCommand(command);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,39 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
//=============================================================================//
|
||||
|
||||
#ifndef C_OBJ_BASE_MANNED_GUN_H
|
||||
#define C_OBJ_BASE_MANNED_GUN_H
|
||||
#ifdef _WIN32
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include "basetfvehicle.h"
|
||||
#include "tf_obj_manned_plasmagun_shared.h"
|
||||
#include "ObjectControlPanel.h"
|
||||
#include "tf_obj_base_manned_gun.h"
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Control screen
|
||||
//-----------------------------------------------------------------------------
|
||||
class CMannedPlasmagunControlPanel : public CRotatingObjectControlPanel
|
||||
{
|
||||
DECLARE_CLASS( CMannedPlasmagunControlPanel, CRotatingObjectControlPanel );
|
||||
|
||||
public:
|
||||
CMannedPlasmagunControlPanel( vgui::Panel *parent, const char *panelName );
|
||||
virtual bool Init( KeyValues* pKeyValues, VGuiScreenInitData_t* pInitData );
|
||||
virtual void OnTick();
|
||||
virtual void OnCommand( const char *command );
|
||||
|
||||
void GetInGun( void );
|
||||
|
||||
private:
|
||||
vgui::Label *m_pMannedLabel;
|
||||
vgui::Button *m_pOccupyButton;
|
||||
};
|
||||
|
||||
#endif // C_OBJ_BASE_MANNED_GUN_H
|
||||
@@ -0,0 +1,272 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose: The client-side version of the portable power generator
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================//
|
||||
#include "cbase.h"
|
||||
#include "c_baseobject.h"
|
||||
#include "tf_shareddefs.h"
|
||||
#include "C_BaseTFPlayer.h"
|
||||
#include "ObjectControlPanel.h"
|
||||
#include "vgui_bitmapbutton.h"
|
||||
|
||||
// memdbgon must be the last include file in a .cpp file!!!
|
||||
#include "tier0/memdbgon.h"
|
||||
|
||||
//=============================================================================
|
||||
//
|
||||
// Portable Power Generator Class
|
||||
//
|
||||
class C_ObjectBuffStation : public C_BaseObject
|
||||
{
|
||||
DECLARE_CLASS( C_ObjectBuffStation, C_BaseObject );
|
||||
|
||||
public:
|
||||
|
||||
DECLARE_CLIENTCLASS();
|
||||
|
||||
C_ObjectBuffStation( void );
|
||||
|
||||
virtual void Release( void );
|
||||
virtual void OnPreDataChanged( DataUpdateType_t updateType );
|
||||
virtual void OnDataChanged( DataUpdateType_t updateType );
|
||||
|
||||
// Since we have material proxies to show building amount, don't offset origin
|
||||
virtual bool OffsetObjectOrigin( Vector& origin )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
int PlayerSocketsLeft() const { return ( BUFF_STATION_MAX_PLAYERS - m_nPlayerCount ); }
|
||||
int ObjectSocketsLeft() const { return ( BUFF_STATION_MAX_OBJECTS - m_nObjectCount ); }
|
||||
|
||||
// Check if the local player is attached
|
||||
bool IsLocalPlayerAttached( void );
|
||||
|
||||
private:
|
||||
typedef CHandle<C_BaseTFPlayer> CPlayerHandle;
|
||||
int m_nPlayerCount;
|
||||
CPlayerHandle m_hPlayers[BUFF_STATION_MAX_PLAYERS];
|
||||
CPlayerHandle m_hOldPlayers[BUFF_STATION_MAX_PLAYERS];
|
||||
|
||||
typedef CHandle<C_BaseObject> CObjectHandle;
|
||||
int m_nObjectCount;
|
||||
CObjectHandle m_hObjects[BUFF_STATION_MAX_OBJECTS];
|
||||
|
||||
private:
|
||||
C_ObjectBuffStation( const C_ObjectBuffStation & ); // not defined, not accessible
|
||||
};
|
||||
|
||||
|
||||
IMPLEMENT_CLIENTCLASS_DT( C_ObjectBuffStation, DT_ObjectBuffStation, CObjectBuffStation )
|
||||
RecvPropInt( RECVINFO( m_nPlayerCount ) ),
|
||||
RecvPropArray( RecvPropEHandle( RECVINFO( m_hPlayers[0]) ), m_hPlayers ),
|
||||
RecvPropInt( RECVINFO( m_nObjectCount ) ),
|
||||
RecvPropArray( RecvPropEHandle( RECVINFO( m_hObjects[0]) ), m_hObjects ),
|
||||
END_RECV_TABLE()
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
C_ObjectBuffStation::C_ObjectBuffStation( void )
|
||||
{
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Check if the local player is attached
|
||||
//-----------------------------------------------------------------------------
|
||||
bool C_ObjectBuffStation::IsLocalPlayerAttached( void )
|
||||
{
|
||||
C_BaseTFPlayer *pLocalPlayer = C_BaseTFPlayer::GetLocalPlayer();
|
||||
for ( int iPlayer = 0; iPlayer < m_nPlayerCount; ++iPlayer )
|
||||
{
|
||||
if ( m_hPlayers[iPlayer].Get() == pLocalPlayer )
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void C_ObjectBuffStation::Release( void )
|
||||
{
|
||||
// Remove any sounds for players attached
|
||||
for ( int i = 0; i < BUFF_STATION_MAX_PLAYERS; i++ )
|
||||
{
|
||||
if ( m_hPlayers[i] )
|
||||
{
|
||||
// Stop the startup, in case it's still going
|
||||
StopSound( m_hPlayers[i]->entindex(), "ObjectPortablePowerGenerator.Startup" );
|
||||
|
||||
// Start the shutdown sound
|
||||
CPASAttenuationFilter filter( m_hPlayers[i], "ObjectPortablePowerGenerator.Shutdown" );
|
||||
EmitSound( filter, m_hPlayers[i]->entindex(), "ObjectPortablePowerGenerator.Shutdown" );
|
||||
}
|
||||
}
|
||||
|
||||
BaseClass::Release();
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void C_ObjectBuffStation::OnPreDataChanged( DataUpdateType_t updateType )
|
||||
{
|
||||
BaseClass::OnPreDataChanged( updateType );
|
||||
|
||||
for ( int i = 0; i < BUFF_STATION_MAX_PLAYERS; i++ )
|
||||
{
|
||||
m_hOldPlayers[i] = m_hPlayers[i];
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void C_ObjectBuffStation::OnDataChanged( DataUpdateType_t updateType )
|
||||
{
|
||||
BaseClass::OnDataChanged( updateType );
|
||||
|
||||
// Did a player connect / disconnect?
|
||||
for ( int i = 0; i < BUFF_STATION_MAX_PLAYERS; i++ )
|
||||
{
|
||||
// Something's changed
|
||||
if ( m_hOldPlayers[i] != m_hPlayers[i] )
|
||||
{
|
||||
// Disconnected?
|
||||
if ( m_hOldPlayers[i] )
|
||||
{
|
||||
// Stop the startup, in case it's still going
|
||||
StopSound( m_hOldPlayers[i]->entindex(), "ObjectPortablePowerGenerator.Startup" );
|
||||
|
||||
// Start the shutdown sound
|
||||
CPASAttenuationFilter filter( m_hOldPlayers[i], "ObjectPortablePowerGenerator.Shutdown" );
|
||||
EmitSound( filter, m_hOldPlayers[i]->entindex(), "ObjectPortablePowerGenerator.Shutdown" );
|
||||
}
|
||||
|
||||
if ( m_hPlayers[i] )
|
||||
{
|
||||
// Start "buff" sound.
|
||||
CPASAttenuationFilter filter( m_hPlayers[i], "ObjectPortablePowerGenerator.Startup" );
|
||||
EmitSound( filter, m_hPlayers[i]->entindex(), "ObjectPortablePowerGenerator.Startup" );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Control screen
|
||||
//-----------------------------------------------------------------------------
|
||||
class CBuffStationControlPanel : public CObjectControlPanel
|
||||
{
|
||||
DECLARE_CLASS( CBuffStationControlPanel, CObjectControlPanel );
|
||||
|
||||
public:
|
||||
|
||||
CBuffStationControlPanel( vgui::Panel *parent, const char *panelName );
|
||||
virtual bool Init( KeyValues* pKeyValues, VGuiScreenInitData_t* pInitData );
|
||||
virtual void OnTick();
|
||||
virtual void OnCommand( const char *command );
|
||||
|
||||
void ConnectToStation( void );
|
||||
|
||||
private:
|
||||
vgui::Label *m_pSocketsLabel;
|
||||
vgui::Button *m_pConnectButton;
|
||||
};
|
||||
|
||||
|
||||
DECLARE_VGUI_SCREEN_FACTORY( CBuffStationControlPanel, "buffstation_control_panel" );
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Constructor:
|
||||
//-----------------------------------------------------------------------------
|
||||
CBuffStationControlPanel::CBuffStationControlPanel( vgui::Panel *parent, const char *panelName )
|
||||
: BaseClass( parent, "CBuffStationControlPanel" )
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Initialization
|
||||
//-----------------------------------------------------------------------------
|
||||
bool CBuffStationControlPanel::Init( KeyValues* pKeyValues, VGuiScreenInitData_t* pInitData )
|
||||
{
|
||||
m_pSocketsLabel = new vgui::Label( this, "SocketReadout", "" );
|
||||
m_pConnectButton = new CBitmapButton( this, "ConnectButton", "Connect" );
|
||||
|
||||
if (!BaseClass::Init(pKeyValues, pInitData))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Frame-based update
|
||||
//-----------------------------------------------------------------------------
|
||||
void CBuffStationControlPanel::OnTick()
|
||||
{
|
||||
BaseClass::OnTick();
|
||||
|
||||
C_BaseObject *pObj = GetOwningObject();
|
||||
if (!pObj)
|
||||
return;
|
||||
|
||||
Assert( dynamic_cast<C_ObjectBuffStation*>(pObj) );
|
||||
C_ObjectBuffStation *pStation = static_cast<C_ObjectBuffStation*>(pObj);
|
||||
|
||||
char buf[256];
|
||||
int nSocketsLeft = pStation->PlayerSocketsLeft();
|
||||
if (nSocketsLeft > 0)
|
||||
{
|
||||
Q_snprintf( buf, sizeof( buf ), "%d sockets left", pStation->PlayerSocketsLeft() );
|
||||
}
|
||||
else
|
||||
{
|
||||
Q_strncpy( buf, "No sockets left", sizeof( buf ) );
|
||||
}
|
||||
|
||||
m_pSocketsLabel->SetText( buf );
|
||||
|
||||
// Make sure the connect/disconnect button is correct
|
||||
if ( pStation->IsLocalPlayerAttached() )
|
||||
{
|
||||
m_pConnectButton->SetText( "Disconnect from Station" );
|
||||
}
|
||||
else
|
||||
{
|
||||
m_pConnectButton->SetText( "Connect To Station" );
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Handle clicking on the Connect/Disconnect button
|
||||
//-----------------------------------------------------------------------------
|
||||
void CBuffStationControlPanel::ConnectToStation( void )
|
||||
{
|
||||
C_BaseObject *pObj = GetOwningObject();
|
||||
if (pObj)
|
||||
{
|
||||
pObj->SendClientCommand( "toggle_connect" );
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Button click handlers
|
||||
//-----------------------------------------------------------------------------
|
||||
void CBuffStationControlPanel::OnCommand( const char *command )
|
||||
{
|
||||
if (!Q_strnicmp(command, "Connect", 7))
|
||||
{
|
||||
ConnectToStation();
|
||||
return;
|
||||
}
|
||||
|
||||
BaseClass::OnCommand(command);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,70 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
//=============================================================================//
|
||||
|
||||
#include "cbase.h"
|
||||
#include "hud.h"
|
||||
#include "commanderoverlay.h"
|
||||
#include "c_baseobject.h"
|
||||
|
||||
// memdbgon must be the last include file in a .cpp file!!!
|
||||
#include "tier0/memdbgon.h"
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
class C_ObjectBunker : public C_BaseObject
|
||||
{
|
||||
DECLARE_CLASS( C_ObjectBunker, C_BaseObject );
|
||||
public:
|
||||
DECLARE_CLIENTCLASS();
|
||||
|
||||
C_ObjectBunker();
|
||||
|
||||
private:
|
||||
C_ObjectBunker( const C_ObjectBunker & ); // not defined, not accessible
|
||||
};
|
||||
|
||||
IMPLEMENT_CLIENTCLASS_DT(C_ObjectBunker, DT_ObjectBunker, CObjectBunker)
|
||||
END_RECV_TABLE()
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
C_ObjectBunker::C_ObjectBunker()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
//=============================================================================
|
||||
// Bunker Ladder
|
||||
//=============================================================================
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
class C_ObjectBunkerLadder : public C_BaseAnimating
|
||||
{
|
||||
DECLARE_CLASS( C_ObjectBunkerLadder, C_BaseAnimating );
|
||||
public:
|
||||
|
||||
DECLARE_CLIENTCLASS();
|
||||
|
||||
C_ObjectBunkerLadder();
|
||||
|
||||
private:
|
||||
C_ObjectBunkerLadder( const C_ObjectBunkerLadder& ); // not defined, not accessible
|
||||
};
|
||||
|
||||
IMPLEMENT_CLIENTCLASS_DT( C_ObjectBunkerLadder, DT_ObjectBunkerLadder, CObjectBunkerLadder )
|
||||
END_RECV_TABLE()
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
C_ObjectBunkerLadder::C_ObjectBunkerLadder()
|
||||
{
|
||||
}
|
||||
|
||||
@@ -0,0 +1,44 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
//=============================================================================//
|
||||
|
||||
#include "cbase.h"
|
||||
#include "hud.h"
|
||||
#include "commanderoverlay.h"
|
||||
#include "c_baseobject.h"
|
||||
|
||||
// memdbgon must be the last include file in a .cpp file!!!
|
||||
#include "tier0/memdbgon.h"
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
class C_ObjectDragonsTeeth : public C_BaseObject
|
||||
{
|
||||
DECLARE_CLASS( C_ObjectDragonsTeeth, C_BaseObject );
|
||||
public:
|
||||
DECLARE_CLIENTCLASS();
|
||||
|
||||
C_ObjectDragonsTeeth();
|
||||
|
||||
// Since we have material proxies to show building amount, don't offset origin
|
||||
virtual bool OffsetObjectOrigin( Vector& origin )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
private:
|
||||
C_ObjectDragonsTeeth( const C_ObjectDragonsTeeth & ); // not defined, not accessible
|
||||
};
|
||||
|
||||
IMPLEMENT_CLIENTCLASS_DT(C_ObjectDragonsTeeth, DT_ObjectDragonsTeeth, CObjectDragonsTeeth)
|
||||
END_RECV_TABLE()
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
C_ObjectDragonsTeeth::C_ObjectDragonsTeeth()
|
||||
{
|
||||
}
|
||||
@@ -0,0 +1,99 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================//
|
||||
#include "cbase.h"
|
||||
#include "hud.h"
|
||||
#include "c_baseobject.h"
|
||||
#include "particles_simple.h"
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
class C_ObjectEMPGenerator : public C_BaseObject
|
||||
{
|
||||
DECLARE_CLASS( C_ObjectEMPGenerator, C_BaseObject );
|
||||
public:
|
||||
DECLARE_CLIENTCLASS();
|
||||
|
||||
C_ObjectEMPGenerator();
|
||||
|
||||
virtual void OnDataChanged( DataUpdateType_t updateType );
|
||||
virtual void ClientThink( void );
|
||||
|
||||
private:
|
||||
CSmartPtr<CSimpleEmitter> m_pEmitter;
|
||||
PMaterialHandle m_hParticleMaterial;
|
||||
TimedEvent m_ParticleEvent;
|
||||
|
||||
private:
|
||||
C_ObjectEMPGenerator( const C_ObjectEMPGenerator & ); // not defined, not accessible
|
||||
};
|
||||
|
||||
IMPLEMENT_CLIENTCLASS_DT(C_ObjectEMPGenerator, DT_ObjectEMPGenerator, CObjectEMPGenerator)
|
||||
END_RECV_TABLE()
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
C_ObjectEMPGenerator::C_ObjectEMPGenerator()
|
||||
{
|
||||
m_ParticleEvent.Init( 300 );
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void C_ObjectEMPGenerator::OnDataChanged( DataUpdateType_t updateType )
|
||||
{
|
||||
BaseClass::OnDataChanged( updateType );
|
||||
|
||||
if ( updateType == DATA_UPDATE_CREATED )
|
||||
{
|
||||
m_pEmitter = CSimpleEmitter::Create( "C_ObjectEMPGenerator" );
|
||||
m_hParticleMaterial = m_pEmitter->GetPMaterial( "sprites/chargeball" );
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void C_ObjectEMPGenerator::ClientThink( void )
|
||||
{
|
||||
// Add particles at the target.
|
||||
float flCur = gpGlobals->frametime;
|
||||
while ( m_ParticleEvent.NextEvent( flCur ) )
|
||||
{
|
||||
Vector vPos = WorldSpaceCenter( );
|
||||
Vector vOffset = RandomVector( -1, 1 );
|
||||
VectorNormalize( vOffset );
|
||||
vPos += vOffset * RandomFloat( 0, 50 );
|
||||
|
||||
SimpleParticle *pParticle = m_pEmitter->AddSimpleParticle( m_hParticleMaterial, vPos );
|
||||
if ( pParticle )
|
||||
{
|
||||
// Move the points along the path.
|
||||
pParticle->m_vecVelocity.Init();
|
||||
pParticle->m_flRoll = 0;
|
||||
pParticle->m_flRollDelta = 0;
|
||||
pParticle->m_flDieTime = 0.4f;
|
||||
pParticle->m_flLifetime = 0;
|
||||
pParticle->m_uchColor[0] = 255;
|
||||
pParticle->m_uchColor[1] = 255;
|
||||
pParticle->m_uchColor[2] = 255;
|
||||
pParticle->m_uchStartAlpha = 32;
|
||||
pParticle->m_uchEndAlpha = 0;
|
||||
pParticle->m_uchStartSize = 6;
|
||||
pParticle->m_uchEndSize = 4;
|
||||
pParticle->m_iFlags = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,36 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
//=============================================================================//
|
||||
|
||||
#include "cbase.h"
|
||||
#include "hud.h"
|
||||
#include "commanderoverlay.h"
|
||||
#include "tf_obj_baseupgrade_shared.h"
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
class C_ObjectExplosives : public C_BaseObjectUpgrade
|
||||
{
|
||||
DECLARE_CLASS( C_ObjectExplosives, C_BaseObjectUpgrade );
|
||||
public:
|
||||
DECLARE_CLIENTCLASS();
|
||||
|
||||
C_ObjectExplosives();
|
||||
|
||||
private:
|
||||
C_ObjectExplosives( const C_ObjectExplosives & ); // not defined, not accessible
|
||||
};
|
||||
|
||||
IMPLEMENT_CLIENTCLASS_DT(C_ObjectExplosives, DT_ObjectExplosives, CObjectExplosives)
|
||||
END_RECV_TABLE()
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
C_ObjectExplosives::C_ObjectExplosives()
|
||||
{
|
||||
}
|
||||
|
||||
@@ -0,0 +1,28 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
//=============================================================================//
|
||||
|
||||
#include "cbase.h"
|
||||
#include "c_obj_base_manned_gun.h"
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
class C_ObjectMannedMissileLauncher : public C_ObjectBaseMannedGun
|
||||
{
|
||||
DECLARE_CLASS( C_ObjectMannedMissileLauncher, C_ObjectBaseMannedGun );
|
||||
public:
|
||||
DECLARE_CLIENTCLASS();
|
||||
|
||||
C_ObjectMannedMissileLauncher() {}
|
||||
|
||||
private:
|
||||
C_ObjectMannedMissileLauncher( const C_ObjectMannedMissileLauncher & ); // not defined, not accessible
|
||||
};
|
||||
|
||||
IMPLEMENT_CLIENTCLASS_DT(C_ObjectMannedMissileLauncher, DT_ObjectMannedMissileLauncher, CObjectMannedMissileLauncher)
|
||||
END_RECV_TABLE()
|
||||
|
||||
@@ -0,0 +1,27 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================//
|
||||
#include "cbase.h"
|
||||
#include "c_obj_base_manned_gun.h"
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
class C_ObjectMannedPlasmagun : public C_ObjectBaseMannedGun
|
||||
{
|
||||
DECLARE_CLASS( C_ObjectMannedPlasmagun, C_ObjectBaseMannedGun );
|
||||
public:
|
||||
DECLARE_CLIENTCLASS();
|
||||
|
||||
C_ObjectMannedPlasmagun() {}
|
||||
|
||||
private:
|
||||
C_ObjectMannedPlasmagun( const C_ObjectMannedPlasmagun & ); // not defined, not accessible
|
||||
};
|
||||
|
||||
IMPLEMENT_CLIENTCLASS_DT(C_ObjectMannedPlasmagun, DT_ObjectMannedPlasmagun, CObjectMannedPlasmagun)
|
||||
END_RECV_TABLE()
|
||||
|
||||
@@ -0,0 +1,27 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
//=============================================================================//
|
||||
|
||||
#include "cbase.h"
|
||||
#include "c_obj_base_manned_gun.h"
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
class C_ObjectMannedShield : public C_ObjectBaseMannedGun
|
||||
{
|
||||
DECLARE_CLASS( C_ObjectMannedShield, C_ObjectBaseMannedGun );
|
||||
public:
|
||||
DECLARE_CLIENTCLASS();
|
||||
|
||||
C_ObjectMannedShield() {}
|
||||
|
||||
private:
|
||||
C_ObjectMannedShield( const C_ObjectMannedShield & ); // not defined, not accessible
|
||||
};
|
||||
|
||||
IMPLEMENT_CLIENTCLASS_DT( C_ObjectMannedShield, DT_ObjectMannedShield, CObjectMannedShield )
|
||||
END_RECV_TABLE()
|
||||
@@ -0,0 +1,37 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================//
|
||||
#include "cbase.h"
|
||||
#include "hud.h"
|
||||
#include "tf_shareddefs.h"
|
||||
#include "c_obj_mapdefined.h"
|
||||
|
||||
// memdbgon must be the last include file in a .cpp file!!!
|
||||
#include "tier0/memdbgon.h"
|
||||
|
||||
IMPLEMENT_CLIENTCLASS_DT(C_ObjectMapDefined, DT_ObjectMapDefined, CObjectMapDefined)
|
||||
RecvPropString( RECVINFO(m_szCustomName) ),
|
||||
END_RECV_TABLE()
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
C_ObjectMapDefined::C_ObjectMapDefined()
|
||||
{
|
||||
memset( m_szCustomName, 0, sizeof(m_szCustomName) );
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Get a text description for the object target
|
||||
//-----------------------------------------------------------------------------
|
||||
const char *C_ObjectMapDefined::GetTargetDescription( void ) const
|
||||
{
|
||||
if ( m_szCustomName && m_szCustomName[0] )
|
||||
return m_szCustomName;
|
||||
|
||||
return BaseClass::GetTargetDescription();
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================//
|
||||
|
||||
#ifndef C_OBJ_MAPDEFINED_H
|
||||
#define C_OBJ_MAPDEFINED_H
|
||||
#ifdef _WIN32
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include "c_baseobject.h"
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
class C_ObjectMapDefined : public C_BaseObject
|
||||
{
|
||||
DECLARE_CLASS( C_ObjectMapDefined, C_BaseObject );
|
||||
public:
|
||||
DECLARE_CLIENTCLASS();
|
||||
|
||||
C_ObjectMapDefined();
|
||||
|
||||
virtual const char *GetTargetDescription( void ) const;
|
||||
|
||||
private:
|
||||
C_ObjectMapDefined( const C_ObjectMapDefined & ); // not defined, not accessible
|
||||
|
||||
char m_szCustomName[ MAX_OBJ_CUSTOMNAME_SIZE ];
|
||||
};
|
||||
|
||||
#endif // C_OBJ_MAPDEFINED_H
|
||||
@@ -0,0 +1,279 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
//=============================================================================//
|
||||
|
||||
#include "cbase.h"
|
||||
#include "c_baseobject.h"
|
||||
#include "ObjectControlPanel.h"
|
||||
#include "hud_minimap.h"
|
||||
#include "vgui_bitmapimage.h"
|
||||
#include "c_vehicle_teleport_station.h"
|
||||
#include <vgui/MouseCode.h>
|
||||
|
||||
|
||||
class C_ObjMCVSelectionPanel;
|
||||
CUtlLinkedList<C_ObjMCVSelectionPanel*,int> g_SelectionPanels;
|
||||
|
||||
|
||||
// ------------------------------------------------------------------------------------------------ //
|
||||
// C_ObjMCVSelectionPanel
|
||||
// ------------------------------------------------------------------------------------------------ //
|
||||
|
||||
class C_ObjMCVSelectionPanel : public C_BaseObject
|
||||
{
|
||||
public:
|
||||
|
||||
DECLARE_CLASS( C_ObjMCVSelectionPanel, C_BaseObject );
|
||||
DECLARE_CLIENTCLASS();
|
||||
|
||||
C_ObjMCVSelectionPanel();
|
||||
~C_ObjMCVSelectionPanel();
|
||||
|
||||
typedef CHandle<C_VehicleTeleportStation> VehicleTeleportStationHandle;
|
||||
CUtlVector<VehicleTeleportStationHandle> m_DeployedTeleportStations;
|
||||
|
||||
|
||||
private:
|
||||
static C_ObjMCVSelectionPanel *s_pSelectionPanel;
|
||||
|
||||
friend void RecvProxy_TeleportStationCount( void *pStruct, int objectID, int currentArrayLength );
|
||||
friend void RecvProxy_TeleportStationElement( const CRecvProxyData *pData, void *pStruct, void *pOut );
|
||||
|
||||
C_ObjMCVSelectionPanel( const C_ObjMCVSelectionPanel & );
|
||||
};
|
||||
|
||||
|
||||
void RecvProxy_TeleportStationCount( void *pStruct, int objectID, int currentArrayLength )
|
||||
{
|
||||
C_ObjMCVSelectionPanel *pPanel = (C_ObjMCVSelectionPanel*)pStruct;
|
||||
if ( pPanel->m_DeployedTeleportStations.Count() != currentArrayLength )
|
||||
{
|
||||
pPanel->m_DeployedTeleportStations.SetSize( currentArrayLength );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void RecvProxy_TeleportStationElement( const CRecvProxyData *pData, void *pStruct, void *pOut )
|
||||
{
|
||||
C_ObjMCVSelectionPanel *pPanel = (C_ObjMCVSelectionPanel*)pStruct;
|
||||
|
||||
Assert( pData->m_iElement < pPanel->m_DeployedTeleportStations.Count() );
|
||||
|
||||
RecvProxy_IntToEHandle( pData, pStruct, &pPanel->m_DeployedTeleportStations[pData->m_iElement] );
|
||||
}
|
||||
|
||||
|
||||
IMPLEMENT_CLIENTCLASS_DT( C_ObjMCVSelectionPanel, DT_MCVSelectionPanel, CObjMCVSelectionPanel )
|
||||
RecvPropVirtualArray(
|
||||
RecvProxy_TeleportStationCount,
|
||||
32,
|
||||
RecvPropEHandle( "teleport_station_element", 0, 0, RecvProxy_TeleportStationElement ),
|
||||
"teleport_stations" )
|
||||
END_RECV_TABLE()
|
||||
|
||||
|
||||
C_ObjMCVSelectionPanel::C_ObjMCVSelectionPanel()
|
||||
{
|
||||
g_SelectionPanels.AddToTail( this );
|
||||
}
|
||||
|
||||
C_ObjMCVSelectionPanel::~C_ObjMCVSelectionPanel()
|
||||
{
|
||||
g_SelectionPanels.FindAndRemove( this );
|
||||
}
|
||||
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// CMCVMinimapPanel
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
class CMCVMinimapPanel : public CMinimapPanel
|
||||
{
|
||||
public:
|
||||
|
||||
DECLARE_CLASS( CMCVMinimapPanel, CMinimapPanel );
|
||||
|
||||
CMCVMinimapPanel( vgui::Panel *pParent, const char *pElementName );
|
||||
virtual ~CMCVMinimapPanel();
|
||||
|
||||
virtual void Paint();
|
||||
virtual void OnMousePressed( vgui::MouseCode code );
|
||||
virtual void OnCursorMoved( int x, int y );
|
||||
|
||||
|
||||
private:
|
||||
BitmapImage m_MCVImage;
|
||||
BitmapImage m_SelectedMCVImage;
|
||||
int m_LastX, m_LastY;
|
||||
};
|
||||
|
||||
|
||||
CMCVMinimapPanel::CMCVMinimapPanel( vgui::Panel *pParent, const char *pElementName )
|
||||
: CMinimapPanel( pElementName )
|
||||
{
|
||||
SetParent( pParent );
|
||||
m_MCVImage.Init( GetVPanel(), "hud/minimap/icon_mcv_unselected" );
|
||||
m_SelectedMCVImage.Init( GetVPanel(), "hud/minimap/icon_mcv_selected" );
|
||||
m_LastX = m_LastY = 0;
|
||||
}
|
||||
|
||||
|
||||
CMCVMinimapPanel::~CMCVMinimapPanel()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void CMCVMinimapPanel::Paint()
|
||||
{
|
||||
// Draw the minimap.
|
||||
BaseClass::Paint();
|
||||
|
||||
// Now draw the MCVs.
|
||||
if ( g_SelectionPanels.Count() > 0 )
|
||||
{
|
||||
C_ObjMCVSelectionPanel *pPanel = g_SelectionPanels[ g_SelectionPanels.Head() ];
|
||||
C_BaseEntity *pSelectedMCV = C_BaseTFPlayer::GetLocalPlayer()->GetSelectedMCV();
|
||||
|
||||
for ( int i=0; i < pPanel->m_DeployedTeleportStations.Count(); i++ )
|
||||
{
|
||||
C_VehicleTeleportStation *pStation = pPanel->m_DeployedTeleportStations[i];
|
||||
if ( pStation )
|
||||
{
|
||||
float x, y;
|
||||
if ( WorldToMinimap( MINIMAP_CLAMP, pStation->GetAbsOrigin(), x, y ) )
|
||||
{
|
||||
int size = 20;
|
||||
|
||||
if ( pStation == pSelectedMCV )
|
||||
m_SelectedMCVImage.DoPaint( x-size/2, y-size/2, size, size );
|
||||
else
|
||||
m_MCVImage.DoPaint( x-size/2, y-size/2, size, size );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void CMCVMinimapPanel::OnMousePressed( vgui::MouseCode code )
|
||||
{
|
||||
BaseClass::OnMousePressed( code );
|
||||
|
||||
if ( code != vgui::MOUSE_LEFT )
|
||||
return;
|
||||
|
||||
// Now draw the MCVs.
|
||||
if ( g_SelectionPanels.Count() > 0 )
|
||||
{
|
||||
C_ObjMCVSelectionPanel *pPanel = g_SelectionPanels[ g_SelectionPanels.Head() ];
|
||||
|
||||
// Find the closest MCV to their mouse press.
|
||||
int iClosest = -1;
|
||||
float flClosest = 1e24;
|
||||
Vector2D curMousePos( m_LastX, m_LastY );
|
||||
|
||||
for ( int i=0; i < pPanel->m_DeployedTeleportStations.Count(); i++ )
|
||||
{
|
||||
C_VehicleTeleportStation *pStation = pPanel->m_DeployedTeleportStations[i];
|
||||
if ( pStation )
|
||||
{
|
||||
Vector2D mcvPos;
|
||||
if ( WorldToMinimap( MINIMAP_CLAMP, pStation->GetAbsOrigin(), mcvPos.x, mcvPos.y ) )
|
||||
{
|
||||
float flTestDist = mcvPos.DistTo( curMousePos );
|
||||
if ( flTestDist < flClosest )
|
||||
{
|
||||
flClosest = flTestDist;
|
||||
iClosest = i;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ( iClosest != -1 && flClosest < 10 )
|
||||
{
|
||||
C_VehicleTeleportStation *pClosest = pPanel->m_DeployedTeleportStations[iClosest];
|
||||
|
||||
char str[512];
|
||||
Q_snprintf( str, sizeof( str ), "SelectMCV %d", pClosest->entindex() );
|
||||
pPanel->SendClientCommand( str );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void CMCVMinimapPanel::OnCursorMoved( int x, int y )
|
||||
{
|
||||
BaseClass::OnCursorMoved( x, y );
|
||||
|
||||
m_LastX = x;
|
||||
m_LastY = y;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// ------------------------------------------------------------------------------------------------ //
|
||||
// CMCVSelectionPanel
|
||||
// ------------------------------------------------------------------------------------------------ //
|
||||
|
||||
class CMCVSelectionPanel : public CObjectControlPanel
|
||||
{
|
||||
DECLARE_CLASS( CMCVSelectionPanel, CObjectControlPanel );
|
||||
|
||||
|
||||
public:
|
||||
|
||||
CMCVSelectionPanel( vgui::Panel *parent, const char *panelName );
|
||||
virtual ~CMCVSelectionPanel();
|
||||
|
||||
virtual bool Init( KeyValues* pKeyValues, VGuiScreenInitData_t* pInitData );
|
||||
virtual void OnCommand( const char *command );
|
||||
|
||||
|
||||
private:
|
||||
|
||||
CMCVMinimapPanel *m_pMinimapPanel;
|
||||
};
|
||||
|
||||
|
||||
DECLARE_VGUI_SCREEN_FACTORY( CMCVSelectionPanel, "mcv_selection_panel" );
|
||||
|
||||
|
||||
CMCVSelectionPanel::CMCVSelectionPanel( vgui::Panel *parent, const char *panelName )
|
||||
: BaseClass( parent, "CMCVSelectionPanel" )
|
||||
{
|
||||
m_pMinimapPanel = new CMCVMinimapPanel( this, "MinimapPanel" );
|
||||
m_pMinimapPanel->SetZPos( 10 );
|
||||
m_pMinimapPanel->Init( NULL );
|
||||
}
|
||||
|
||||
|
||||
CMCVSelectionPanel::~CMCVSelectionPanel()
|
||||
{
|
||||
delete m_pMinimapPanel;
|
||||
}
|
||||
|
||||
|
||||
bool CMCVSelectionPanel::Init( KeyValues* pKeyValues, VGuiScreenInitData_t* pInitData )
|
||||
{
|
||||
if ( !BaseClass::Init( pKeyValues, pInitData ) )
|
||||
return false;
|
||||
|
||||
m_pMinimapPanel->LevelInit( engine->GetLevelName() );
|
||||
m_pMinimapPanel->SetVisible( true );
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
void CMCVSelectionPanel::OnCommand( const char *command )
|
||||
{
|
||||
BaseClass::OnCommand( command );
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,389 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose: Client version of CObjectMortar
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================//
|
||||
#include "cbase.h"
|
||||
#include "hud.h"
|
||||
#include "CommanderOverlay.h"
|
||||
#include "c_baseobject.h"
|
||||
#include "tf_shareddefs.h"
|
||||
#include "c_basetfplayer.h"
|
||||
#include "ObjectControlPanel.h"
|
||||
#include <vgui_controls/Label.h>
|
||||
#include <vgui_controls/Button.h>
|
||||
#include "vgui_rotation_slider.h"
|
||||
#include <vgui/ISurface.h>
|
||||
#include "vgui_basepanel.h"
|
||||
#include "vgui_bitmapimage.h"
|
||||
#include "iusesmortarpanel.h"
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
class C_ObjectMortar : public C_BaseObject, public IUsesMortarPanel
|
||||
{
|
||||
DECLARE_CLASS( C_ObjectMortar, C_BaseObject );
|
||||
public:
|
||||
DECLARE_CLIENTCLASS();
|
||||
DECLARE_ENTITY_PANEL();
|
||||
|
||||
C_ObjectMortar();
|
||||
|
||||
virtual void SetDormant( bool bDormant );
|
||||
virtual void Select( void );
|
||||
virtual void RecalculateIDString( void );
|
||||
|
||||
void FireMortar( void );
|
||||
|
||||
// IUsesMortarPanel
|
||||
public:
|
||||
// Get the data from this mortar needed by the panel
|
||||
virtual void GetMortarData( float *flClientMortarYaw, bool *bAllowedToFire, float *flPower, float *flFiringPower, float *flFiringAccuracy, int *iFiringState );
|
||||
virtual void SendYawCommand( void );
|
||||
virtual void ForceClientYawCountdown( float flTime );
|
||||
virtual void ClickFire( void );
|
||||
|
||||
public:
|
||||
int m_iRoundType;
|
||||
int m_iMortarRounds[ MA_LASTAMMOTYPE ];
|
||||
|
||||
// Mortar firing info.
|
||||
int m_iFiringState; // One of the MORTAR_ defines.
|
||||
bool m_bMortarReloading;
|
||||
float m_flPower;
|
||||
bool m_bAllowedToFire;
|
||||
|
||||
// Parameters for the next shot.
|
||||
float m_flFiringPower;
|
||||
float m_flFiringAccuracy;
|
||||
|
||||
float m_flMortarYaw; // What direction the mortar is aimed in.
|
||||
float m_flMortarPitch;
|
||||
|
||||
// This is what is used on the client to draw the ground line and orient the mortar.
|
||||
// It is usually copied right over from m_flClientMortarYaw (which comes from the server),
|
||||
// but this is also used when rotating the mortar so you can see the line move smoothly.
|
||||
float m_flClientMortarYaw;
|
||||
|
||||
// This is set to about 1/4 seconds when you rotate the mortar line so you use the client's
|
||||
// (smooth, non-lagged) yaw changes instead of the server's.
|
||||
float m_flForceClientYawCountdown;
|
||||
|
||||
private:
|
||||
C_ObjectMortar( const C_ObjectMortar & ); // not defined, not accessible
|
||||
};
|
||||
|
||||
IMPLEMENT_CLIENTCLASS_DT(C_ObjectMortar, DT_ObjectMortar, CObjectMortar)
|
||||
RecvPropInt( RECVINFO(m_iRoundType) ),
|
||||
RecvPropArray( RecvPropInt( RECVINFO(m_iMortarRounds[0]) ), m_iMortarRounds )
|
||||
END_RECV_TABLE()
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
C_ObjectMortar::C_ObjectMortar( void )
|
||||
{
|
||||
memset( m_iMortarRounds, 0, sizeof( m_iMortarRounds ) );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void C_ObjectMortar::SetDormant( bool bDormant )
|
||||
{
|
||||
BaseClass::SetDormant( bDormant );
|
||||
ENTITY_PANEL_ACTIVATE( "mortar", !bDormant );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Cycle ammo types on the mortar
|
||||
//-----------------------------------------------------------------------------
|
||||
void C_ObjectMortar::Select( void )
|
||||
{
|
||||
C_BaseTFPlayer *pPlayer = C_BaseTFPlayer::GetLocalPlayer();
|
||||
if ( pPlayer == NULL )
|
||||
return;
|
||||
|
||||
int iOldType = m_iRoundType++;
|
||||
|
||||
// Cycle to the next ammo type
|
||||
while ( m_iRoundType != iOldType )
|
||||
{
|
||||
// Hit the end of the round types?
|
||||
if ( m_iRoundType == MA_LASTAMMOTYPE )
|
||||
{
|
||||
m_iRoundType = MA_SHELL;
|
||||
break;
|
||||
}
|
||||
|
||||
// Does this round type need a technology?
|
||||
if ( MortarAmmoTechs[ m_iRoundType ] && MortarAmmoTechs[ m_iRoundType ][0] )
|
||||
{
|
||||
// Does the player have the technology?
|
||||
if ( pPlayer->HasNamedTechnology( MortarAmmoTechs[ m_iRoundType ] ) )
|
||||
{
|
||||
// Do we have ammo?
|
||||
if ( m_iMortarRounds[ m_iRoundType ] > 0 )
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Go to the next round type
|
||||
m_iRoundType++;
|
||||
}
|
||||
|
||||
engine->ClientCmd( VarArgs("mortarround %d", m_iRoundType) );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void C_ObjectMortar::RecalculateIDString( void )
|
||||
{
|
||||
// Only owners get full data
|
||||
if ( IsOwnedByLocalPlayer() )
|
||||
{
|
||||
if ( m_iRoundType >= 0 )
|
||||
{
|
||||
// -1 means we have infinite rounds of this type
|
||||
if ( m_iMortarRounds[ m_iRoundType ] == -1 )
|
||||
{
|
||||
Q_snprintf( m_szIDString, sizeof(m_szIDString), "%s - %s", GetTargetDescription(), MortarAmmoNames[ m_iRoundType ] );
|
||||
}
|
||||
else
|
||||
{
|
||||
Q_snprintf( m_szIDString, sizeof(m_szIDString), "%s - %d %s", GetTargetDescription(), m_iMortarRounds[ m_iRoundType ], MortarAmmoNames[ m_iRoundType ] );
|
||||
}
|
||||
Q_strncat( m_szIDString, "\nUse it to change ammo types.", sizeof(m_szIDString), COPY_ALL_CHARACTERS );
|
||||
}
|
||||
}
|
||||
|
||||
BaseClass::RecalculateIDString();
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void C_ObjectMortar::ClickFire( void )
|
||||
{
|
||||
switch( m_iFiringState )
|
||||
{
|
||||
case MORTAR_IDLE:
|
||||
m_iFiringState = MORTAR_CHARGING_POWER;
|
||||
break;
|
||||
|
||||
case MORTAR_CHARGING_POWER:
|
||||
m_flFiringPower = m_flPower;
|
||||
m_iFiringState = MORTAR_CHARGING_ACCURACY;
|
||||
break;
|
||||
|
||||
case MORTAR_CHARGING_ACCURACY:
|
||||
m_flFiringAccuracy = m_flPower;
|
||||
m_iFiringState = MORTAR_IDLE;
|
||||
|
||||
FireMortar();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void C_ObjectMortar::GetMortarData( float *flClientMortarYaw, bool *bAllowedToFire, float *flPower, float *flFiringPower, float *flFiringAccuracy, int *iFiringState )
|
||||
{
|
||||
*flClientMortarYaw = m_flClientMortarYaw;
|
||||
*bAllowedToFire = m_bAllowedToFire;
|
||||
*flPower = m_flPower;
|
||||
*flFiringPower = m_flFiringPower;
|
||||
*flFiringAccuracy = m_flFiringAccuracy;
|
||||
*iFiringState = m_iFiringState;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void C_ObjectMortar::SendYawCommand( void )
|
||||
{
|
||||
char szbuf[48];
|
||||
Q_snprintf( szbuf, sizeof( szbuf ), "MortarYaw %0.2f\n", m_flClientMortarYaw );
|
||||
SendClientCommand( szbuf );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void C_ObjectMortar::ForceClientYawCountdown( float flTime )
|
||||
{
|
||||
m_flForceClientYawCountdown = flTime;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Control screen
|
||||
//-----------------------------------------------------------------------------
|
||||
class CMortarControlPanel : public CObjectControlPanel
|
||||
{
|
||||
DECLARE_CLASS( CMortarControlPanel, CObjectControlPanel );
|
||||
public:
|
||||
CMortarControlPanel( vgui::Panel *parent, const char *panelName );
|
||||
virtual ~CMortarControlPanel();
|
||||
|
||||
virtual bool Init( KeyValues* pKeyValues, VGuiScreenInitData_t* pInitData );
|
||||
virtual void OnCommand( const char *command );
|
||||
C_ObjectMortar* GetMortar() const;
|
||||
|
||||
protected:
|
||||
virtual vgui::Panel* TickCurrentPanel();
|
||||
|
||||
private:
|
||||
CMortarMinimapPanel *m_pMinimapPanel;
|
||||
};
|
||||
|
||||
|
||||
DECLARE_VGUI_SCREEN_FACTORY( CMortarControlPanel, "mortar_control_panel" );
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Constructor:
|
||||
//-----------------------------------------------------------------------------
|
||||
CMortarControlPanel::CMortarControlPanel( vgui::Panel *parent, const char *panelName )
|
||||
: BaseClass( parent, "CMortarControlPanel" )
|
||||
{
|
||||
m_pMinimapPanel = new CMortarMinimapPanel( this, "MinimapPanel" );
|
||||
m_pMinimapPanel->Init( NULL );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
CMortarControlPanel::~CMortarControlPanel()
|
||||
{
|
||||
delete m_pMinimapPanel;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Initialization
|
||||
//-----------------------------------------------------------------------------
|
||||
bool CMortarControlPanel::Init( KeyValues* pKeyValues, VGuiScreenInitData_t* pInitData )
|
||||
{
|
||||
// Make sure all named panels are created up above because BaseClass::Init initializes them
|
||||
// all from their keyvalues.
|
||||
if ( !BaseClass::Init( pKeyValues, pInitData ) )
|
||||
return false;
|
||||
|
||||
// Init subpanels.
|
||||
int x, y, w, h;
|
||||
GetBounds( x, y, w, h );
|
||||
|
||||
m_pMinimapPanel->LevelInit( engine->GetLevelName() );
|
||||
m_pMinimapPanel->SetVisible( true );
|
||||
m_pMinimapPanel->InitMortarMinimap( GetMortar() );
|
||||
return true;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
C_ObjectMortar* CMortarControlPanel::GetMortar() const
|
||||
{
|
||||
return dynamic_cast< C_ObjectMortar* >( GetOwningObject() );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void C_ObjectMortar::FireMortar( void )
|
||||
{
|
||||
char cmd[512];
|
||||
Q_snprintf( cmd, sizeof( cmd ), "FireMortar %.2f %.2f", m_flFiringPower, m_flFiringAccuracy );
|
||||
SendClientCommand( cmd );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Frame-based update
|
||||
//-----------------------------------------------------------------------------
|
||||
vgui::Panel* CMortarControlPanel::TickCurrentPanel()
|
||||
{
|
||||
C_BaseObject *pObj = GetOwningObject();
|
||||
if (!pObj)
|
||||
return BaseClass::TickCurrentPanel();;
|
||||
|
||||
ShowOwnerLabel( true );
|
||||
ShowHealthLabel( true );
|
||||
|
||||
C_ObjectMortar *pMortar = GetMortar();
|
||||
if ( !pMortar )
|
||||
return BaseClass::TickCurrentPanel();;
|
||||
|
||||
ShowOwnerLabel( false );
|
||||
ShowHealthLabel( false );
|
||||
|
||||
m_pMinimapPanel->Repaint();
|
||||
|
||||
float flAccuracySpeed = (1.0 / MORTAR_CHARGE_ACCURACY_RATE);
|
||||
|
||||
// Handle power charging
|
||||
switch( pMortar->m_iFiringState )
|
||||
{
|
||||
case MORTAR_IDLE:
|
||||
pMortar->m_flPower = 0;
|
||||
break;
|
||||
|
||||
case MORTAR_CHARGING_POWER:
|
||||
pMortar->m_flPower = MIN( pMortar->m_flPower + ( (1.0 / MORTAR_CHARGE_POWER_RATE) * gpGlobals->frametime), 1 );
|
||||
pMortar->m_flFiringPower = 0;
|
||||
pMortar->m_flFiringAccuracy = 0;
|
||||
if ( pMortar->m_flPower >= 1.0 )
|
||||
{
|
||||
// Hit Max, start going down
|
||||
pMortar->m_flFiringPower = pMortar->m_flPower;
|
||||
pMortar->m_iFiringState = MORTAR_CHARGING_ACCURACY;
|
||||
}
|
||||
break;
|
||||
|
||||
case MORTAR_CHARGING_ACCURACY:
|
||||
// Calculate accuracy speed
|
||||
if ( pMortar->m_flFiringPower > 0.5 )
|
||||
{
|
||||
// Shots over halfway suffer an increased speed to the accuracy power, making accurate shots harder
|
||||
float flAdjustedPower = (pMortar->m_flFiringPower - 0.5) * 3.0;
|
||||
flAccuracySpeed += (pMortar->m_flFiringPower * flAdjustedPower);
|
||||
}
|
||||
|
||||
pMortar->m_flPower = MAX( pMortar->m_flPower - ( flAccuracySpeed * gpGlobals->frametime), -0.25f);
|
||||
if ( pMortar->m_flPower <= -0.25 )
|
||||
{
|
||||
// Hit Min, fire mortar
|
||||
pMortar->m_flFiringAccuracy = pMortar->m_flPower;
|
||||
pMortar->m_iFiringState = MORTAR_IDLE;
|
||||
|
||||
pMortar->FireMortar();
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return BaseClass::TickCurrentPanel();
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Button click handlers
|
||||
//-----------------------------------------------------------------------------
|
||||
void CMortarControlPanel::OnCommand( const char *command )
|
||||
{
|
||||
C_ObjectMortar *pMortar = GetMortar();
|
||||
if ( !pMortar )
|
||||
return;
|
||||
|
||||
if ( !Q_stricmp( command, "FireMortar" ) )
|
||||
{
|
||||
pMortar->ClickFire();
|
||||
}
|
||||
|
||||
BaseClass::OnCommand(command);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,340 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================//
|
||||
#include "cbase.h"
|
||||
#include "c_baseobject.h"
|
||||
#include "ObjectControlPanel.h"
|
||||
#include "tf_shareddefs.h"
|
||||
#include "tempent.h"
|
||||
#include "c_te_legacytempents.h"
|
||||
#include "iviewrender_beams.h"
|
||||
#include "beamdraw.h"
|
||||
#include "view.h"
|
||||
|
||||
// memdbgon must be the last include file in a .cpp file!!!
|
||||
#include "tier0/memdbgon.h"
|
||||
|
||||
#define NUM_POWERPACK_GLOWS 6
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
class C_ObjectPowerPack : public C_BaseObject
|
||||
{
|
||||
DECLARE_CLASS( C_ObjectPowerPack, C_BaseObject );
|
||||
public:
|
||||
DECLARE_CLIENTCLASS();
|
||||
|
||||
C_ObjectPowerPack();
|
||||
~C_ObjectPowerPack();
|
||||
int SocketsLeft() const { return (MAX_OBJECTS_PER_PACK - m_iObjectsAttached); }
|
||||
|
||||
// Since we have material proxies to show building amount, don't offset origin
|
||||
virtual bool OffsetObjectOrigin( Vector& origin )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
virtual void OnGoActive( void );
|
||||
virtual void OnGoInactive( void );
|
||||
void RemoveGlows( void );
|
||||
virtual void ClientThink( void );
|
||||
virtual int DrawModel( int flags );
|
||||
|
||||
private:
|
||||
int m_iObjectsAttached;
|
||||
int m_iGlowModelIndex;
|
||||
C_LocalTempEntity *m_pGlowSprites[ NUM_POWERPACK_GLOWS ];
|
||||
|
||||
// Jacob's laddder
|
||||
Beam_t *m_pJacobsLadderBeam;
|
||||
float m_flJacobsLeftPoint;
|
||||
float m_flJacobsRightPoint;
|
||||
Vector m_vecJacobsStart;
|
||||
Vector m_vecJacobsEnd;
|
||||
CMaterialReference m_hJacobsPointMaterial;
|
||||
|
||||
private:
|
||||
C_ObjectPowerPack( const C_ObjectPowerPack & ); // not defined, not accessible
|
||||
};
|
||||
|
||||
IMPLEMENT_CLIENTCLASS_DT(C_ObjectPowerPack, DT_ObjectPowerPack, CObjectPowerPack)
|
||||
RecvPropInt( RECVINFO(m_iObjectsAttached) ),
|
||||
END_RECV_TABLE()
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
C_ObjectPowerPack::C_ObjectPowerPack()
|
||||
{
|
||||
for ( int i = 0; i < NUM_POWERPACK_GLOWS; i++ )
|
||||
{
|
||||
m_pGlowSprites[i] = NULL;
|
||||
}
|
||||
|
||||
m_iGlowModelIndex = PrecacheModel( "effects/human_object_glow.vmt" );
|
||||
m_pJacobsLadderBeam = NULL;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
C_ObjectPowerPack::~C_ObjectPowerPack( void )
|
||||
{
|
||||
RemoveGlows();
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: We've just gone active
|
||||
//-----------------------------------------------------------------------------
|
||||
void C_ObjectPowerPack::OnGoActive( void )
|
||||
{
|
||||
// Turn on our glows
|
||||
for ( int i = 0; i < NUM_POWERPACK_GLOWS; i++ )
|
||||
{
|
||||
// Find the attachment point
|
||||
int iAttachment = LookupAttachment( VarArgs("glow_%d",(i+1)) );
|
||||
Vector vecOrigin;
|
||||
QAngle vecAngles;
|
||||
if ( GetAttachment( iAttachment, vecOrigin, vecAngles ) )
|
||||
{
|
||||
Vector vecForward;
|
||||
AngleVectors( vecAngles, &vecForward );
|
||||
m_pGlowSprites[i] = tempents->TempSprite( vecOrigin, vec3_origin, 0.35, m_iGlowModelIndex, kRenderTransAdd, 0, 0.5, 1, FTENT_PERSIST | FTENT_NEVERDIE | FTENT_BEOCCLUDED, vecForward );
|
||||
}
|
||||
}
|
||||
|
||||
m_flJacobsLeftPoint = 0;
|
||||
m_flJacobsRightPoint = 0;
|
||||
m_hJacobsPointMaterial.Init( "sprites/blueflare2", TEXTURE_GROUP_CLIENT_EFFECTS );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: We've just gone inactive
|
||||
//-----------------------------------------------------------------------------
|
||||
void C_ObjectPowerPack::OnGoInactive( void )
|
||||
{
|
||||
// Turn off our glows
|
||||
RemoveGlows();
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void C_ObjectPowerPack::RemoveGlows( void )
|
||||
{
|
||||
for ( int i = 0; i < NUM_POWERPACK_GLOWS; i++ )
|
||||
{
|
||||
if ( m_pGlowSprites[i] )
|
||||
{
|
||||
m_pGlowSprites[i]->die = 0;
|
||||
m_pGlowSprites[i] = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
// Stop the jacob's ladder
|
||||
if ( m_pJacobsLadderBeam )
|
||||
{
|
||||
m_pJacobsLadderBeam->flags &= ~FBEAM_FOREVER;
|
||||
m_pJacobsLadderBeam->die = gpGlobals->curtime;
|
||||
m_pJacobsLadderBeam = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void C_ObjectPowerPack::ClientThink( void )
|
||||
{
|
||||
// Create the jacob's ladder
|
||||
if ( !m_pJacobsLadderBeam )
|
||||
{
|
||||
BeamInfo_t beamInfo;
|
||||
beamInfo.m_vecStart.Init();
|
||||
beamInfo.m_vecEnd.Init();
|
||||
beamInfo.m_pszModelName = "sprites/physbeam.vmt";
|
||||
beamInfo.m_flHaloScale = 0.0f;
|
||||
beamInfo.m_flLife = 0.0f;
|
||||
beamInfo.m_flWidth = 8.0f;
|
||||
beamInfo.m_flEndWidth = 4.0f;
|
||||
beamInfo.m_flFadeLength = 0.0f;
|
||||
beamInfo.m_flAmplitude = 20.0f;
|
||||
beamInfo.m_flBrightness = 255.0f;
|
||||
beamInfo.m_flSpeed = 0.0f;
|
||||
beamInfo.m_nStartFrame = 0;
|
||||
beamInfo.m_flFrameRate = 0.0f;
|
||||
beamInfo.m_flRed = 206.0f;
|
||||
beamInfo.m_flGreen = 181.0f;
|
||||
beamInfo.m_flBlue = 127.0f;
|
||||
beamInfo.m_nSegments = 5;
|
||||
beamInfo.m_bRenderable = true;
|
||||
m_pJacobsLadderBeam = beams->CreateBeamPoints( beamInfo );
|
||||
}
|
||||
|
||||
// Update the position of the jacob's ladder
|
||||
BeamInfo_t beamInfo;
|
||||
QAngle vecAngle;
|
||||
int iAttachment;
|
||||
|
||||
// Setup a color reflecting the amount of power being used
|
||||
color32 color;
|
||||
color.r = 206;
|
||||
color.g = 182;
|
||||
color.b = 127;
|
||||
color.a = 255;
|
||||
|
||||
// Tesla Effect
|
||||
Vector vecRightTop, vecRightBottom;
|
||||
Vector vecLeftTop, vecLeftBottom;
|
||||
iAttachment = LookupAttachment( "Tesla_ll" );
|
||||
GetAttachment( iAttachment, vecLeftBottom, vecAngle );
|
||||
iAttachment = LookupAttachment( "Tesla_ul" );
|
||||
GetAttachment( iAttachment, vecLeftTop, vecAngle );
|
||||
iAttachment = LookupAttachment( "Tesla_lr" );
|
||||
GetAttachment( iAttachment, vecRightBottom, vecAngle );
|
||||
iAttachment = LookupAttachment( "Tesla_ur" );
|
||||
GetAttachment( iAttachment, vecRightTop, vecAngle );
|
||||
|
||||
float flSpeed = 0.02;
|
||||
|
||||
m_flJacobsLeftPoint += random->RandomFloat( flSpeed * 0.25, flSpeed * 2);
|
||||
m_flJacobsRightPoint += random->RandomFloat( flSpeed * 0.25, flSpeed * 2);
|
||||
|
||||
// If they've both hit the end, break the ladder
|
||||
if ( m_flJacobsLeftPoint >= 1.0f && m_flJacobsRightPoint >= 1.0f )
|
||||
{
|
||||
// Snap!
|
||||
m_flJacobsLeftPoint = 0.0f;
|
||||
m_flJacobsRightPoint = 0.0f;
|
||||
}
|
||||
else if ( m_flJacobsLeftPoint > 1.0f )
|
||||
{
|
||||
// Only the left point's made it
|
||||
m_flJacobsLeftPoint = 1.0f;
|
||||
}
|
||||
else if ( m_flJacobsRightPoint > 1.0f )
|
||||
{
|
||||
// Only the right point's made it
|
||||
m_flJacobsRightPoint = 1.0f;
|
||||
}
|
||||
|
||||
Vector vecLeft = vecLeftTop - vecLeftBottom;
|
||||
Vector vecRight = vecRightTop - vecRightBottom;
|
||||
m_vecJacobsStart = vecLeftBottom + ( m_flJacobsLeftPoint * vecLeft );
|
||||
m_vecJacobsEnd = vecRightBottom + ( m_flJacobsRightPoint * vecRight );
|
||||
|
||||
beamInfo.m_vecStart = m_vecJacobsStart;
|
||||
beamInfo.m_vecEnd = m_vecJacobsEnd;
|
||||
beamInfo.m_flRed = color.r;
|
||||
beamInfo.m_flGreen = color.g;
|
||||
beamInfo.m_flBlue = color.b;
|
||||
beams->UpdateBeamInfo( m_pJacobsLadderBeam, beamInfo );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
int C_ObjectPowerPack::DrawModel( int flags )
|
||||
{
|
||||
if ( BaseClass::DrawModel( flags ) )
|
||||
{
|
||||
if ( ShouldBeActive() )
|
||||
{
|
||||
// Get the distance to the view
|
||||
float flDistance = (GetAbsOrigin() - MainViewOrigin()).LengthSqr();
|
||||
if ( flDistance < (1024 * 1024) )
|
||||
{
|
||||
// Draw a sprite at the tips.
|
||||
color32 color;
|
||||
color.r = 255;
|
||||
color.g = 255;
|
||||
color.b = 255;
|
||||
color.a = 255;
|
||||
float flSize = 25.0f;
|
||||
materials->Bind( m_hJacobsPointMaterial, this );
|
||||
DrawSprite( m_vecJacobsStart, flSize, flSize, color );
|
||||
DrawSprite( m_vecJacobsEnd, flSize, flSize, color );
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Control screen
|
||||
//-----------------------------------------------------------------------------
|
||||
class CPowerPackControlPanel : public CObjectControlPanel
|
||||
{
|
||||
DECLARE_CLASS( CPowerPackControlPanel, CObjectControlPanel );
|
||||
|
||||
public:
|
||||
CPowerPackControlPanel( vgui::Panel *parent, const char *panelName );
|
||||
virtual bool Init( KeyValues* pKeyValues, VGuiScreenInitData_t* pInitData );
|
||||
virtual void OnTick();
|
||||
|
||||
private:
|
||||
vgui::Label *m_pSocketsLabel;
|
||||
};
|
||||
|
||||
|
||||
DECLARE_VGUI_SCREEN_FACTORY( CPowerPackControlPanel, "powerpack_control_panel" );
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Constructor:
|
||||
//-----------------------------------------------------------------------------
|
||||
CPowerPackControlPanel::CPowerPackControlPanel( vgui::Panel *parent, const char *panelName )
|
||||
: BaseClass( parent, "CPowerPackControlPanel" )
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Initialization
|
||||
//-----------------------------------------------------------------------------
|
||||
bool CPowerPackControlPanel::Init( KeyValues* pKeyValues, VGuiScreenInitData_t* pInitData )
|
||||
{
|
||||
m_pSocketsLabel = new vgui::Label( GetActivePanel(), "SocketReadout", "" );
|
||||
|
||||
if (!BaseClass::Init(pKeyValues, pInitData))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Frame-based update
|
||||
//-----------------------------------------------------------------------------
|
||||
void CPowerPackControlPanel::OnTick()
|
||||
{
|
||||
BaseClass::OnTick();
|
||||
|
||||
C_BaseObject *pObj = GetOwningObject();
|
||||
if (!pObj)
|
||||
return;
|
||||
|
||||
Assert( dynamic_cast<C_ObjectPowerPack*>(pObj) );
|
||||
C_ObjectPowerPack *pPowerPack = static_cast<C_ObjectPowerPack*>(pObj);
|
||||
|
||||
char buf[256];
|
||||
int nSocketsLeft = pPowerPack->SocketsLeft();
|
||||
if (nSocketsLeft > 0)
|
||||
{
|
||||
Q_snprintf( buf, sizeof( buf ), "%d sockets left", pPowerPack->SocketsLeft() );
|
||||
}
|
||||
else
|
||||
{
|
||||
Q_strncpy( buf, "No sockets left", sizeof( buf ) );
|
||||
}
|
||||
|
||||
m_pSocketsLabel->SetText( buf );
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,35 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================//
|
||||
#include "cbase.h"
|
||||
#include "hud.h"
|
||||
#include "c_baseobject.h"
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
class C_ObjectRallyFlag : public C_BaseObject
|
||||
{
|
||||
DECLARE_CLASS( C_ObjectRallyFlag, C_BaseObject );
|
||||
public:
|
||||
DECLARE_CLIENTCLASS();
|
||||
|
||||
C_ObjectRallyFlag();
|
||||
|
||||
private:
|
||||
C_ObjectRallyFlag( const C_ObjectRallyFlag & ); // not defined, not accessible
|
||||
};
|
||||
|
||||
IMPLEMENT_CLIENTCLASS_DT(C_ObjectRallyFlag, DT_ObjectRallyFlag, CObjectRallyFlag)
|
||||
END_RECV_TABLE()
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
C_ObjectRallyFlag::C_ObjectRallyFlag()
|
||||
{
|
||||
}
|
||||
|
||||
@@ -0,0 +1,164 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================//
|
||||
#include "cbase.h"
|
||||
#include "hud.h"
|
||||
#include "c_obj_resourcepump.h"
|
||||
#include "commanderoverlay.h"
|
||||
#include "vgui_healthbar.h"
|
||||
#include "ObjectControlPanel.h"
|
||||
#include "tf_shareddefs.h"
|
||||
#include "vgui_bitmapbutton.h"
|
||||
#include "C_Func_Resource.h"
|
||||
|
||||
// memdbgon must be the last include file in a .cpp file!!!
|
||||
#include "tier0/memdbgon.h"
|
||||
|
||||
BEGIN_RECV_TABLE_NOBASE( C_ObjectResourcePump, DT_ResourcePumpTeamOnlyVars )
|
||||
RecvPropInt( RECVINFO(m_iPumpLevel) ),
|
||||
RecvPropEHandle( RECVINFO(m_hResourceZone) ),
|
||||
END_RECV_TABLE()
|
||||
|
||||
|
||||
IMPLEMENT_CLIENTCLASS_DT(C_ObjectResourcePump, DT_ResourcePump, CObjectResourcePump)
|
||||
RecvPropDataTable( "teamonly", 0, 0, &REFERENCE_RECV_TABLE( DT_ResourcePumpTeamOnlyVars ) )
|
||||
END_RECV_TABLE()
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
C_ObjectResourcePump::C_ObjectResourcePump()
|
||||
{
|
||||
m_iPumpLevel = 1;
|
||||
m_pResourceBar = NULL;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void C_ObjectResourcePump::SetDormant( bool bDormant )
|
||||
{
|
||||
BaseClass::SetDormant( bDormant );
|
||||
ENTITY_PANEL_ACTIVATE( "resource_pump", !bDormant );
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Control screen
|
||||
//-----------------------------------------------------------------------------
|
||||
class CResourcePumpControlPanel : public CObjectControlPanel
|
||||
{
|
||||
DECLARE_CLASS( CResourcePumpControlPanel, CObjectControlPanel );
|
||||
|
||||
public:
|
||||
CResourcePumpControlPanel( vgui::Panel *parent, const char *panelName );
|
||||
virtual bool Init( KeyValues* pKeyValues, VGuiScreenInitData_t* pInitData );
|
||||
virtual void OnTick();
|
||||
virtual void OnCommand( const char *command );
|
||||
|
||||
void Upgrade( void );
|
||||
|
||||
private:
|
||||
vgui::Button *m_pUpgradeButton;
|
||||
vgui::Label *m_pResourcesLabel;
|
||||
};
|
||||
|
||||
|
||||
DECLARE_VGUI_SCREEN_FACTORY( CResourcePumpControlPanel, "resourcepump_control_panel" );
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Constructor:
|
||||
//-----------------------------------------------------------------------------
|
||||
CResourcePumpControlPanel::CResourcePumpControlPanel( vgui::Panel *parent, const char *panelName )
|
||||
: BaseClass( parent, "CResourcePumpControlPanel" )
|
||||
{
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Initialization
|
||||
//-----------------------------------------------------------------------------
|
||||
bool CResourcePumpControlPanel::Init( KeyValues* pKeyValues, VGuiScreenInitData_t* pInitData )
|
||||
{
|
||||
m_pUpgradeButton = new CBitmapButton( this, "UpgradeButton", "Upgrade" );
|
||||
m_pResourcesLabel = new vgui::Label( this, "ResourcesLabel", "Resources: 0" );
|
||||
|
||||
if (!BaseClass::Init(pKeyValues, pInitData))
|
||||
return false;
|
||||
|
||||
// ROBIN: Removed upgrading for now
|
||||
m_pUpgradeButton->SetVisible( false );
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Frame-based update
|
||||
//-----------------------------------------------------------------------------
|
||||
void CResourcePumpControlPanel::OnTick()
|
||||
{
|
||||
BaseClass::OnTick();
|
||||
|
||||
C_BaseObject *pObj = GetOwningObject();
|
||||
if (!pObj)
|
||||
return;
|
||||
|
||||
Assert( dynamic_cast<C_ObjectResourcePump*>(pObj) );
|
||||
C_ObjectResourcePump *pPump = static_cast<C_ObjectResourcePump*>(pObj);
|
||||
|
||||
char buf[256];
|
||||
int iPumpLevel = pPump->GetLevel();
|
||||
int iCost = CalculateObjectUpgrade( OBJ_RESOURCEPUMP, iPumpLevel );
|
||||
if ( iCost )
|
||||
{
|
||||
Q_snprintf( buf, sizeof( buf ), "Upgrade to Level %d\nCost: %d", iPumpLevel+1, iCost );
|
||||
}
|
||||
else
|
||||
{
|
||||
Q_snprintf( buf, sizeof( buf ), "Level %d", iPumpLevel );
|
||||
}
|
||||
|
||||
m_pUpgradeButton->SetText( buf );
|
||||
|
||||
C_ResourceZone *pResourceZone = pPump->GetResourceZone();
|
||||
if (pResourceZone)
|
||||
{
|
||||
Q_snprintf( buf, sizeof( buf ), "Resources: %d", pResourceZone->m_nResourcesLeft );
|
||||
m_pResourcesLabel->SetText( buf );
|
||||
}
|
||||
else
|
||||
{
|
||||
m_pResourcesLabel->SetText( "Resources: 0" );
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Dismantles the object
|
||||
//-----------------------------------------------------------------------------
|
||||
void CResourcePumpControlPanel::Upgrade( void )
|
||||
{
|
||||
C_BaseObject *pObj = GetOwningObject();
|
||||
if (pObj)
|
||||
{
|
||||
pObj->SendClientCommand( "upgrade" );
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Button click handlers
|
||||
//-----------------------------------------------------------------------------
|
||||
void CResourcePumpControlPanel::OnCommand( const char *command )
|
||||
{
|
||||
if (!Q_strnicmp(command, "Upgrade", 7))
|
||||
{
|
||||
Upgrade();
|
||||
return;
|
||||
}
|
||||
|
||||
BaseClass::OnCommand(command);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,44 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================//
|
||||
|
||||
#ifndef C_OBJ_RESOURCEPUMP_H
|
||||
#define C_OBJ_RESOURCEPUMP_H
|
||||
#ifdef _WIN32
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include "CommanderOverlay.h"
|
||||
#include "c_baseobject.h"
|
||||
|
||||
class C_ResourceZone;
|
||||
|
||||
class C_ObjectResourcePump : public C_BaseObject
|
||||
{
|
||||
DECLARE_CLASS( C_ObjectResourcePump, C_BaseObject );
|
||||
public:
|
||||
DECLARE_CLIENTCLASS();
|
||||
DECLARE_ENTITY_PANEL();
|
||||
|
||||
C_ObjectResourcePump();
|
||||
|
||||
virtual void SetDormant( bool bDormant );
|
||||
int GetLevel( void ) { return m_iPumpLevel; }
|
||||
|
||||
C_ResourceZone* GetResourceZone() { return m_hResourceZone.Get(); }
|
||||
|
||||
private:
|
||||
CHealthBarPanel *m_pResourceBar;
|
||||
int m_iPumpLevel;
|
||||
CHandle<C_ResourceZone> m_hResourceZone;
|
||||
|
||||
private:
|
||||
C_ObjectResourcePump( const C_ObjectResourcePump & ); // not defined, not accessible
|
||||
};
|
||||
|
||||
|
||||
|
||||
#endif // C_OBJ_RESOURCEPUMP_H
|
||||
@@ -0,0 +1,38 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose: Client's CObjectSentrygun
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================//
|
||||
#include "cbase.h"
|
||||
#include "hud.h"
|
||||
#include "CommanderOverlay.h"
|
||||
#include "c_baseobject.h"
|
||||
#include "vgui_healthbar.h"
|
||||
#include "c_obj_respawn_station.h"
|
||||
#include "C_BaseTFPlayer.h"
|
||||
|
||||
// memdbgon must be the last include file in a .cpp file!!!
|
||||
#include "tier0/memdbgon.h"
|
||||
|
||||
|
||||
IMPLEMENT_CLIENTCLASS_DT(C_ObjectRespawnStation, DT_ObjectRespawnStation, CObjectRespawnStation)
|
||||
END_RECV_TABLE()
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
C_ObjectRespawnStation::C_ObjectRespawnStation( void )
|
||||
{
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void C_ObjectRespawnStation::SetDormant( bool bDormant )
|
||||
{
|
||||
BaseClass::SetDormant( bDormant );
|
||||
ENTITY_PANEL_ACTIVATE( "respawn_station", !bDormant );
|
||||
}
|
||||
|
||||
@@ -0,0 +1,39 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================//
|
||||
|
||||
#ifndef C_OBJ_RESPAWN_STATION_H
|
||||
#define C_OBJ_RESPAWN_STATION_H
|
||||
#ifdef _WIN32
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Respawn Station object
|
||||
//-----------------------------------------------------------------------------
|
||||
class C_ObjectRespawnStation : public C_BaseObject
|
||||
{
|
||||
DECLARE_CLASS( C_ObjectRespawnStation, C_BaseObject );
|
||||
|
||||
public:
|
||||
DECLARE_CLIENTCLASS();
|
||||
DECLARE_ENTITY_PANEL();
|
||||
|
||||
C_ObjectRespawnStation();
|
||||
|
||||
// Status
|
||||
virtual void SetDormant( bool bDormant );
|
||||
|
||||
protected:
|
||||
// A special panel to indicate which one's the respawn station
|
||||
CPanelRegistration m_SelectedRespawnPanel;
|
||||
|
||||
private:
|
||||
C_ObjectRespawnStation( const C_ObjectRespawnStation & ); // not defined, not accessible
|
||||
};
|
||||
|
||||
|
||||
#endif // C_OBJ_RESPAWN_STATION_H
|
||||
@@ -0,0 +1,151 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose: Client's CObjectSentrygun
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================//
|
||||
#include "cbase.h"
|
||||
#include "c_baseobject.h"
|
||||
#include "c_basetfplayer.h"
|
||||
#include "ObjectControlPanel.h"
|
||||
#include "vgui_bitmapbutton.h"
|
||||
|
||||
// memdbgon must be the last include file in a .cpp file!!!
|
||||
#include "tier0/memdbgon.h"
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Resupply Station object
|
||||
//-----------------------------------------------------------------------------
|
||||
class C_ObjectResupply : public C_BaseObject
|
||||
{
|
||||
DECLARE_CLASS( C_ObjectResupply, C_BaseObject );
|
||||
public:
|
||||
DECLARE_CLIENTCLASS();
|
||||
|
||||
C_ObjectResupply();
|
||||
|
||||
private:
|
||||
C_ObjectResupply( const C_ObjectResupply & ); // not defined, not accessible
|
||||
};
|
||||
|
||||
|
||||
IMPLEMENT_CLIENTCLASS_DT(C_ObjectResupply, DT_ObjectResupply, CObjectResupply)
|
||||
END_RECV_TABLE()
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
C_ObjectResupply::C_ObjectResupply()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Control screen
|
||||
//-----------------------------------------------------------------------------
|
||||
class CResupplyControlPanel : public CObjectControlPanel
|
||||
{
|
||||
DECLARE_CLASS( CResupplyControlPanel, CObjectControlPanel );
|
||||
|
||||
public:
|
||||
CResupplyControlPanel( vgui::Panel *parent, const char *panelName );
|
||||
virtual bool Init( KeyValues* pKeyValues, VGuiScreenInitData_t* pInitData );
|
||||
virtual void OnCommand( const char *command );
|
||||
|
||||
protected:
|
||||
virtual void OnTickActive( C_BaseObject *pObj, C_BaseTFPlayer *pLocalPlayer );
|
||||
|
||||
private:
|
||||
void Buy( ResupplyBuyType_t type );
|
||||
|
||||
vgui::Button *m_pBuyAmmoButton;
|
||||
vgui::Button *m_pBuyGrenadesButton;
|
||||
vgui::Button *m_pBuyHealthButton;
|
||||
vgui::Button *m_pBuyAllButton;
|
||||
};
|
||||
|
||||
|
||||
DECLARE_VGUI_SCREEN_FACTORY( CResupplyControlPanel, "resupply_control_panel" );
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Constructor:
|
||||
//-----------------------------------------------------------------------------
|
||||
CResupplyControlPanel::CResupplyControlPanel( vgui::Panel *parent, const char *panelName )
|
||||
: BaseClass( parent, "CResupplyControlPanel" )
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Initialization
|
||||
//-----------------------------------------------------------------------------
|
||||
bool CResupplyControlPanel::Init( KeyValues* pKeyValues, VGuiScreenInitData_t* pInitData )
|
||||
{
|
||||
// Grab ahold of certain well-known controls
|
||||
m_pBuyAmmoButton = new CBitmapButton( GetActivePanel(), "BuyAmmoButton", "" );
|
||||
m_pBuyGrenadesButton = new CBitmapButton( GetActivePanel(), "BuyGrenadesButton", "" );
|
||||
m_pBuyHealthButton = new CBitmapButton( GetActivePanel(), "BuyHealthButton", "" );
|
||||
m_pBuyAllButton = new CBitmapButton( GetActivePanel(), "BuyAllButton", "" );
|
||||
|
||||
return BaseClass::Init( pKeyValues, pInitData );
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Deactivates buttons we can't afford
|
||||
//-----------------------------------------------------------------------------
|
||||
void CResupplyControlPanel::OnTickActive( C_BaseObject *pObj, C_BaseTFPlayer *pLocalPlayer )
|
||||
{
|
||||
BaseClass::OnTickActive( pObj, pLocalPlayer );
|
||||
|
||||
int nBankResources = pLocalPlayer ? pLocalPlayer->GetBankResources() : 0;
|
||||
m_pBuyAmmoButton->SetEnabled( nBankResources >= RESUPPLY_AMMO_COST );
|
||||
m_pBuyGrenadesButton->SetEnabled( nBankResources >= RESUPPLY_GRENADES_COST );
|
||||
m_pBuyHealthButton->SetEnabled( nBankResources >= RESUPPLY_HEALTH_COST );
|
||||
m_pBuyAllButton->SetEnabled( nBankResources >= RESUPPLY_ALL_COST );
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Buys stuff
|
||||
//-----------------------------------------------------------------------------
|
||||
void CResupplyControlPanel::Buy( ResupplyBuyType_t type )
|
||||
{
|
||||
C_BaseObject *pObj = GetOwningObject();
|
||||
if (pObj)
|
||||
{
|
||||
char szbuf[48];
|
||||
Q_snprintf( szbuf, sizeof( szbuf ), "buy %d", type );
|
||||
pObj->SendClientCommand( szbuf );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Button click handlers
|
||||
//-----------------------------------------------------------------------------
|
||||
void CResupplyControlPanel::OnCommand( const char *command )
|
||||
{
|
||||
if (!Q_strnicmp(command, "BuyAmmo", 8))
|
||||
{
|
||||
Buy(RESUPPLY_BUY_AMMO);
|
||||
}
|
||||
else if (!Q_strnicmp(command, "BuyHealth", 10))
|
||||
{
|
||||
Buy(RESUPPLY_BUY_HEALTH);
|
||||
}
|
||||
else if (!Q_strnicmp(command, "BuyGrenades", 12))
|
||||
{
|
||||
Buy(RESUPPLY_BUY_GRENADES);
|
||||
}
|
||||
else if (!Q_strnicmp(command, "BuyAll", 7))
|
||||
{
|
||||
Buy(RESUPPLY_BUY_ALL);
|
||||
}
|
||||
else
|
||||
{
|
||||
BaseClass::OnCommand(command);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
//=============================================================================//
|
||||
|
||||
#include "cbase.h"
|
||||
#include "hud.h"
|
||||
#include "commanderoverlay.h"
|
||||
#include "c_baseobject.h"
|
||||
|
||||
// memdbgon must be the last include file in a .cpp file!!!
|
||||
#include "tier0/memdbgon.h"
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
class C_ObjectSandbagBunker : public C_BaseObject
|
||||
{
|
||||
DECLARE_CLASS( C_ObjectSandbagBunker, C_BaseObject );
|
||||
public:
|
||||
DECLARE_CLIENTCLASS();
|
||||
|
||||
C_ObjectSandbagBunker();
|
||||
|
||||
private:
|
||||
C_ObjectSandbagBunker( const C_ObjectSandbagBunker & ); // not defined, not accessible
|
||||
};
|
||||
|
||||
IMPLEMENT_CLIENTCLASS_DT(C_ObjectSandbagBunker, DT_ObjectSandbagBunker, CObjectSandbagBunker)
|
||||
END_RECV_TABLE()
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
C_ObjectSandbagBunker::C_ObjectSandbagBunker()
|
||||
{
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
//=============================================================================//
|
||||
|
||||
#include "cbase.h"
|
||||
#include "hud.h"
|
||||
#include "commanderoverlay.h"
|
||||
#include "tf_obj_baseupgrade_shared.h"
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
class C_ObjectSelfHeal : public C_BaseObjectUpgrade
|
||||
{
|
||||
DECLARE_CLASS( C_ObjectSelfHeal, C_BaseObjectUpgrade );
|
||||
public:
|
||||
DECLARE_CLIENTCLASS();
|
||||
|
||||
C_ObjectSelfHeal();
|
||||
|
||||
private:
|
||||
C_ObjectSelfHeal( const C_ObjectSelfHeal & ); // not defined, not accessible
|
||||
};
|
||||
|
||||
IMPLEMENT_CLIENTCLASS_DT(C_ObjectSelfHeal, DT_ObjectSelfHeal, CObjectSelfHeal)
|
||||
END_RECV_TABLE()
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
C_ObjectSelfHeal::C_ObjectSelfHeal()
|
||||
{
|
||||
}
|
||||
|
||||
@@ -0,0 +1,106 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================//
|
||||
|
||||
#ifndef C_OBJ_SENTRYGUN_H
|
||||
#define C_OBJ_SENTRYGUN_H
|
||||
#ifdef _WIN32
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Base Sentrygun
|
||||
//-----------------------------------------------------------------------------
|
||||
class C_ObjectSentrygun : public C_BaseObject
|
||||
{
|
||||
DECLARE_CLASS( C_ObjectSentrygun, C_BaseObject );
|
||||
public:
|
||||
DECLARE_CLIENTCLASS();
|
||||
DECLARE_ENTITY_PANEL();
|
||||
|
||||
C_ObjectSentrygun();
|
||||
virtual void GetBoneControllers(float controllers[MAXSTUDIOBONES]);
|
||||
virtual int DrawModel( int flags );
|
||||
virtual void SetDormant( bool bDormant );
|
||||
virtual void PreDataUpdate( DataUpdateType_t updateType );
|
||||
virtual void PostDataUpdate( DataUpdateType_t updateType );
|
||||
virtual void OnDataChanged( DataUpdateType_t updateType );
|
||||
virtual float GetInitialBuilderYaw();
|
||||
int GetAmmoLeft( void ) { return m_iAmmo; }
|
||||
virtual void FinishedBuilding( void );
|
||||
|
||||
virtual void ClientThink( void );
|
||||
|
||||
private:
|
||||
bool IsTurtled( void ) { return m_bTurtled; }
|
||||
|
||||
// Turret Functions
|
||||
bool MoveTurret( void );
|
||||
|
||||
// Recompute sentrygun orientation...
|
||||
void RecomputeOrientation();
|
||||
|
||||
public:
|
||||
|
||||
int m_iRightBound;
|
||||
int m_iLeftBound;
|
||||
bool m_bTurningRight;
|
||||
|
||||
// Movement
|
||||
int m_iBaseTurnRate;
|
||||
float m_fTurnRate;
|
||||
QAngle m_vecCurAngles;
|
||||
QAngle m_vecGoalAngles;
|
||||
Vector m_vecCurDishAngles;
|
||||
|
||||
float m_fBoneXRotator;
|
||||
float m_fBoneYRotator;
|
||||
int m_iAmmo;
|
||||
|
||||
// Turtling
|
||||
bool m_bTurtled;
|
||||
bool m_bLastTurtled;
|
||||
float m_flStartedTurtlingAt;
|
||||
float m_flStartedUnTurtlingAt;
|
||||
|
||||
int m_nAnimationParity;
|
||||
int m_nLastAnimationParity;
|
||||
|
||||
// Networked from server
|
||||
EHANDLE m_hEnemy;
|
||||
|
||||
|
||||
QAngle m_angPrevLocalAngles;
|
||||
int m_nOrientationParity;
|
||||
int m_nPrevOrientationParity;
|
||||
|
||||
private:
|
||||
C_ObjectSentrygun( const C_ObjectSentrygun & ); // not defined, not accessible
|
||||
};
|
||||
|
||||
class C_ObjectSentrygunPlasma : public C_ObjectSentrygun
|
||||
{
|
||||
DECLARE_CLASS( C_ObjectSentrygunPlasma, C_ObjectSentrygun );
|
||||
public:
|
||||
C_ObjectSentrygunPlasma();
|
||||
DECLARE_CLIENTCLASS();
|
||||
|
||||
private:
|
||||
C_ObjectSentrygunPlasma( const C_ObjectSentrygunPlasma & ); // not defined, not accessible
|
||||
};
|
||||
|
||||
class C_ObjectSentrygunRocketlauncher : public C_ObjectSentrygun
|
||||
{
|
||||
DECLARE_CLASS( C_ObjectSentrygunRocketlauncher, C_ObjectSentrygun );
|
||||
public:
|
||||
C_ObjectSentrygunRocketlauncher();
|
||||
DECLARE_CLIENTCLASS();
|
||||
|
||||
private:
|
||||
C_ObjectSentrygunRocketlauncher( const C_ObjectSentrygunRocketlauncher & ); // not defined, not accessible
|
||||
};
|
||||
|
||||
#endif // C_OBJ_SENTRYGUN_H
|
||||
@@ -0,0 +1,111 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose: Client's CObjectSentrygun
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================//
|
||||
#include "cbase.h"
|
||||
#include "hud.h"
|
||||
#include "CommanderOverlay.h"
|
||||
#include "c_baseobject.h"
|
||||
#include "vgui_healthbar.h"
|
||||
#include "ObjectControlPanel.h"
|
||||
#include "c_shield.h"
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Resupply Station object
|
||||
//-----------------------------------------------------------------------------
|
||||
class C_ObjectShieldWallBase : public C_BaseObject
|
||||
{
|
||||
DECLARE_CLASS( C_ObjectShieldWallBase, C_BaseObject );
|
||||
|
||||
public:
|
||||
C_ObjectShieldWallBase() {}
|
||||
|
||||
public:
|
||||
CHandle<C_Shield> m_hDeployedShield;
|
||||
|
||||
private:
|
||||
C_ObjectShieldWallBase( const C_ObjectShieldWallBase & ); // not defined, not accessible
|
||||
};
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
// Projected shield wall
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
class C_ObjectShieldWall : public C_ObjectShieldWallBase
|
||||
{
|
||||
DECLARE_CLASS( C_ObjectShieldWall, C_ObjectShieldWallBase );
|
||||
public:
|
||||
DECLARE_CLIENTCLASS();
|
||||
DECLARE_ENTITY_PANEL();
|
||||
|
||||
C_ObjectShieldWall( void );
|
||||
|
||||
virtual void SetDormant( bool bDormant );
|
||||
virtual void RecalculateIDString( void );
|
||||
|
||||
private:
|
||||
C_ObjectShieldWall( const C_ObjectShieldWall & ); // not defined, not accessible
|
||||
};
|
||||
|
||||
IMPLEMENT_CLIENTCLASS_DT(C_ObjectShieldWall, DT_ObjectShieldWall, CObjectShieldWall)
|
||||
RecvPropEHandle(RECVINFO(m_hDeployedShield)),
|
||||
END_RECV_TABLE()
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
C_ObjectShieldWall::C_ObjectShieldWall( void )
|
||||
{
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void C_ObjectShieldWall::SetDormant( bool bDormant )
|
||||
{
|
||||
BaseClass::SetDormant( bDormant );
|
||||
ENTITY_PANEL_ACTIVATE( "shield_wall", !bDormant );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void C_ObjectShieldWall::RecalculateIDString( void )
|
||||
{
|
||||
if ( m_hDeployedShield )
|
||||
{
|
||||
// Report shield strength
|
||||
Q_snprintf( m_szIDString, sizeof(m_szIDString), "Shield Strength: %.0f percent", m_hDeployedShield->GetPowerLevel() * 100 );
|
||||
}
|
||||
|
||||
BaseClass::RecalculateIDString();
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Control screen
|
||||
//-----------------------------------------------------------------------------
|
||||
class CShieldWallControlPanel : public CRotatingObjectControlPanel
|
||||
{
|
||||
DECLARE_CLASS( CShieldWallControlPanel, CRotatingObjectControlPanel );
|
||||
|
||||
public:
|
||||
CShieldWallControlPanel( vgui::Panel *parent, const char *panelName );
|
||||
};
|
||||
|
||||
|
||||
DECLARE_VGUI_SCREEN_FACTORY( CShieldWallControlPanel, "shieldwall_control_panel" );
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Constructor:
|
||||
//-----------------------------------------------------------------------------
|
||||
CShieldWallControlPanel::CShieldWallControlPanel( vgui::Panel *parent, const char *panelName )
|
||||
: BaseClass( parent, "CShieldWallControlPanel" )
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,69 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
//=============================================================================//
|
||||
|
||||
#include "cbase.h"
|
||||
#include "hud.h"
|
||||
#include "commanderoverlay.h"
|
||||
#include "c_baseobject.h"
|
||||
|
||||
// memdbgon must be the last include file in a .cpp file!!!
|
||||
#include "tier0/memdbgon.h"
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
class C_ObjectTower : public C_BaseObject
|
||||
{
|
||||
DECLARE_CLASS( C_ObjectTower, C_BaseObject );
|
||||
public:
|
||||
DECLARE_CLIENTCLASS();
|
||||
|
||||
C_ObjectTower();
|
||||
|
||||
private:
|
||||
C_ObjectTower( const C_ObjectTower & ); // not defined, not accessible
|
||||
};
|
||||
|
||||
IMPLEMENT_CLIENTCLASS_DT(C_ObjectTower, DT_ObjectTower, CObjectTower)
|
||||
END_RECV_TABLE()
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
C_ObjectTower::C_ObjectTower()
|
||||
{
|
||||
}
|
||||
|
||||
//=============================================================================
|
||||
// Tower Ladder
|
||||
//=============================================================================
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
class C_ObjectTowerLadder : public C_BaseAnimating
|
||||
{
|
||||
DECLARE_CLASS( C_ObjectTowerLadder, C_BaseAnimating );
|
||||
public:
|
||||
|
||||
DECLARE_CLIENTCLASS();
|
||||
|
||||
C_ObjectTowerLadder();
|
||||
|
||||
private:
|
||||
C_ObjectTowerLadder( const C_ObjectTowerLadder& ); // not defined, not accessible
|
||||
};
|
||||
|
||||
IMPLEMENT_CLIENTCLASS_DT( C_ObjectTowerLadder, DT_ObjectTowerLadder, CObjectTowerLadder )
|
||||
END_RECV_TABLE()
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
C_ObjectTowerLadder::C_ObjectTowerLadder()
|
||||
{
|
||||
}
|
||||
|
||||
@@ -0,0 +1,143 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================//
|
||||
|
||||
#include "cbase.h"
|
||||
#include "hud.h"
|
||||
#include "c_obj_mapdefined.h"
|
||||
#include "minimap_trace.h"
|
||||
#include <KeyValues.h>
|
||||
#include "VGuiMatSurface/IMatSystemSurface.h"
|
||||
|
||||
// memdbgon must be the last include file in a .cpp file!!!
|
||||
#include "tier0/memdbgon.h"
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
class C_ObjectTunnel : public C_ObjectMapDefined
|
||||
{
|
||||
DECLARE_CLASS( C_ObjectTunnel, C_ObjectMapDefined );
|
||||
public:
|
||||
DECLARE_PREDICTABLE();
|
||||
DECLARE_CLIENTCLASS();
|
||||
|
||||
C_ObjectTunnel();
|
||||
|
||||
private:
|
||||
C_ObjectTunnel( const C_ObjectTunnel& src );
|
||||
};
|
||||
|
||||
LINK_ENTITY_TO_CLASS( obj_tunnel, C_ObjectTunnel );
|
||||
BEGIN_PREDICTION_DATA( C_ObjectTunnel )
|
||||
END_PREDICTION_DATA();
|
||||
|
||||
|
||||
IMPLEMENT_CLIENTCLASS_DT(C_ObjectTunnel, DT_ObjectTunnel, CObjectTunnel)
|
||||
END_RECV_TABLE()
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
C_ObjectTunnel::C_ObjectTunnel()
|
||||
{
|
||||
CONSTRUCT_MINIMAP_PANEL( "obj_tunnel", MINIMAP_OBJECTS );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
class CMinimapObjectTunnelPanel : public CMinimapTraceTeamBitmapPanel
|
||||
{
|
||||
DECLARE_CLASS( CMinimapObjectTunnelPanel, CMinimapTraceTeamBitmapPanel );
|
||||
|
||||
public:
|
||||
CMinimapObjectTunnelPanel( vgui::Panel *parent, const char *panelName )
|
||||
: BaseClass( parent, "CMinimapObjectTunnelPanel" )
|
||||
{
|
||||
}
|
||||
|
||||
virtual bool Init( KeyValues* pKeyValues, MinimapInitData_t* pInitData );
|
||||
virtual void Paint();
|
||||
|
||||
private:
|
||||
enum
|
||||
{
|
||||
STATE_ENABLED = 0,
|
||||
STATE_DISABLED,
|
||||
|
||||
NUM_STATES
|
||||
};
|
||||
|
||||
CTeamBitmapImage m_TeamImage[ NUM_STATES ];
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
// A standard minimap renderable that displays a bitmap that changes when team changes
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
DECLARE_MINIMAP_FACTORY( CMinimapObjectTunnelPanel, "minimap_obj_tunnel_panel" );
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
// Input : pKeyValues -
|
||||
// pInitData -
|
||||
// Output : Returns true on success, false on failure.
|
||||
//-----------------------------------------------------------------------------
|
||||
bool CMinimapObjectTunnelPanel::Init( KeyValues* pKeyValues, MinimapInitData_t* pInitData )
|
||||
{
|
||||
if (!BaseClass::Init(pKeyValues, pInitData))
|
||||
return false;
|
||||
|
||||
// Load viewcone material
|
||||
KeyValues *enabled = pKeyValues->FindKey( "EnabledImage" );
|
||||
if ( enabled )
|
||||
{
|
||||
if ( !m_TeamImage[ STATE_ENABLED ].Init( this, enabled, pInitData->m_pEntity ) )
|
||||
return false;
|
||||
}
|
||||
|
||||
KeyValues *disabled = pKeyValues->FindKey( "DisabledImage" );
|
||||
if ( disabled )
|
||||
{
|
||||
if ( !m_TeamImage[ STATE_DISABLED ].Init( this, disabled, pInitData->m_pEntity ) )
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void CMinimapObjectTunnelPanel::Paint()
|
||||
{
|
||||
// Draw the view cone
|
||||
C_BaseEntity *pEntity = GetEntity();
|
||||
Assert( pEntity );
|
||||
|
||||
if ( gHUD.IsHidden( HIDEHUD_MISCSTATUS ) )
|
||||
return;
|
||||
|
||||
if ( !pEntity->IsBaseObject() )
|
||||
return;
|
||||
|
||||
C_BaseObject *obj = static_cast< C_BaseObject * >( pEntity );
|
||||
Assert( obj );
|
||||
|
||||
bool enabled = !obj->IsDisabled();
|
||||
int image = enabled ? STATE_ENABLED : STATE_DISABLED;
|
||||
|
||||
if (!m_bClipToMap)
|
||||
{
|
||||
g_pMatSystemSurface->DisableClipping( true );
|
||||
}
|
||||
m_TeamImage[ image ].SetAlpha( ComputePanelAlpha() );
|
||||
m_TeamImage[ image ].Paint();
|
||||
g_pMatSystemSurface->DisableClipping( false );
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
//=============================================================================//
|
||||
|
||||
#include "cbase.h"
|
||||
#include "hud.h"
|
||||
#include "commanderoverlay.h"
|
||||
#include "tf_obj_baseupgrade_shared.h"
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
class C_ObjectVehicleBoost : public C_BaseObjectUpgrade
|
||||
{
|
||||
|
||||
DECLARE_CLASS( C_ObjectVehicleBoost, C_BaseObjectUpgrade );
|
||||
|
||||
public:
|
||||
|
||||
DECLARE_CLIENTCLASS();
|
||||
|
||||
C_ObjectVehicleBoost();
|
||||
|
||||
private:
|
||||
|
||||
C_ObjectVehicleBoost( const C_ObjectVehicleBoost& ); // not defined, not accessible
|
||||
};
|
||||
|
||||
IMPLEMENT_CLIENTCLASS_DT( C_ObjectVehicleBoost, DT_ObjectVehicleBoost, CObjectVehicleBoost )
|
||||
END_RECV_TABLE()
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
C_ObjectVehicleBoost::C_ObjectVehicleBoost()
|
||||
{
|
||||
}
|
||||
|
||||
@@ -0,0 +1,558 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose: Client's CObjectSentrygun
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================//
|
||||
#include "cbase.h"
|
||||
#include "bone_setup.h"
|
||||
#include "CommanderOverlay.h"
|
||||
#include "c_baseobject.h"
|
||||
#include "C_Obj_SentryGun.h"
|
||||
#include "tf_shareddefs.h"
|
||||
#include "c_basetfplayer.h"
|
||||
#include "ObjectControlPanel.h"
|
||||
#include <vgui_controls/Button.h>
|
||||
|
||||
inline float UTIL_AngleMod(float a)
|
||||
{
|
||||
return anglemod(a);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Base Sentrygun
|
||||
//-----------------------------------------------------------------------------
|
||||
BEGIN_RECV_TABLE_NOBASE(C_ObjectSentrygun, DT_SentrygunTeamOnlyVars)
|
||||
RecvPropInt(RECVINFO( m_iAmmo )),
|
||||
END_RECV_TABLE()
|
||||
|
||||
IMPLEMENT_CLIENTCLASS_DT(C_ObjectSentrygun, DT_ObjectSentrygun, CObjectSentrygun)
|
||||
RecvPropInt( RECVINFO( m_iBaseTurnRate ) ),
|
||||
RecvPropEHandle(RECVINFO(m_hEnemy)),
|
||||
RecvPropDataTable( "teamonly", 0, 0, &REFERENCE_RECV_TABLE( DT_SentrygunTeamOnlyVars )),
|
||||
RecvPropInt(RECVINFO(m_bTurtled)),
|
||||
RecvPropInt( RECVINFO( m_nAnimationParity ) ),
|
||||
RecvPropInt( RECVINFO( m_nOrientationParity ) ),
|
||||
END_RECV_TABLE()
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
C_ObjectSentrygun::C_ObjectSentrygun()
|
||||
{
|
||||
m_fBoneXRotator = 0;
|
||||
m_fBoneYRotator = 0;
|
||||
m_iAmmo = 0;
|
||||
m_bTurtled = false;
|
||||
m_flStartedTurtlingAt = 0;
|
||||
m_flStartedUnTurtlingAt = 0;
|
||||
|
||||
SetViewOffset( Vector(0,0,22) );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void C_ObjectSentrygun::SetDormant( bool bDormant )
|
||||
{
|
||||
BaseClass::SetDormant( bDormant );
|
||||
ENTITY_PANEL_ACTIVATE( "sentrygun", !bDormant );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
int C_ObjectSentrygun::DrawModel( int flags )
|
||||
{
|
||||
float flRealOriginZ = GetLocalOrigin().z;
|
||||
|
||||
// If we're turtling, slide the model into the ground
|
||||
if ( m_bTurtled )
|
||||
{
|
||||
// How far down are we?
|
||||
float flTime = MIN( gpGlobals->curtime - m_flStartedTurtlingAt, SENTRY_TURTLE_TIME );
|
||||
float flPercent = 1 - (SENTRY_TURTLE_TIME - flTime) / SENTRY_TURTLE_TIME;
|
||||
|
||||
// FIXME: This is totally wrong!!!
|
||||
Vector vNewOrigin = GetLocalOrigin();
|
||||
vNewOrigin.z -= (CollisionProp()->OBBSize().z * flPercent);
|
||||
SetLocalOrigin( vNewOrigin );
|
||||
InvalidateBoneCache();
|
||||
}
|
||||
else if ( !m_bTurtled )
|
||||
{
|
||||
if ( m_flStartedUnTurtlingAt )
|
||||
{
|
||||
float flTime = MIN( gpGlobals->curtime - m_flStartedUnTurtlingAt, SENTRY_TURTLE_TIME );
|
||||
float flPercent = (SENTRY_TURTLE_TIME - flTime) / SENTRY_TURTLE_TIME;
|
||||
|
||||
// FIXME: This is totally wrong!!!
|
||||
Vector vNewOrigin = GetLocalOrigin();
|
||||
vNewOrigin.z -= (CollisionProp()->OBBSize().z * flPercent);
|
||||
SetLocalOrigin( vNewOrigin );
|
||||
InvalidateBoneCache();
|
||||
|
||||
// Fully unturtled?
|
||||
if ( flTime >= SENTRY_TURTLE_TIME )
|
||||
{
|
||||
m_flStartedUnTurtlingAt = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int drawn = BaseClass::DrawModel( flags );
|
||||
SetLocalOriginDim( Z_INDEX, flRealOriginZ );
|
||||
|
||||
return drawn;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void C_ObjectSentrygun::PreDataUpdate( DataUpdateType_t updateType )
|
||||
{
|
||||
BaseClass::PreDataUpdate( updateType );
|
||||
|
||||
m_bLastTurtled = m_bTurtled;
|
||||
m_nLastAnimationParity = m_nAnimationParity;
|
||||
m_angPrevLocalAngles = GetLocalAngles();
|
||||
m_nPrevOrientationParity = m_nOrientationParity;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void C_ObjectSentrygun::PostDataUpdate( DataUpdateType_t updateType )
|
||||
{
|
||||
BaseClass::PostDataUpdate( updateType );
|
||||
|
||||
if ( m_bLastTurtled != m_bTurtled )
|
||||
{
|
||||
if ( m_bTurtled )
|
||||
{
|
||||
m_flStartedTurtlingAt = gpGlobals->curtime;
|
||||
m_flStartedUnTurtlingAt = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_flStartedUnTurtlingAt = gpGlobals->curtime;
|
||||
m_flStartedTurtlingAt = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if ( m_nLastAnimationParity != m_nAnimationParity )
|
||||
{
|
||||
SetCycle( 0.0f );
|
||||
}
|
||||
|
||||
bool changed = false;
|
||||
QAngle angleDiff;
|
||||
angleDiff = ( GetAbsAngles() - m_angPrevLocalAngles );
|
||||
for (int i = 0;i < 3; i++ )
|
||||
{
|
||||
angleDiff[i] = UTIL_AngleMod( angleDiff[ i ] );
|
||||
}
|
||||
|
||||
if ( angleDiff.Length() > 0.1f )
|
||||
{
|
||||
changed = true;
|
||||
}
|
||||
if ( updateType == DATA_UPDATE_CREATED || changed )
|
||||
{
|
||||
// Orient it
|
||||
m_vecCurAngles.y = UTIL_AngleMod( GetLocalAngles().y );
|
||||
RecomputeOrientation();
|
||||
}
|
||||
else if ( m_nPrevOrientationParity != m_nOrientationParity )
|
||||
{
|
||||
if ( changed )
|
||||
{
|
||||
RecomputeOrientation();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void C_ObjectSentrygun::OnDataChanged( DataUpdateType_t updateType )
|
||||
{
|
||||
BaseClass::OnDataChanged( updateType );
|
||||
|
||||
if ( updateType == DATA_UPDATE_CREATED )
|
||||
{
|
||||
// Start thinking (Baseclass stops it)
|
||||
SetNextClientThink( CLIENT_THINK_ALWAYS );
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void C_ObjectSentrygun::FinishedBuilding( void )
|
||||
{
|
||||
BaseClass::FinishedBuilding();
|
||||
|
||||
EmitSound( "ObjectSentrygun.Activate" );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void C_ObjectSentrygun::GetBoneControllers(float controllers[MAXSTUDIOBONECTRLS])
|
||||
{
|
||||
studiohdr_t *pModel = modelinfo->GetStudiomodel( GetModel() );
|
||||
|
||||
// When yaw preview is on,
|
||||
if (!IsPreviewingYaw())
|
||||
{
|
||||
Studio_SetController(pModel, 0, m_fBoneXRotator, controllers[0]);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Bone rotation == 0 here to make it exactly match the preview
|
||||
Studio_SetController(pModel, 0, 0, controllers[0]);
|
||||
}
|
||||
|
||||
Studio_SetController(pModel, 1, m_fBoneYRotator, controllers[1]);
|
||||
Studio_SetController(pModel, 2, m_fBoneYRotator, controllers[2]);
|
||||
Studio_SetController(pModel, 3, m_fBoneYRotator, controllers[3]);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: This is called to get the initial builder yaw...
|
||||
//-----------------------------------------------------------------------------
|
||||
float C_ObjectSentrygun::GetInitialBuilderYaw()
|
||||
{
|
||||
// Take the current rotation into account
|
||||
return GetAbsAngles().y + m_fBoneXRotator;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Called when a rotation happens
|
||||
//-----------------------------------------------------------------------------
|
||||
void C_ObjectSentrygun::RecomputeOrientation( )
|
||||
{
|
||||
m_iRightBound = UTIL_AngleMod( m_vecCurAngles.y - 50);
|
||||
m_iLeftBound = UTIL_AngleMod( m_vecCurAngles.y + 50);
|
||||
if ( m_iRightBound > m_iLeftBound )
|
||||
{
|
||||
m_iRightBound = m_iLeftBound;
|
||||
m_iLeftBound = UTIL_AngleMod( m_vecCurAngles.y - 50);
|
||||
}
|
||||
|
||||
// Start it rotating
|
||||
m_vecGoalAngles.y = m_iRightBound;;
|
||||
m_vecGoalAngles.x = m_vecCurAngles.x = 0;
|
||||
|
||||
m_fBoneXRotator = 0.0f;
|
||||
m_fBoneYRotator = 0.0f;
|
||||
|
||||
m_bTurningRight = true;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Handle movement of the turret
|
||||
//-----------------------------------------------------------------------------
|
||||
bool C_ObjectSentrygun::MoveTurret(void)
|
||||
{
|
||||
bool bMoved = 0;
|
||||
|
||||
float turnrate = (float)(m_iBaseTurnRate) * 10.0f;
|
||||
turnrate *= gpGlobals->frametime;
|
||||
|
||||
// any x movement?
|
||||
if ( m_vecCurAngles.x != m_vecGoalAngles.x )
|
||||
{
|
||||
float flDir = m_vecGoalAngles.x > m_vecCurAngles.x ? 1 : -1 ;
|
||||
|
||||
m_vecCurAngles.x += 0.1 * (turnrate * 5) * flDir;
|
||||
|
||||
// if we started below the goal, and now we're past, peg to goal
|
||||
if (flDir == 1)
|
||||
{
|
||||
if (m_vecCurAngles.x > m_vecGoalAngles.x)
|
||||
m_vecCurAngles.x = m_vecGoalAngles.x;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (m_vecCurAngles.x < m_vecGoalAngles.x)
|
||||
m_vecCurAngles.x = m_vecGoalAngles.x;
|
||||
}
|
||||
|
||||
m_fBoneYRotator = m_vecCurAngles.x;
|
||||
|
||||
bMoved = 1;
|
||||
}
|
||||
|
||||
if ( m_vecCurAngles.y != m_vecGoalAngles.y )
|
||||
{
|
||||
float flDir = m_vecGoalAngles.y > m_vecCurAngles.y ? 1 : -1 ;
|
||||
float flDist = fabs(m_vecGoalAngles.y - m_vecCurAngles.y);
|
||||
bool bReversed = false;
|
||||
|
||||
if (flDist > 180)
|
||||
{
|
||||
flDist = 360 - flDist;
|
||||
flDir = -flDir;
|
||||
bReversed = true;
|
||||
}
|
||||
|
||||
if (m_hEnemy == NULL )
|
||||
{
|
||||
if (flDist > 30)
|
||||
{
|
||||
if (m_fTurnRate < turnrate * 20)
|
||||
{
|
||||
m_fTurnRate += turnrate;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Slow down
|
||||
if ( m_fTurnRate > (turnrate * 5) )
|
||||
m_fTurnRate -= turnrate;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// When tracking enemies, move faster and don't slow
|
||||
if (flDist > 30)
|
||||
{
|
||||
if (m_fTurnRate < turnrate * 30)
|
||||
{
|
||||
m_fTurnRate += turnrate * 3;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
m_vecCurAngles.y += 0.1 * m_fTurnRate * flDir;
|
||||
|
||||
// if we passed over the goal, peg right to it now
|
||||
if (flDir == -1)
|
||||
{
|
||||
if ( (bReversed == false && m_vecGoalAngles.y > m_vecCurAngles.y) || (bReversed == true && m_vecGoalAngles.y < m_vecCurAngles.y) )
|
||||
m_vecCurAngles.y = m_vecGoalAngles.y;
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( (bReversed == false && m_vecGoalAngles.y < m_vecCurAngles.y) || (bReversed == true && m_vecGoalAngles.y > m_vecCurAngles.y) )
|
||||
m_vecCurAngles.y = m_vecGoalAngles.y;
|
||||
}
|
||||
|
||||
if (m_vecCurAngles.y < 0)
|
||||
m_vecCurAngles.y += 360;
|
||||
else if (m_vecCurAngles.y >= 360)
|
||||
m_vecCurAngles.y -= 360;
|
||||
|
||||
if (flDist < (0.05 * turnrate))
|
||||
m_vecCurAngles.y = m_vecGoalAngles.y;
|
||||
|
||||
m_fBoneXRotator = m_vecCurAngles.y - UTIL_AngleMod( GetAbsAngles().y );
|
||||
|
||||
bMoved = 1;
|
||||
}
|
||||
|
||||
if ( !bMoved || !m_fTurnRate )
|
||||
m_fTurnRate = turnrate;
|
||||
|
||||
if ( bMoved )
|
||||
{
|
||||
NetworkStateChanged();
|
||||
}
|
||||
|
||||
return bMoved;
|
||||
}
|
||||
|
||||
void C_ObjectSentrygun::ClientThink( void )
|
||||
{
|
||||
// Turtling sentryguns don't think
|
||||
if ( IsTurtled() )
|
||||
return;
|
||||
|
||||
if ( IsPlacing() || IsBuilding() )
|
||||
return;
|
||||
|
||||
|
||||
if ( m_hEnemy != NULL )
|
||||
{
|
||||
// Figure out where we're firing at
|
||||
Vector vecMid = EyePosition();
|
||||
Vector vecFireTarget = m_hEnemy->WorldSpaceCenter(); // + vecMid; // BodyTarget( vecMid );
|
||||
Vector vecDirToEnemy = vecFireTarget - vecMid;
|
||||
QAngle angToTarget;
|
||||
VectorAngles(vecDirToEnemy, angToTarget);
|
||||
|
||||
angToTarget.y = UTIL_AngleMod( angToTarget.y );
|
||||
if (angToTarget.x < -180)
|
||||
angToTarget.x += 360;
|
||||
if (angToTarget.x > 180)
|
||||
angToTarget.x -= 360;
|
||||
|
||||
// now all numbers should be in [1...360]
|
||||
// pin to turret limitations to [-50...50]
|
||||
if (angToTarget.x > 50)
|
||||
angToTarget.x = 50;
|
||||
else if (angToTarget.x < -50)
|
||||
angToTarget.x = -50;
|
||||
|
||||
m_vecGoalAngles.y = angToTarget.y;
|
||||
m_vecGoalAngles.x = angToTarget.x;
|
||||
|
||||
MoveTurret();
|
||||
return;
|
||||
}
|
||||
|
||||
// Rotate
|
||||
if ( !MoveTurret() )
|
||||
{
|
||||
// Play a sound occasionally
|
||||
if ( random->RandomFloat(0, 1) < 0.02 )
|
||||
{
|
||||
EmitSound( "ObjectSentrygun.Idle" );
|
||||
}
|
||||
|
||||
// Switch rotation direction
|
||||
if (m_bTurningRight)
|
||||
{
|
||||
m_bTurningRight = false;
|
||||
m_vecGoalAngles.y = m_iLeftBound;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_bTurningRight = true;
|
||||
m_vecGoalAngles.y = m_iRightBound;
|
||||
}
|
||||
|
||||
// Randomly look up and down a bit
|
||||
if ( random->RandomFloat(0, 1) < 0.3 )
|
||||
{
|
||||
m_vecGoalAngles.x = (int)random->RandomFloat(-10,10);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Control screen
|
||||
//-----------------------------------------------------------------------------
|
||||
class CSentrygunControlPanel : public CRotatingObjectControlPanel
|
||||
{
|
||||
DECLARE_CLASS( CSentrygunControlPanel, CRotatingObjectControlPanel );
|
||||
|
||||
public:
|
||||
CSentrygunControlPanel( vgui::Panel *parent, const char *panelName );
|
||||
virtual bool Init( KeyValues* pKeyValues, VGuiScreenInitData_t* pInitData );
|
||||
virtual void OnTick();
|
||||
virtual void OnCommand( const char *command );
|
||||
|
||||
void AddAmmo( void );
|
||||
|
||||
private:
|
||||
vgui::Label *m_pAmmoLabel;
|
||||
};
|
||||
|
||||
|
||||
DECLARE_VGUI_SCREEN_FACTORY( CSentrygunControlPanel, "sentrygun_control_panel" );
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Constructor:
|
||||
//-----------------------------------------------------------------------------
|
||||
CSentrygunControlPanel::CSentrygunControlPanel( vgui::Panel *parent, const char *panelName )
|
||||
: BaseClass( parent, "CSentrygunControlPanel" )
|
||||
{
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Initialization
|
||||
//-----------------------------------------------------------------------------
|
||||
bool CSentrygunControlPanel::Init( KeyValues* pKeyValues, VGuiScreenInitData_t* pInitData )
|
||||
{
|
||||
m_pAmmoLabel = new vgui::Label( this, "AmmoReadout", "" );
|
||||
|
||||
if (!BaseClass::Init(pKeyValues, pInitData))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Frame-based update
|
||||
//-----------------------------------------------------------------------------
|
||||
void CSentrygunControlPanel::OnTick()
|
||||
{
|
||||
BaseClass::OnTick();
|
||||
|
||||
C_BaseObject *pObj = GetOwningObject();
|
||||
if (!pObj)
|
||||
return;
|
||||
|
||||
Assert( dynamic_cast<C_ObjectSentrygun*>(pObj) );
|
||||
C_ObjectSentrygun *pSentrygun = static_cast<C_ObjectSentrygun*>(pObj);
|
||||
|
||||
char buf[256];
|
||||
int iAmmo = pSentrygun->GetAmmoLeft();
|
||||
if (iAmmo > 0)
|
||||
{
|
||||
Q_snprintf( buf, sizeof( buf ), "%d rounds left", iAmmo );
|
||||
}
|
||||
else
|
||||
{
|
||||
Q_snprintf( buf, sizeof( buf ), "OUT OF AMMO" );
|
||||
}
|
||||
m_pAmmoLabel->SetText( buf );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Handle ammo input to the sentrygun
|
||||
//-----------------------------------------------------------------------------
|
||||
void CSentrygunControlPanel::AddAmmo( void )
|
||||
{
|
||||
C_BaseObject *pObj = GetOwningObject();
|
||||
if (pObj)
|
||||
{
|
||||
pObj->SendClientCommand( "addammo" );
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Button click handlers
|
||||
//-----------------------------------------------------------------------------
|
||||
void CSentrygunControlPanel::OnCommand( const char *command )
|
||||
{
|
||||
if (!Q_strnicmp(command, "AddAmmo", 7))
|
||||
{
|
||||
AddAmmo();
|
||||
return;
|
||||
}
|
||||
|
||||
BaseClass::OnCommand(command);
|
||||
}
|
||||
|
||||
|
||||
|
||||
//======================================================================================================
|
||||
// SENTRYGUN TYPES
|
||||
//======================================================================================================
|
||||
// Purpose: Plasma sentrygun
|
||||
//-----------------------------------------------------------------------------
|
||||
IMPLEMENT_CLIENTCLASS_DT(C_ObjectSentrygunPlasma, DT_ObjectSentrygunPlasma, CObjectSentrygunPlasma)
|
||||
END_RECV_TABLE()
|
||||
|
||||
C_ObjectSentrygunPlasma::C_ObjectSentrygunPlasma()
|
||||
{
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Rocket launcher sentrygun
|
||||
//-----------------------------------------------------------------------------
|
||||
IMPLEMENT_CLIENTCLASS_DT(C_ObjectSentrygunRocketlauncher, DT_ObjectSentrygunRocketlauncher, CObjectSentrygunRocketlauncher)
|
||||
END_RECV_TABLE()
|
||||
|
||||
C_ObjectSentrygunRocketlauncher::C_ObjectSentrygunRocketlauncher()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,73 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose: Client Side COrder class
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================//
|
||||
|
||||
#ifndef C_ORDER_H
|
||||
#define C_ORDER_H
|
||||
#ifdef _WIN32
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include <vgui_controls/Label.h>
|
||||
#include <vgui_controls/Panel.h>
|
||||
#include "CommanderOverlay.h"
|
||||
#include "hud_minimap.h"
|
||||
|
||||
class COrderLabel;
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Datatable container class for orders
|
||||
//-----------------------------------------------------------------------------
|
||||
class C_Order : public C_BaseEntity
|
||||
{
|
||||
DECLARE_CLASS( C_Order, C_BaseEntity );
|
||||
public:
|
||||
DECLARE_CLIENTCLASS();
|
||||
|
||||
C_Order( void );
|
||||
~C_Order( void );
|
||||
|
||||
virtual void ClientThink( void );
|
||||
virtual void OnDataChanged( DataUpdateType_t updateType );
|
||||
virtual void RemoveOrder( void );
|
||||
virtual void GetDescription( char *pDest, int bufferSize );
|
||||
virtual void GetTargetDescription( char *pDest, int bufferSize );
|
||||
|
||||
// Status drawing
|
||||
virtual void CreateStatus( vgui::Panel *pParent );
|
||||
virtual void DestroyStatus( void );
|
||||
virtual void UpdateStatus( void );
|
||||
virtual bool ShouldDrawReticle( void );
|
||||
|
||||
// Data access
|
||||
int GetPriority( void );
|
||||
int GetTarget( void );
|
||||
int GetType( void );
|
||||
bool IsPersonalOrder( void );
|
||||
|
||||
protected:
|
||||
// Received via datatable
|
||||
int m_iPriority;
|
||||
int m_iOrderType;
|
||||
int m_iTargetEntIndex;
|
||||
|
||||
// Used in status drawing
|
||||
COrderLabel *m_pNameLabel;
|
||||
|
||||
// Animating panel to show the new order.
|
||||
float m_flNewOrderHighlightTimer;
|
||||
|
||||
// Hook up the overlay on the tactical map.
|
||||
DECLARE_ENTITY_PANEL();
|
||||
DECLARE_MINIMAP_PANEL();
|
||||
|
||||
protected:
|
||||
int m_nHintID;
|
||||
};
|
||||
|
||||
|
||||
#endif // C_ORDER_H
|
||||
@@ -0,0 +1,22 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================//
|
||||
#include "cbase.h"
|
||||
#include "c_order_assist.h"
|
||||
|
||||
|
||||
IMPLEMENT_CLIENTCLASS_DT( C_OrderAssist, DT_OrderAssist, COrderAssist )
|
||||
END_RECV_TABLE()
|
||||
|
||||
|
||||
void C_OrderAssist::GetDescription( char *pDest, int bufferSize )
|
||||
{
|
||||
char targetDesc[512];
|
||||
GetTargetDescription( targetDesc, sizeof( targetDesc ) );
|
||||
|
||||
Q_snprintf( pDest, bufferSize, "Assist %s", targetDesc );
|
||||
}
|
||||
|
||||
@@ -0,0 +1,32 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================//
|
||||
|
||||
#ifndef C_ORDER_ASSIST_H
|
||||
#define C_ORDER_ASSIST_H
|
||||
#ifdef _WIN32
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
|
||||
#include "c_order_player.h"
|
||||
|
||||
|
||||
class C_OrderAssist : public C_OrderPlayer
|
||||
{
|
||||
public:
|
||||
DECLARE_CLASS( C_OrderAssist, C_OrderPlayer );
|
||||
DECLARE_CLIENTCLASS();
|
||||
|
||||
|
||||
// C_Order overrides.
|
||||
public:
|
||||
|
||||
virtual void GetDescription( char *pDest, int bufferSize );
|
||||
};
|
||||
|
||||
|
||||
#endif // C_ORDER_ASSIST_H
|
||||
@@ -0,0 +1,26 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================//
|
||||
#include "cbase.h"
|
||||
#include "c_order_buildsentrygun.h"
|
||||
#include "tf_hints.h"
|
||||
|
||||
|
||||
IMPLEMENT_CLIENTCLASS_DT( C_OrderBuildSentryGun, DT_OrderBuildSentryGun, COrderBuildSentryGun )
|
||||
END_RECV_TABLE()
|
||||
|
||||
|
||||
C_OrderBuildSentryGun::C_OrderBuildSentryGun()
|
||||
{
|
||||
m_nHintID = TF_HINT_BUILDSENTRYGUN_PLASMA;
|
||||
}
|
||||
|
||||
|
||||
void C_OrderBuildSentryGun::GetDescription( char *pDest, int bufferSize )
|
||||
{
|
||||
Q_strncpy( pDest, "Build Sentry Gun To Protect Object", bufferSize );
|
||||
}
|
||||
|
||||
@@ -0,0 +1,34 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================//
|
||||
|
||||
#ifndef C_ORDER_BUILDSENTRYGUN_H
|
||||
#define C_ORDER_BUILDSENTRYGUN_H
|
||||
#ifdef _WIN32
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
|
||||
#include "c_order.h"
|
||||
|
||||
|
||||
class C_OrderBuildSentryGun : public C_Order
|
||||
{
|
||||
public:
|
||||
DECLARE_CLASS( C_OrderBuildSentryGun, C_Order );
|
||||
DECLARE_CLIENTCLASS();
|
||||
|
||||
C_OrderBuildSentryGun();
|
||||
|
||||
|
||||
// C_Order overrides.
|
||||
public:
|
||||
|
||||
virtual void GetDescription( char *pDest, int bufferSize );
|
||||
};
|
||||
|
||||
|
||||
#endif // C_ORDER_BUILDSENTRYGUN_H
|
||||
@@ -0,0 +1,19 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================//
|
||||
#include "cbase.h"
|
||||
#include "c_order_buildshieldwall.h"
|
||||
|
||||
|
||||
IMPLEMENT_CLIENTCLASS_DT( C_OrderBuildShieldWall, DT_OrderBuildShieldWall, COrderBuildShieldWall )
|
||||
END_RECV_TABLE()
|
||||
|
||||
|
||||
void C_OrderBuildShieldWall::GetDescription( char *pDest, int bufferSize )
|
||||
{
|
||||
Q_strncpy( pDest, "Build Shield Wall To Protect Object", bufferSize );
|
||||
}
|
||||
|
||||
@@ -0,0 +1,32 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================//
|
||||
|
||||
#ifndef C_ORDER_BUILDSHIELDWALL_H
|
||||
#define C_ORDER_BUILDSHIELDWALL_H
|
||||
#ifdef _WIN32
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
|
||||
#include "c_order.h"
|
||||
|
||||
|
||||
class C_OrderBuildShieldWall : public C_Order
|
||||
{
|
||||
public:
|
||||
DECLARE_CLASS( C_OrderBuildShieldWall, C_Order );
|
||||
DECLARE_CLIENTCLASS();
|
||||
|
||||
|
||||
// C_Order overrides.
|
||||
public:
|
||||
|
||||
virtual void GetDescription( char *pDest, int bufferSize );
|
||||
};
|
||||
|
||||
|
||||
#endif // C_ORDER_BUILDSHIELDWALL_H
|
||||
@@ -0,0 +1,22 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================//
|
||||
#include "cbase.h"
|
||||
#include "c_order_heal.h"
|
||||
|
||||
|
||||
IMPLEMENT_CLIENTCLASS_DT( C_OrderHeal, DT_OrderHeal, COrderHeal )
|
||||
END_RECV_TABLE()
|
||||
|
||||
|
||||
void C_OrderHeal::GetDescription( char *pDest, int bufferSize )
|
||||
{
|
||||
char targetDesc[512];
|
||||
GetTargetDescription( targetDesc, sizeof( targetDesc ) );
|
||||
|
||||
Q_snprintf( pDest, bufferSize, "Heal %s", targetDesc );
|
||||
}
|
||||
|
||||
@@ -0,0 +1,32 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================//
|
||||
|
||||
#ifndef C_ORDER_HEAL_H
|
||||
#define C_ORDER_HEAL_H
|
||||
#ifdef _WIN32
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
|
||||
#include "c_order_player.h"
|
||||
|
||||
|
||||
class C_OrderHeal : public C_OrderPlayer
|
||||
{
|
||||
public:
|
||||
DECLARE_CLASS( C_OrderHeal, C_OrderPlayer );
|
||||
DECLARE_CLIENTCLASS();
|
||||
|
||||
|
||||
// C_Order overrides.
|
||||
public:
|
||||
|
||||
virtual void GetDescription( char *pDest, int bufferSize );
|
||||
};
|
||||
|
||||
|
||||
#endif // C_ORDER_HEAL_H
|
||||
@@ -0,0 +1,22 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================//
|
||||
#include "cbase.h"
|
||||
#include "c_order_killmortarguy.h"
|
||||
|
||||
|
||||
IMPLEMENT_CLIENTCLASS_DT( C_OrderKillMortarGuy, DT_OrderKillMortarGuy, COrderKillMortarGuy )
|
||||
END_RECV_TABLE()
|
||||
|
||||
|
||||
void C_OrderKillMortarGuy::GetDescription( char *pDest, int bufferSize )
|
||||
{
|
||||
char targetDesc[512];
|
||||
GetTargetDescription( targetDesc, sizeof( targetDesc ) );
|
||||
|
||||
Q_snprintf( pDest, bufferSize, "Kill Mortar Guy: %s", targetDesc );
|
||||
}
|
||||
|
||||
@@ -0,0 +1,32 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================//
|
||||
|
||||
#ifndef C_ORDER_KILLMORTARGUY_H
|
||||
#define C_ORDER_KILLMORTARGUY_H
|
||||
#ifdef _WIN32
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
|
||||
#include "c_order_player.h"
|
||||
|
||||
|
||||
class C_OrderKillMortarGuy : public C_OrderPlayer
|
||||
{
|
||||
public:
|
||||
DECLARE_CLASS( C_OrderKillMortarGuy, C_OrderPlayer );
|
||||
DECLARE_CLIENTCLASS();
|
||||
|
||||
|
||||
// C_Order overrides.
|
||||
public:
|
||||
|
||||
virtual void GetDescription( char *pDest, int bufferSize );
|
||||
};
|
||||
|
||||
|
||||
#endif // C_ORDER_KILLMORTARGUY_H
|
||||
@@ -0,0 +1,22 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================//
|
||||
#include "cbase.h"
|
||||
#include "c_order_mortar_attack.h"
|
||||
|
||||
|
||||
IMPLEMENT_CLIENTCLASS_DT( C_OrderMortarAttack, DT_OrderMortarAttack, COrderMortarAttack )
|
||||
END_RECV_TABLE()
|
||||
|
||||
|
||||
void C_OrderMortarAttack::GetDescription( char *pDest, int bufferSize )
|
||||
{
|
||||
char targetDesc[512];
|
||||
GetTargetDescription( targetDesc, sizeof( targetDesc ) );
|
||||
|
||||
Q_snprintf( pDest, bufferSize, "Attack %s with mortar", targetDesc );
|
||||
}
|
||||
|
||||
@@ -0,0 +1,32 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================//
|
||||
|
||||
#ifndef C_ORDER_MORTAR_ATTACK_H
|
||||
#define C_ORDER_MORTAR_ATTACK_H
|
||||
#ifdef _WIN32
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
|
||||
#include "c_order.h"
|
||||
|
||||
|
||||
class C_OrderMortarAttack : public C_Order
|
||||
{
|
||||
public:
|
||||
DECLARE_CLASS( C_OrderMortarAttack, C_Order );
|
||||
DECLARE_CLIENTCLASS();
|
||||
|
||||
|
||||
// C_Order overrides.
|
||||
public:
|
||||
|
||||
virtual void GetDescription( char *pDest, int bufferSize );
|
||||
};
|
||||
|
||||
|
||||
#endif // C_ORDER_MORTAR_ATTACK_H
|
||||
@@ -0,0 +1,38 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================//
|
||||
#include "cbase.h"
|
||||
#include "c_order_player.h"
|
||||
#include "cliententitylist.h"
|
||||
#include "c_basetfplayer.h"
|
||||
|
||||
|
||||
IMPLEMENT_CLIENTCLASS_DT( C_OrderPlayer, DT_OrderPlayer, COrderPlayer )
|
||||
END_RECV_TABLE()
|
||||
|
||||
|
||||
void C_OrderPlayer::GetTargetDescription( char *pDest, int bufferSize )
|
||||
{
|
||||
pDest[0] = 0;
|
||||
|
||||
// Order target
|
||||
if ( !m_iTargetEntIndex )
|
||||
return;
|
||||
|
||||
C_BaseEntity *pEnt = cl_entitylist->GetEnt(m_iTargetEntIndex);
|
||||
if ( !pEnt )
|
||||
return;
|
||||
|
||||
C_BaseTFPlayer *pPlayer = dynamic_cast<C_BaseTFPlayer*>(pEnt);
|
||||
if ( pPlayer )
|
||||
{
|
||||
pPlayer->GetTargetDescription( pDest, bufferSize );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,33 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================//
|
||||
|
||||
#ifndef C_ORDER_PLAYER_H
|
||||
#define C_ORDER_PLAYER_H
|
||||
#ifdef _WIN32
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
|
||||
#include "c_order.h"
|
||||
|
||||
|
||||
// Orders that point at players.
|
||||
class C_OrderPlayer : public C_Order
|
||||
{
|
||||
public:
|
||||
DECLARE_CLASS( C_OrderPlayer, C_Order );
|
||||
DECLARE_CLIENTCLASS();
|
||||
|
||||
|
||||
// C_Order overrides.
|
||||
public:
|
||||
|
||||
virtual void GetTargetDescription( char *pDest, int bufferSize );
|
||||
};
|
||||
|
||||
|
||||
#endif // C_ORDER_PLAYER_H
|
||||
@@ -0,0 +1,19 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================//
|
||||
#include "cbase.h"
|
||||
#include "c_order_repair.h"
|
||||
|
||||
|
||||
IMPLEMENT_CLIENTCLASS_DT( C_OrderRepair, DT_OrderRepair, COrderRepair )
|
||||
END_RECV_TABLE()
|
||||
|
||||
|
||||
void C_OrderRepair::GetDescription( char *pDest, int bufferSize )
|
||||
{
|
||||
Q_strncpy( pDest, "Repair Structure", bufferSize );
|
||||
}
|
||||
|
||||
@@ -0,0 +1,32 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================//
|
||||
|
||||
#ifndef C_ORDER_REPAIR_H
|
||||
#define C_ORDER_REPAIR_H
|
||||
#ifdef _WIN32
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
|
||||
#include "c_order.h"
|
||||
|
||||
|
||||
class C_OrderRepair : public C_Order
|
||||
{
|
||||
public:
|
||||
DECLARE_CLASS( C_OrderRepair, C_Order );
|
||||
DECLARE_CLIENTCLASS();
|
||||
|
||||
|
||||
// C_Order overrides.
|
||||
public:
|
||||
|
||||
virtual void GetDescription( char *pDest, int bufferSize );
|
||||
};
|
||||
|
||||
|
||||
#endif // C_ORDER_REPAIR_H
|
||||
@@ -0,0 +1,27 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================//
|
||||
|
||||
#include "cbase.h"
|
||||
#include "c_order_resourcepump.h"
|
||||
#include "tf_hints.h"
|
||||
|
||||
|
||||
IMPLEMENT_CLIENTCLASS_DT( C_OrderResourcePump, DT_OrderResourcePump, COrderResourcePump )
|
||||
END_RECV_TABLE()
|
||||
|
||||
|
||||
C_OrderResourcePump::C_OrderResourcePump()
|
||||
{
|
||||
m_nHintID = TF_HINT_BUILDRESOURCEPUMP;
|
||||
}
|
||||
|
||||
|
||||
void C_OrderResourcePump::GetDescription( char *pDest, int bufferSize )
|
||||
{
|
||||
Q_strncpy( pDest, "Build Resource Pump", bufferSize );
|
||||
}
|
||||
|
||||
@@ -0,0 +1,34 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================//
|
||||
|
||||
#ifndef C_ORDER_RESOURCEPUMP_H
|
||||
#define C_ORDER_RESOURCEPUMP_H
|
||||
#ifdef _WIN32
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
|
||||
#include "c_order.h"
|
||||
|
||||
|
||||
class C_OrderResourcePump : public C_Order
|
||||
{
|
||||
public:
|
||||
DECLARE_CLASS( C_OrderResourcePump, C_Order );
|
||||
DECLARE_CLIENTCLASS();
|
||||
|
||||
C_OrderResourcePump();
|
||||
|
||||
|
||||
// C_Order overrides.
|
||||
public:
|
||||
|
||||
virtual void GetDescription( char *pDest, int bufferSize );
|
||||
};
|
||||
|
||||
|
||||
#endif // C_ORDER_RESOURCEPUMP_H
|
||||
@@ -0,0 +1,19 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================//
|
||||
#include "cbase.h"
|
||||
#include "c_order_respawnstation.h"
|
||||
|
||||
|
||||
IMPLEMENT_CLIENTCLASS_DT( C_OrderRespawnStation, DT_OrderRespawnStation, COrderRespawnStation )
|
||||
END_RECV_TABLE()
|
||||
|
||||
|
||||
void C_OrderRespawnStation::GetDescription( char *pDest, int bufferSize )
|
||||
{
|
||||
Q_strncpy( pDest, "Build Respawn Station Near Object", bufferSize );
|
||||
}
|
||||
|
||||
@@ -0,0 +1,32 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================//
|
||||
|
||||
#ifndef C_ORDER_RESPAWNSTATION_H
|
||||
#define C_ORDER_RESPAWNSTATION_H
|
||||
#ifdef _WIN32
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
|
||||
#include "c_order_player.h"
|
||||
|
||||
|
||||
class C_OrderRespawnStation : public C_Order
|
||||
{
|
||||
public:
|
||||
DECLARE_CLASS( C_OrderRespawnStation, C_Order );
|
||||
DECLARE_CLIENTCLASS();
|
||||
|
||||
|
||||
// C_Order overrides.
|
||||
public:
|
||||
|
||||
virtual void GetDescription( char *pDest, int bufferSize );
|
||||
};
|
||||
|
||||
|
||||
#endif // C_ORDER_RESPAWNSTATION_H
|
||||
@@ -0,0 +1,19 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================//
|
||||
#include "cbase.h"
|
||||
#include "c_order_resupply.h"
|
||||
|
||||
|
||||
IMPLEMENT_CLIENTCLASS_DT( C_OrderResupply, DT_OrderResupply, COrderResupply )
|
||||
END_RECV_TABLE()
|
||||
|
||||
|
||||
void C_OrderResupply::GetDescription( char *pDest, int bufferSize )
|
||||
{
|
||||
Q_strncpy( pDest, "Build Resupply Station Near Object", bufferSize );
|
||||
}
|
||||
|
||||
@@ -0,0 +1,32 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================//
|
||||
|
||||
#ifndef C_ORDER_RESUPPLY_H
|
||||
#define C_ORDER_RESUPPLY_H
|
||||
#ifdef _WIN32
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
|
||||
#include "c_order.h"
|
||||
|
||||
|
||||
class C_OrderResupply : public C_Order
|
||||
{
|
||||
public:
|
||||
DECLARE_CLASS( C_OrderResupply, C_Order );
|
||||
DECLARE_CLIENTCLASS();
|
||||
|
||||
|
||||
// C_Order overrides.
|
||||
public:
|
||||
|
||||
virtual void GetDescription( char *pDest, int bufferSize );
|
||||
};
|
||||
|
||||
|
||||
#endif // C_ORDER_RESUPPLY_H
|
||||
@@ -0,0 +1,246 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================//
|
||||
#include "cbase.h"
|
||||
#include "model_types.h"
|
||||
#include "vcollide.h"
|
||||
#include "vcollide_parse.h"
|
||||
#include "solidsetdefaults.h"
|
||||
#include "c_basetfplayer.h"
|
||||
#include "bone_setup.h"
|
||||
#include "engine/ivmodelinfo.h"
|
||||
|
||||
CPhysCollide *PhysCreateBbox( const Vector &mins, const Vector &maxs );
|
||||
extern CSolidSetDefaults g_SolidSetup;
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
class C_RagdollShadow : public C_BaseAnimating
|
||||
{
|
||||
DECLARE_CLASS( C_RagdollShadow, C_BaseAnimating );
|
||||
public:
|
||||
DECLARE_CLIENTCLASS();
|
||||
|
||||
C_RagdollShadow( void );
|
||||
~C_RagdollShadow( void );
|
||||
|
||||
virtual void OnDataChanged( DataUpdateType_t updateType );
|
||||
|
||||
virtual void ClientThink( void );
|
||||
virtual int DrawModel( int flags );
|
||||
|
||||
public:
|
||||
IPhysicsObject *VPhysicsInitShadow( bool allowPhysicsMovement, bool allowPhysicsRotation );
|
||||
void VPhysicsSetObject( IPhysicsObject *pPhysics );
|
||||
void VPhysicsDestroyObject( void );
|
||||
|
||||
int m_nPlayer;
|
||||
EHANDLE m_hPlayer;
|
||||
|
||||
IPhysicsObject *m_pPhysicsObject;
|
||||
IPhysicsSpring *m_pSpring;
|
||||
};
|
||||
|
||||
IMPLEMENT_CLIENTCLASS_DT( C_RagdollShadow, DT_RagdollShadow, CRagdollShadow )
|
||||
RecvPropInt( RECVINFO( m_nPlayer ) ),
|
||||
END_RECV_TABLE()
|
||||
|
||||
C_RagdollShadow::C_RagdollShadow( void )
|
||||
{
|
||||
m_nPlayer = -1;
|
||||
m_hPlayer = NULL;
|
||||
|
||||
m_pPhysicsObject = NULL;
|
||||
m_pSpring = NULL;
|
||||
}
|
||||
|
||||
C_RagdollShadow::~C_RagdollShadow( void )
|
||||
{
|
||||
VPhysicsDestroyObject();
|
||||
|
||||
delete m_pSpring;
|
||||
}
|
||||
|
||||
void C_RagdollShadow::VPhysicsDestroyObject( void )
|
||||
{
|
||||
if ( m_pPhysicsObject )
|
||||
{
|
||||
physenv->DestroyObject( m_pPhysicsObject );
|
||||
m_pPhysicsObject = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
// Create a physics thingy based on an existing collision model
|
||||
IPhysicsObject *PhysModelCreateCustom( C_BaseEntity *pEntity, const CPhysCollide *pModel, const Vector &origin, const QAngle &angles, const char *props )
|
||||
{
|
||||
solid_t solid;
|
||||
solid.params = g_PhysDefaultObjectParams;
|
||||
solid.params.mass = 85.0f;
|
||||
solid.params.inertia = 1e24f;
|
||||
int surfaceProp = -1;
|
||||
if ( props && props[0] )
|
||||
{
|
||||
surfaceProp = physprops->GetSurfaceIndex( props );
|
||||
}
|
||||
solid.params.pGameData = static_cast<void *>(pEntity);
|
||||
IPhysicsObject *pObject = physenv->CreatePolyObject( pModel, surfaceProp, origin, angles, &solid.params );
|
||||
return pObject;
|
||||
}
|
||||
|
||||
IPhysicsObject *PhysModelCreateRagdoll( C_BaseEntity *pEntity, int modelIndex, const Vector &origin, const QAngle &angles )
|
||||
{
|
||||
vcollide_t *pCollide = modelinfo->GetVCollide( modelIndex );
|
||||
if ( !pCollide )
|
||||
return NULL;
|
||||
|
||||
solid_t solid;
|
||||
memset( &solid, 0, sizeof(solid) );
|
||||
solid.params = g_PhysDefaultObjectParams;
|
||||
|
||||
IVPhysicsKeyParser *pParse = physcollision->VPhysicsKeyParserCreate( pCollide->pKeyValues );
|
||||
while ( !pParse->Finished() )
|
||||
{
|
||||
const char *pBlock = pParse->GetCurrentBlockName();
|
||||
if ( !strcmpi( pBlock, "solid" ) )
|
||||
{
|
||||
pParse->ParseSolid( &solid, &g_SolidSetup );
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
pParse->SkipBlock();
|
||||
}
|
||||
}
|
||||
physcollision->VPhysicsKeyParserDestroy( pParse );
|
||||
|
||||
// collisions are off by default
|
||||
solid.params.enableCollisions = true;
|
||||
|
||||
int surfaceProp = -1;
|
||||
if ( solid.surfaceprop[0] )
|
||||
{
|
||||
surfaceProp = physprops->GetSurfaceIndex( solid.surfaceprop );
|
||||
}
|
||||
solid.params.pGameData = static_cast<void *>(pEntity);
|
||||
solid.params.pName = "ragdoll_player";
|
||||
IPhysicsObject *pObject = physenv->CreatePolyObject( pCollide->solids[0], surfaceProp, origin, angles, &solid.params );
|
||||
//PhysCheckAdd( pObject, STRING(pEntity->m_iClassname) );
|
||||
return pObject;
|
||||
}
|
||||
|
||||
void C_RagdollShadow::VPhysicsSetObject( IPhysicsObject *pPhysics )
|
||||
{
|
||||
if ( m_pPhysicsObject && pPhysics )
|
||||
{
|
||||
Warning( "C_RagdollShadow::Overwriting physics object!\n" );
|
||||
}
|
||||
m_pPhysicsObject = pPhysics;
|
||||
}
|
||||
|
||||
|
||||
// This creates a vphysics object with a shadow controller that follows the AI
|
||||
IPhysicsObject *C_RagdollShadow::VPhysicsInitShadow( bool allowPhysicsMovement, bool allowPhysicsRotation )
|
||||
{
|
||||
CStudioHdr *hdr = GetModelPtr();
|
||||
if ( !hdr )
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// If this entity already has a physics object, then it should have been deleted prior to making this call.
|
||||
Assert(!m_pPhysicsObject);
|
||||
|
||||
// make sure m_vecOrigin / m_vecAngles are correct
|
||||
const Vector &origin = GetAbsOrigin();
|
||||
QAngle angles = GetAbsAngles();
|
||||
IPhysicsObject *pPhysicsObject = NULL;
|
||||
|
||||
if ( GetSolid() == SOLID_BBOX )
|
||||
{
|
||||
const char *pSurfaceProps = "flesh";
|
||||
if ( GetModelIndex() && modelinfo->GetModelType( GetModel() ) == mod_studio )
|
||||
{
|
||||
pSurfaceProps = Studio_GetDefaultSurfaceProps( hdr );
|
||||
}
|
||||
angles = vec3_angle;
|
||||
CPhysCollide *pCollide = PhysCreateBbox( WorldAlignMins(), WorldAlignMaxs() );
|
||||
if ( !pCollide )
|
||||
return NULL;
|
||||
pPhysicsObject = PhysModelCreateCustom( this, pCollide, origin, angles, pSurfaceProps );
|
||||
}
|
||||
else
|
||||
{
|
||||
pPhysicsObject = PhysModelCreateRagdoll( this, GetModelIndex(), origin, angles );
|
||||
}
|
||||
VPhysicsSetObject( pPhysicsObject );
|
||||
pPhysicsObject->SetShadow( 1e4, 1e4, allowPhysicsMovement, allowPhysicsRotation );
|
||||
pPhysicsObject->UpdateShadow( GetAbsOrigin(), GetAbsAngles(), false, 0 );
|
||||
// PhysAddShadow( this );
|
||||
return pPhysicsObject;
|
||||
}
|
||||
|
||||
void C_RagdollShadow::OnDataChanged( DataUpdateType_t updateType )
|
||||
{
|
||||
BaseClass::OnDataChanged( updateType );
|
||||
|
||||
// Has to happen *after* the client handle is set
|
||||
SetNextClientThink( CLIENT_THINK_ALWAYS );
|
||||
|
||||
bool bnewentity = (updateType == DATA_UPDATE_CREATED);
|
||||
if ( bnewentity && ( m_nPlayer != 0 ) )
|
||||
{
|
||||
SetNextClientThink( CLIENT_THINK_ALWAYS );
|
||||
|
||||
Assert( !m_pPhysicsObject );
|
||||
|
||||
C_BaseEntity *pl = static_cast< C_BaseEntity * >( cl_entitylist->GetEnt( m_nPlayer ) );
|
||||
if ( pl )
|
||||
{
|
||||
m_hPlayer = pl;
|
||||
}
|
||||
|
||||
m_pPhysicsObject = VPhysicsInitShadow( true, false );
|
||||
}
|
||||
|
||||
if ( m_pPhysicsObject )
|
||||
{
|
||||
// Create the spring if we don't have one yet
|
||||
if ( !m_pSpring )
|
||||
{
|
||||
C_BaseTFPlayer *pl = static_cast< C_BaseTFPlayer * >( (C_BaseEntity *)m_hPlayer );
|
||||
if ( pl && pl->VPhysicsGetObject() )
|
||||
{
|
||||
springparams_t spring;
|
||||
spring.constant = 15000;
|
||||
spring.damping = 1.0;
|
||||
spring.naturalLength = 0.0f;
|
||||
spring.relativeDamping = 100.0f;
|
||||
VectorCopy( vec3_origin, spring.startPosition );
|
||||
VectorCopy( vec3_origin, spring.endPosition );
|
||||
spring.useLocalPositions = true;
|
||||
|
||||
m_pSpring = physenv->CreateSpring( m_pPhysicsObject, pl->VPhysicsGetObject(), &spring );
|
||||
|
||||
PhysDisableObjectCollisions( m_pPhysicsObject, pl->VPhysicsGetObject() );
|
||||
}
|
||||
}
|
||||
|
||||
m_pPhysicsObject->UpdateShadow( GetAbsOrigin(), GetAbsAngles(), false, 0 );
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void C_RagdollShadow::ClientThink( void )
|
||||
{
|
||||
BaseClass::ClientThink();
|
||||
}
|
||||
|
||||
int C_RagdollShadow::DrawModel( int flags )
|
||||
{
|
||||
// int drawn = BaseClass::DrawModel( flags );
|
||||
// return drawn;
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================//
|
||||
#include "cbase.h"
|
||||
#include "particles_simple.h"
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
class C_ResourceChunk : public C_BaseAnimating
|
||||
{
|
||||
DECLARE_CLASS( C_ResourceChunk, C_BaseAnimating );
|
||||
public:
|
||||
DECLARE_CLIENTCLASS();
|
||||
};
|
||||
|
||||
IMPLEMENT_CLIENTCLASS_DT( C_ResourceChunk, DT_ResourceChunk, CResourceChunk )
|
||||
END_RECV_TABLE()
|
||||
|
||||
@@ -0,0 +1,837 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose: Client's sheild entity
|
||||
//
|
||||
// $Workfile: $
|
||||
// $NoKeywords: $
|
||||
//=============================================================================//
|
||||
#include "cbase.h"
|
||||
#include "C_Shield.h"
|
||||
#include "clienteffectprecachesystem.h"
|
||||
#include "clientmode.h"
|
||||
#include "materialsystem/imesh.h"
|
||||
#include "mapdata.h"
|
||||
#include "ivrenderview.h"
|
||||
#include "tf_shareddefs.h"
|
||||
#include "collisionutils.h"
|
||||
#include "functionproxy.h"
|
||||
|
||||
// Precache the effects
|
||||
CLIENTEFFECT_REGISTER_BEGIN( Shield )
|
||||
CLIENTEFFECT_MATERIAL( "shadertest/wireframevertexcolor" )
|
||||
CLIENTEFFECT_MATERIAL( "effects/shield/shield" )
|
||||
CLIENTEFFECT_MATERIAL( "effects/shieldhit" )
|
||||
CLIENTEFFECT_MATERIAL( "effects/shieldpass" )
|
||||
CLIENTEFFECT_MATERIAL( "effects/shieldpass2" )
|
||||
CLIENTEFFECT_REGISTER_END()
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Stores a list of all active shields
|
||||
//-----------------------------------------------------------------------------
|
||||
CUtlVector< C_Shield* > C_Shield::s_Shields;
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Various important constants:
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#define SHIELD_DAMAGE_CHANGE_FIRST_PASS_TIME 0.3f
|
||||
#define SHIELD_DAMAGE_CHANGE_TRANSITION_TIME 0.5f
|
||||
#define SHIELD_DAMAGE_CHANGE_TRANSITION_START_TIME (SHIELD_DAMAGE_CHANGE_TIME - SHIELD_DAMAGE_CHANGE_TRANSITION_TIME)
|
||||
#define SHIELD_DAMAGE_CHANGE_TOTAL_TIME (SHIELD_DAMAGE_CHANGE_TRANSITION_START_TIME + SHIELD_DAMAGE_CHANGE_TRANSITION_TIME)
|
||||
#define SHIELD_TRANSITION_MAX_BLEND_AMT 0.2f
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Data table
|
||||
//-----------------------------------------------------------------------------
|
||||
//EXTERN_RECV_TABLE(DT_BaseEntity);
|
||||
|
||||
IMPLEMENT_CLIENTCLASS_DT(C_Shield, DT_Shield, CShield)
|
||||
RecvPropInt( RECVINFO(m_nOwningPlayerIndex) ),
|
||||
RecvPropFloat( RECVINFO(m_flPowerLevel) ),
|
||||
RecvPropInt( RECVINFO(m_bIsEMPed) ),
|
||||
END_RECV_TABLE()
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Shield color for the various protection types
|
||||
//-----------------------------------------------------------------------------
|
||||
static unsigned char s_ImpactDecalColor[3] = { 0, 0, 255 };
|
||||
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// Functions.
|
||||
// ----------------------------------------------------------------------------
|
||||
C_Shield::C_Shield()
|
||||
{
|
||||
m_pWireframe.Init( "shadertest/wireframevertexcolor", TEXTURE_GROUP_OTHER );
|
||||
m_pShield.Init( "effects/shield/shield", TEXTURE_GROUP_CLIENT_EFFECTS );
|
||||
m_pHitDecal.Init( "effects/shieldhit", TEXTURE_GROUP_CLIENT_EFFECTS );
|
||||
m_pPassDecal.Init( "effects/shieldpass", TEXTURE_GROUP_CLIENT_EFFECTS );
|
||||
m_pPassDecal2.Init( "effects/shieldpass2", TEXTURE_GROUP_CLIENT_EFFECTS );
|
||||
m_FadeValue = 1.0f;
|
||||
m_CurveValue = 1.0f;
|
||||
m_bCollisionsActive = true;
|
||||
|
||||
s_Shields.AddToTail(this);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
C_Shield::~C_Shield()
|
||||
{
|
||||
int i = s_Shields.Find(this);
|
||||
if ( i >= 0 )
|
||||
{
|
||||
s_Shields.FastRemove(i);
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Inherited classes should call this in their constructor to indicate size...
|
||||
//-----------------------------------------------------------------------------
|
||||
void C_Shield::InitShield( int w, int h, int subdivisions )
|
||||
{
|
||||
m_SplinePatch.Init( w, h, 2 );
|
||||
|
||||
m_SubdivisionCount = subdivisions;
|
||||
Assert( m_SubdivisionCount > 1 );
|
||||
m_InvSubdivisionCount = 1.0f / (m_SubdivisionCount - 1);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// This is called after a network update
|
||||
//-----------------------------------------------------------------------------
|
||||
void C_Shield::OnDataChanged( DataUpdateType_t updateType )
|
||||
{
|
||||
if (updateType == DATA_UPDATE_CREATED)
|
||||
{
|
||||
m_StartTime = engine->GetLastTimeStamp();
|
||||
}
|
||||
|
||||
BaseClass::OnDataChanged( updateType );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
// Input : collisionGroup -
|
||||
// Output : Returns true on success, false on failure.
|
||||
//-----------------------------------------------------------------------------
|
||||
bool C_Shield::ShouldCollide( int collisionGroup, int contentsMask ) const
|
||||
{
|
||||
return m_bCollisionsActive && ((collisionGroup == TFCOLLISION_GROUP_WEAPON) || (collisionGroup == TFCOLLISION_GROUP_GRENADE));
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Should I draw?
|
||||
//-----------------------------------------------------------------------------
|
||||
bool C_Shield::ShouldDraw()
|
||||
{
|
||||
// Let the client mode (like commander mode) reject drawing entities.
|
||||
if (g_pClientMode && !g_pClientMode->ShouldDrawEntity(this) )
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Activates/deactivates a shield for collision purposes
|
||||
//-----------------------------------------------------------------------------
|
||||
void C_Shield::ActivateCollisions( bool activate )
|
||||
{
|
||||
m_bCollisionsActive = activate;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Activates all shields
|
||||
//-----------------------------------------------------------------------------
|
||||
void C_Shield::ActivateShields( bool activate, int team )
|
||||
{
|
||||
for (int i = s_Shields.Count(); --i >= 0; )
|
||||
{
|
||||
// Activate all shields on the same team
|
||||
if ( (team == -1) || (team == s_Shields[i]->GetTeamNumber()) )
|
||||
{
|
||||
s_Shields[i]->ActivateCollisions( activate );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Helper method for collision testing
|
||||
//-----------------------------------------------------------------------------
|
||||
#pragma warning ( disable : 4701 )
|
||||
|
||||
bool C_Shield::TestCollision( const Ray_t& ray, unsigned int mask, trace_t& trace )
|
||||
{
|
||||
// Can't block anything if we're EMPed, or we've got no power left to block
|
||||
if ( m_bIsEMPed )
|
||||
return false;
|
||||
if ( m_flPowerLevel <= 0 )
|
||||
return false;
|
||||
|
||||
// Here, we're gonna test for collision.
|
||||
// If we don't stop this kind of bullet, we'll generate an effect here
|
||||
// but we won't change the trace to indicate a collision.
|
||||
|
||||
// It's just polygon soup...
|
||||
int hitgroup;
|
||||
bool firstTri;
|
||||
int v1[2], v2[2], v3[2];
|
||||
float ihit, jhit;
|
||||
float mint = FLT_MAX;
|
||||
float t;
|
||||
|
||||
int h = Height();
|
||||
int w = Width();
|
||||
|
||||
for (int i = 0; i < h - 1; ++i)
|
||||
{
|
||||
for (int j = 0; j < w - 1; ++j)
|
||||
{
|
||||
// Don't test if this panel ain't active...
|
||||
if (!IsPanelActive( j, i ))
|
||||
continue;
|
||||
|
||||
// NOTE: Structure order of points so that our barycentric
|
||||
// axes for each triangle are along the (u,v) directions of the mesh
|
||||
// The barycentric coords we'll need below
|
||||
|
||||
// Two triangles per quad...
|
||||
t = IntersectRayWithTriangle( ray,
|
||||
GetPoint( j, i + 1 ),
|
||||
GetPoint( j + 1, i + 1 ),
|
||||
GetPoint( j, i ), true );
|
||||
if ((t >= 0.0f) && (t < mint))
|
||||
{
|
||||
mint = t;
|
||||
v1[0] = j; v1[1] = i + 1;
|
||||
v2[0] = j + 1; v2[1] = i + 1;
|
||||
v3[0] = j; v3[1] = i;
|
||||
ihit = i; jhit = j;
|
||||
firstTri = true;
|
||||
}
|
||||
|
||||
t = IntersectRayWithTriangle( ray,
|
||||
GetPoint( j + 1, i ),
|
||||
GetPoint( j, i ),
|
||||
GetPoint( j + 1, i + 1 ), true );
|
||||
if ((t >= 0.0f) && (t < mint))
|
||||
{
|
||||
mint = t;
|
||||
v1[0] = j + 1; v1[1] = i;
|
||||
v2[0] = j; v2[1] = i;
|
||||
v3[0] = j + 1; v3[1] = i + 1;
|
||||
ihit = i; jhit = j;
|
||||
firstTri = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (mint == FLT_MAX)
|
||||
return false;
|
||||
|
||||
// Stuff the barycentric coordinates of the triangle hit into the hit group
|
||||
// For the first triangle, the first edge goes along u, the second edge goes
|
||||
// along -v. For the second triangle, the first edge goes along -u,
|
||||
// the second edge goes along v.
|
||||
const Vector& v1vec = GetPoint(v1[0], v1[1]);
|
||||
const Vector& v2vec = GetPoint(v2[0], v2[1]);
|
||||
const Vector& v3vec = GetPoint(v3[0], v3[1]);
|
||||
float u, v;
|
||||
bool ok = ComputeIntersectionBarycentricCoordinates( ray,
|
||||
v1vec, v2vec, v3vec, u, v );
|
||||
Assert( ok );
|
||||
if ( !ok )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (firstTri)
|
||||
v = 1.0 - v;
|
||||
else
|
||||
u = 1.0 - u;
|
||||
v += ihit; u += jhit;
|
||||
v /= (h - 1);
|
||||
u /= (w - 1);
|
||||
|
||||
// Compress (u,v) into 1 dot 15, v in top bits
|
||||
hitgroup = (((int)(v * (1 << 15))) << 16) + (int)(u * (1 << 15));
|
||||
|
||||
Vector normal;
|
||||
float intercept;
|
||||
ComputeTrianglePlane( v1vec, v2vec, v3vec, normal, intercept );
|
||||
|
||||
UTIL_SetTrace( trace, ray, this, mint, hitgroup, CONTENTS_SOLID, normal, intercept );
|
||||
return true;
|
||||
}
|
||||
|
||||
#pragma warning ( default : 4701 )
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Called when we hit something that we deflect...
|
||||
//-----------------------------------------------------------------------------
|
||||
void C_Shield::RegisterDeflection(const Vector& vecDir, int bitsDamageType, trace_t *ptr)
|
||||
{
|
||||
Vector normalDir;
|
||||
VectorCopy( vecDir, normalDir );
|
||||
VectorNormalize( normalDir );
|
||||
|
||||
CreateShieldDeflection( ptr->hitgroup, normalDir, false );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// This is required to get all the decals to animate correctly
|
||||
//-----------------------------------------------------------------------------
|
||||
void C_Shield::SetCurrentDecal( int idx )
|
||||
{
|
||||
m_CurrentDecal = idx;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// returns the address of a variable that stores the material animation frame
|
||||
//-----------------------------------------------------------------------------
|
||||
float C_Shield::GetTextureAnimationStartTime()
|
||||
{
|
||||
if( m_CurrentDecal == -1 )
|
||||
return m_StartTime;
|
||||
return m_Decals[m_CurrentDecal].m_StartTime;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Indicates that a texture animation has wrapped
|
||||
//-----------------------------------------------------------------------------
|
||||
void C_Shield::TextureAnimationWrapped()
|
||||
{
|
||||
if( m_CurrentDecal != -1 )
|
||||
{
|
||||
m_Decals[m_CurrentDecal].m_StartTime = -1.0f;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Indicates a collision occurred:
|
||||
//-----------------------------------------------------------------------------
|
||||
void C_Shield::ReceiveMessage( int classID, bf_read &msg )
|
||||
{
|
||||
if ( classID != GetClientClass()->m_ClassID )
|
||||
{
|
||||
// message is for subclass
|
||||
BaseClass::ReceiveMessage( classID, msg );
|
||||
return;
|
||||
}
|
||||
|
||||
int hitgroup;
|
||||
Vector dir;
|
||||
unsigned char partialBlock;
|
||||
|
||||
hitgroup = msg.ReadLong( );
|
||||
msg.ReadBitVec3Normal( dir );
|
||||
partialBlock = msg.ReadByte( );
|
||||
|
||||
CreateShieldDeflection( hitgroup, dir, partialBlock );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void C_Shield::CreateShieldDeflection( int hitgroup, const Vector &dir, bool partialBlock )
|
||||
{
|
||||
float hitU = (float)(hitgroup & 0xFFFF) / (float)(1 << 15);
|
||||
float hitV = (float)(hitgroup >> 16) / (float)(1 << 15);
|
||||
|
||||
Ripple_t ripple;
|
||||
ripple.m_RippleU = hitU;
|
||||
ripple.m_RippleV = hitV;
|
||||
ripple.m_Amplitude = partialBlock ? 4 : 30;
|
||||
ripple.m_Radius = 0.08f;
|
||||
ripple.m_StartTime = engine->GetLastTimeStamp();
|
||||
ripple.m_Direction = dir;
|
||||
m_Ripples.AddToTail(ripple);
|
||||
|
||||
Decal_t decal;
|
||||
decal.m_RippleU = hitU;
|
||||
decal.m_RippleV = hitV;
|
||||
decal.m_Radius = partialBlock ? 0.03f : 0.08f;
|
||||
decal.m_StartTime = engine->GetLastTimeStamp();
|
||||
m_Decals.AddToTail(decal);
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Draws the control points in wireframe
|
||||
//-----------------------------------------------------------------------------
|
||||
void C_Shield::DrawWireframeModel( Vector const** ppPositions )
|
||||
{
|
||||
IMesh* pMesh = materials->GetDynamicMesh( true, NULL, NULL, m_pWireframe );
|
||||
|
||||
int numLines = (Height() - 1) * Width() + Height() * (Width() - 1);
|
||||
|
||||
CMeshBuilder meshBuilder;
|
||||
meshBuilder.Begin( pMesh, MATERIAL_LINES, numLines );
|
||||
|
||||
Vector const* tmp;
|
||||
for (int i = 0; i < Height(); ++i)
|
||||
{
|
||||
for (int j = 0; j < Width(); ++j)
|
||||
{
|
||||
if ( i > 0 )
|
||||
{
|
||||
tmp = ppPositions[j + Width() * i];
|
||||
meshBuilder.Position3fv( tmp->Base() );
|
||||
meshBuilder.Color4ub( 255, 255, 255, 128 );
|
||||
meshBuilder.AdvanceVertex();
|
||||
|
||||
tmp = ppPositions[j + Width() * (i-1)];
|
||||
meshBuilder.Position3fv( tmp->Base() );
|
||||
meshBuilder.Color4ub( 255, 255, 255, 128 );
|
||||
meshBuilder.AdvanceVertex();
|
||||
}
|
||||
|
||||
if (j > 0)
|
||||
{
|
||||
tmp = ppPositions[j + Width() * i];
|
||||
meshBuilder.Position3fv( tmp->Base() );
|
||||
meshBuilder.Color4ub( 255, 255, 255, 128 );
|
||||
meshBuilder.AdvanceVertex();
|
||||
|
||||
tmp = ppPositions[j - 1 + Width() * i];
|
||||
meshBuilder.Position3fv( tmp->Base() );
|
||||
meshBuilder.Color4ub( 255, 255, 255, 128 );
|
||||
meshBuilder.AdvanceVertex();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
meshBuilder.End();
|
||||
pMesh->Draw();
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Draws the base shield
|
||||
//-----------------------------------------------------------------------------
|
||||
#define TRANSITION_REGION_WIDTH 0.5f
|
||||
|
||||
extern ConVar mat_wireframe;
|
||||
|
||||
void C_Shield::DrawShieldPoints(Vector* pt, Vector* normal, float* opacity)
|
||||
{
|
||||
SetCurrentDecal( -1 );
|
||||
|
||||
if (mat_wireframe.GetInt() == 0)
|
||||
materials->Bind( m_pShield, (IClientRenderable*)this );
|
||||
else
|
||||
materials->Bind( m_pWireframe, (IClientRenderable*)this );
|
||||
IMesh* pMesh = materials->GetDynamicMesh( true, NULL, NULL );
|
||||
|
||||
int numTriangles = (m_SubdivisionCount - 1) * (m_SubdivisionCount - 1) * 2;
|
||||
|
||||
CMeshBuilder meshBuilder;
|
||||
meshBuilder.Begin( pMesh, MATERIAL_TRIANGLES, numTriangles );
|
||||
|
||||
float du = 1.0f * m_InvSubdivisionCount;
|
||||
float dv = du;
|
||||
|
||||
unsigned char color[3];
|
||||
color[0] = 255;
|
||||
color[1] = 255;
|
||||
color[2] = 255;
|
||||
|
||||
for ( int i = 0; i < m_SubdivisionCount - 1; ++i)
|
||||
{
|
||||
float v = i * dv;
|
||||
|
||||
for (int j = 0; j < m_SubdivisionCount - 1; ++j)
|
||||
{
|
||||
int idx = i * m_SubdivisionCount + j;
|
||||
float u = j * du;
|
||||
|
||||
meshBuilder.Position3fv( pt[idx].Base() );
|
||||
meshBuilder.Color4ub( color[0], color[1], color[2], opacity[idx] );
|
||||
meshBuilder.Normal3fv( normal[idx].Base() );
|
||||
meshBuilder.TexCoord2f( 0, u, v );
|
||||
meshBuilder.AdvanceVertex();
|
||||
|
||||
meshBuilder.Position3fv( pt[idx + m_SubdivisionCount].Base() );
|
||||
meshBuilder.Color4ub( color[0], color[1], color[2], opacity[idx+m_SubdivisionCount] );
|
||||
meshBuilder.Normal3fv( normal[idx + m_SubdivisionCount].Base() );
|
||||
meshBuilder.TexCoord2f( 0, u, v + dv );
|
||||
meshBuilder.AdvanceVertex();
|
||||
|
||||
meshBuilder.Position3fv( pt[idx + 1].Base() );
|
||||
meshBuilder.Color4ub( color[0], color[1], color[2], opacity[idx+1] );
|
||||
meshBuilder.Normal3fv( normal[idx+1].Base() );
|
||||
meshBuilder.TexCoord2f( 0, u + du, v );
|
||||
meshBuilder.AdvanceVertex();
|
||||
|
||||
meshBuilder.Position3fv( pt[idx + 1].Base() );
|
||||
meshBuilder.Color4ub( color[0], color[1], color[2], opacity[idx+1] );
|
||||
meshBuilder.Normal3fv( normal[idx+1].Base() );
|
||||
meshBuilder.TexCoord2f( 0, u + du, v );
|
||||
meshBuilder.AdvanceVertex();
|
||||
|
||||
meshBuilder.Position3fv( pt[idx + m_SubdivisionCount].Base() );
|
||||
meshBuilder.Color4ub( color[0], color[1], color[2], opacity[idx+m_SubdivisionCount] );
|
||||
meshBuilder.Normal3fv( normal[idx + m_SubdivisionCount].Base() );
|
||||
meshBuilder.TexCoord2f( 0, u, v + dv );
|
||||
meshBuilder.AdvanceVertex();
|
||||
|
||||
meshBuilder.Position3fv( pt[idx + m_SubdivisionCount + 1].Base() );
|
||||
meshBuilder.Color4ub( color[0], color[1], color[2], opacity[idx+m_SubdivisionCount+1] );
|
||||
meshBuilder.Normal3fv( normal[idx + m_SubdivisionCount + 1].Base() );
|
||||
meshBuilder.TexCoord2f( 0, u + du, v + dv );
|
||||
meshBuilder.AdvanceVertex();
|
||||
}
|
||||
}
|
||||
|
||||
meshBuilder.End();
|
||||
pMesh->Draw();
|
||||
}
|
||||
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Draws shield decals
|
||||
//-----------------------------------------------------------------------------
|
||||
void C_Shield::DrawShieldDecals( Vector* pt, bool hitDecals )
|
||||
{
|
||||
if (m_Decals.Size() == 0)
|
||||
return;
|
||||
|
||||
// Compute ripples:
|
||||
for ( int r = m_Decals.Size(); --r >= 0; )
|
||||
{
|
||||
// At the moment, nothing passes!
|
||||
bool passDecal = false;
|
||||
if ((!hitDecals) && (passDecal == hitDecals))
|
||||
continue;
|
||||
|
||||
SetCurrentDecal( r );
|
||||
|
||||
// We have to force a flush here because we're changing the proxy state
|
||||
if (!hitDecals)
|
||||
materials->Bind( m_pPassDecal, (IClientRenderable*)this );
|
||||
else
|
||||
materials->Bind( passDecal ? m_pPassDecal2 : m_pHitDecal, (IClientRenderable*)this );
|
||||
|
||||
float dtime = gpGlobals->curtime - m_Decals[r].m_StartTime;
|
||||
float decay = exp( -( 2 * dtime) );
|
||||
|
||||
// Retire the animation if it wraps
|
||||
// This gets set by TextureAnimatedWrapped above
|
||||
if ((m_Decals[r].m_StartTime < 0.0f) || (decay < 1e-3))
|
||||
{
|
||||
m_Decals.Remove(r);
|
||||
continue;
|
||||
}
|
||||
|
||||
IMesh* pMesh = materials->GetDynamicMesh();
|
||||
|
||||
// Figure out the quads we must mod2x....
|
||||
float u0 = m_Decals[r].m_RippleU - m_Decals[r].m_Radius;
|
||||
float u1 = m_Decals[r].m_RippleU + m_Decals[r].m_Radius;
|
||||
float v0 = m_Decals[r].m_RippleV - m_Decals[r].m_Radius;
|
||||
float v1 = m_Decals[r].m_RippleV + m_Decals[r].m_Radius;
|
||||
float du = u1 - u0;
|
||||
float dv = v1 - v0;
|
||||
|
||||
int i0 = Floor2Int( v0 * (m_SubdivisionCount - 1) );
|
||||
int i1 = Ceil2Int( v1 * (m_SubdivisionCount - 1) );
|
||||
int j0 = Floor2Int( u0 * (m_SubdivisionCount - 1) );
|
||||
int j1 = Ceil2Int( u1 * (m_SubdivisionCount - 1) );
|
||||
if (i0 < 0)
|
||||
i0 = 0;
|
||||
if (i1 >= m_SubdivisionCount)
|
||||
i1 = m_SubdivisionCount - 1;
|
||||
if (j0 < 0)
|
||||
j0 = 0;
|
||||
if (j1 >= m_SubdivisionCount)
|
||||
j1 = m_SubdivisionCount - 1;
|
||||
|
||||
int numTriangles = (i1 - i0) * (j1 - j0) * 2;
|
||||
|
||||
CMeshBuilder meshBuilder;
|
||||
meshBuilder.Begin( pMesh, MATERIAL_TRIANGLES, numTriangles );
|
||||
|
||||
float decalDu = m_InvSubdivisionCount / du;
|
||||
float decalDv = m_InvSubdivisionCount / dv;
|
||||
|
||||
unsigned char color[3];
|
||||
color[0] = s_ImpactDecalColor[0] * decay;
|
||||
color[1] = s_ImpactDecalColor[1] * decay;
|
||||
color[2] = s_ImpactDecalColor[2] * decay;
|
||||
|
||||
for ( int i = i0; i < i1; ++i)
|
||||
{
|
||||
float t = (float)i * m_InvSubdivisionCount;
|
||||
for (int j = j0; j < j1; ++j)
|
||||
{
|
||||
float s = (float)j * m_InvSubdivisionCount;
|
||||
int idx = i * m_SubdivisionCount + j;
|
||||
|
||||
// Compute (u,v) into the decal
|
||||
float decalU = (s - u0) / du;
|
||||
float decalV = (t - v0) / dv;
|
||||
|
||||
meshBuilder.Position3fv( pt[idx].Base() );
|
||||
meshBuilder.Color3ubv( color );
|
||||
meshBuilder.TexCoord2f( 0, decalU, decalV );
|
||||
meshBuilder.AdvanceVertex();
|
||||
|
||||
meshBuilder.Position3fv( pt[idx + m_SubdivisionCount].Base() );
|
||||
meshBuilder.Color3ubv( color );
|
||||
meshBuilder.TexCoord2f( 0, decalU, decalV + decalDv );
|
||||
meshBuilder.AdvanceVertex();
|
||||
|
||||
meshBuilder.Position3fv( pt[idx + 1].Base() );
|
||||
meshBuilder.Color3ubv( color );
|
||||
meshBuilder.TexCoord2f( 0, decalU + decalDu, decalV );
|
||||
meshBuilder.AdvanceVertex();
|
||||
|
||||
meshBuilder.Position3fv( pt[idx + 1].Base() );
|
||||
meshBuilder.Color3ubv( color );
|
||||
meshBuilder.TexCoord2f( 0, decalU + decalDu, decalV );
|
||||
meshBuilder.AdvanceVertex();
|
||||
|
||||
meshBuilder.Position3fv( pt[idx + m_SubdivisionCount].Base() );
|
||||
meshBuilder.Color3ubv( color );
|
||||
meshBuilder.TexCoord2f( 0, decalU, decalV + decalDv );
|
||||
meshBuilder.AdvanceVertex();
|
||||
|
||||
meshBuilder.Position3fv( pt[idx + m_SubdivisionCount + 1].Base() );
|
||||
meshBuilder.Color3ubv( color );
|
||||
meshBuilder.TexCoord2f( 0, decalU + decalDu, decalV + decalDv );
|
||||
meshBuilder.AdvanceVertex();
|
||||
}
|
||||
}
|
||||
|
||||
meshBuilder.End();
|
||||
pMesh->Draw();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Computes a single point
|
||||
//-----------------------------------------------------------------------------
|
||||
void C_Shield::ComputePoint( float s, float t, Vector& pt, Vector& normal, float& opacity )
|
||||
{
|
||||
// Precache some computations for the point on the spline at (s, t).
|
||||
m_SplinePatch.SetupPatchQuery( s, t );
|
||||
|
||||
// Get the position + normal
|
||||
m_SplinePatch.GetPointAndNormal( pt, normal );
|
||||
|
||||
// From here on down is all futzing with opacity
|
||||
|
||||
// Check neighbors for activity...
|
||||
bool active = IsPanelActive(m_SplinePatch.m_is, m_SplinePatch.m_it);
|
||||
if (m_SplinePatch.m_fs == 0.0f)
|
||||
active = active || IsPanelActive(m_SplinePatch.m_is - 1, m_SplinePatch.m_it);
|
||||
if (m_SplinePatch.m_ft == 0.0f)
|
||||
active = active || IsPanelActive(m_SplinePatch.m_is, m_SplinePatch.m_it - 1);
|
||||
|
||||
if (!active)
|
||||
{
|
||||
// If the panel's not active, it's transparent.
|
||||
opacity = 0.0f;
|
||||
}
|
||||
else
|
||||
{
|
||||
if ((s == 0.0f) || (t == 0.0f) ||
|
||||
(s == (Width() - 1.0f)) || (t == (Height() - 1.0f)) )
|
||||
{
|
||||
// If it's on the edge, it's max opacity
|
||||
opacity = 192.0f;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Channel zero is the opacity data
|
||||
opacity = m_SplinePatch.GetChannel( 0 );
|
||||
|
||||
// Make the shield translucent if the owner is the local player...
|
||||
// Also don't mess with the edges..
|
||||
if (m_ShieldOwnedByLocalPlayer)
|
||||
{
|
||||
// Channel 1 is the opacity blend
|
||||
float blendFactor = m_SplinePatch.GetChannel( 1 );
|
||||
blendFactor = clamp( blendFactor, 0.0f, 1.0f );
|
||||
|
||||
float blendValue = 1.0f;
|
||||
Vector delta;
|
||||
VectorSubtract( pt, GetAbsOrigin(), delta );
|
||||
float dist = VectorLength( delta );
|
||||
if (dist != 0.0f)
|
||||
{
|
||||
delta *= 1.0f / dist;
|
||||
float dot = DotProduct( m_ViewDir, delta );
|
||||
float angle = acos( dot );
|
||||
float fov = M_PI * render->GetFieldOfView() / 180.0f;
|
||||
if (angle < fov * .2f)
|
||||
blendValue = 0.1f;
|
||||
else if (angle < fov * 0.4f)
|
||||
{
|
||||
// Want a cos falloff between .2 and .4
|
||||
// 0.1 at .2 and 1.0 at .4
|
||||
angle -= fov * 0.2f;
|
||||
blendValue = 1.0f - 0.9f * 0.5f * (cos ( M_PI * angle / (fov * 0.2f) ) + 1.0f);
|
||||
}
|
||||
}
|
||||
|
||||
// Interpolate between 1 and the blend value based on the blend factor...
|
||||
opacity *= (1.0f - blendFactor) + blendFactor * blendValue;
|
||||
}
|
||||
|
||||
opacity = clamp( opacity, 0.0f, 192.0f );
|
||||
}
|
||||
}
|
||||
opacity *= m_FadeValue;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Compute the shield points using catmull-rom
|
||||
//-----------------------------------------------------------------------------
|
||||
void C_Shield::ComputeShieldPoints( Vector* pt, Vector* normal, float* opacity )
|
||||
{
|
||||
int i;
|
||||
for ( i = 0; i < m_SubdivisionCount; ++i)
|
||||
{
|
||||
float t = (Height() - 1) * (float)i * m_InvSubdivisionCount;
|
||||
for (int j = 0; j < m_SubdivisionCount; ++j)
|
||||
{
|
||||
float s = (Width() - 1) * (float)j * m_InvSubdivisionCount;
|
||||
int idx = i * m_SubdivisionCount + j;
|
||||
|
||||
ComputePoint( s, t, pt[idx], normal[idx], opacity[idx] );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Compute the shield ripples from being hit
|
||||
//-----------------------------------------------------------------------------
|
||||
void C_Shield::RippleShieldPoints( Vector* pt, float* opacity )
|
||||
{
|
||||
// Compute ripples:
|
||||
for ( int r = m_Ripples.Size(); --r >= 0; )
|
||||
{
|
||||
float dtime = gpGlobals->curtime - m_Ripples[r].m_StartTime;
|
||||
float decay = exp( -( 2 * dtime) );
|
||||
float amplitude = m_Ripples[r].m_Amplitude * decay;
|
||||
|
||||
for ( int i = 0; i < m_SubdivisionCount; ++i)
|
||||
{
|
||||
float t = i * m_InvSubdivisionCount;
|
||||
for (int j = 0; j < m_SubdivisionCount; ++j)
|
||||
{
|
||||
float s = j * m_InvSubdivisionCount;
|
||||
int idx = i * m_SubdivisionCount + j;
|
||||
|
||||
float ds = s - m_Ripples[r].m_RippleU;
|
||||
float dt = t - m_Ripples[r].m_RippleV;
|
||||
float dr = sqrt( ds * ds + dt * dt );
|
||||
if (dr < m_Ripples[r].m_Radius)
|
||||
{
|
||||
// need to apply ripple
|
||||
float diff = amplitude * cos( 0.5f * M_PI * dr / m_Ripples[r].m_Radius );
|
||||
VectorMA( pt[idx], diff, m_Ripples[r].m_Direction, pt[idx] );
|
||||
|
||||
// Compute opacity at this point...
|
||||
float impactopacity = 192.0f * decay * dr / m_Ripples[r].m_Radius;
|
||||
if (impactopacity > opacity[idx])
|
||||
opacity[idx] = impactopacity;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (amplitude < 0.1)
|
||||
m_Ripples.Remove(r);
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Main draw entry point
|
||||
//-----------------------------------------------------------------------------
|
||||
int C_Shield::DrawModel( int flags )
|
||||
{
|
||||
if ( !m_bReadyToDraw )
|
||||
return 0;
|
||||
|
||||
if (m_FadeValue == 0.0f)
|
||||
return 1;
|
||||
|
||||
// If I have no power, don't draw
|
||||
if ( m_flPowerLevel <= 0 )
|
||||
return 1;
|
||||
|
||||
// Make it curvy or not!!
|
||||
m_SplinePatch.SetLinearBlend( m_CurveValue );
|
||||
|
||||
// Set up the patch with all the data it's going to need
|
||||
int count = Width() * Height();
|
||||
Vector const** pControlPoints = (Vector const**)stackalloc(count * sizeof(Vector*));
|
||||
float* pControlOpacity = (float*)stackalloc(count * sizeof(float));
|
||||
float* pControlBlend = (float*)stackalloc(count * sizeof(float));
|
||||
|
||||
GetShieldData( pControlPoints, pControlOpacity, pControlBlend );
|
||||
m_SplinePatch.SetControlPositions( pControlPoints );
|
||||
m_SplinePatch.SetChannelData( 0, pControlOpacity );
|
||||
m_SplinePatch.SetChannelData( 1, pControlBlend );
|
||||
|
||||
// DrawWireframeModel( pControlPoints );
|
||||
|
||||
// Allocate space for temporary data
|
||||
int numSubdivisions = m_SubdivisionCount * m_SubdivisionCount;
|
||||
Vector* pt = (Vector*)stackalloc(numSubdivisions * sizeof(Vector));
|
||||
Vector* normal = (Vector*)stackalloc(numSubdivisions * sizeof(Vector));
|
||||
float* opacity = (float*)stackalloc(numSubdivisions * sizeof(float));
|
||||
|
||||
// Do something a little special if this shield is owned by the local player
|
||||
C_BasePlayer *player = C_BasePlayer::GetLocalPlayer();
|
||||
m_ShieldOwnedByLocalPlayer = (player->entindex() == m_nOwningPlayerIndex);
|
||||
if (m_ShieldOwnedByLocalPlayer)
|
||||
{
|
||||
QAngle viewAngles;
|
||||
engine->GetViewAngles(viewAngles);
|
||||
AngleVectors( viewAngles, &m_ViewDir );
|
||||
}
|
||||
|
||||
ComputeShieldPoints( pt, normal, opacity );
|
||||
RippleShieldPoints( pt, opacity );
|
||||
|
||||
// Commented out because it causes things to not be drawn behind it
|
||||
// DrawShieldDecals( pt, false );
|
||||
|
||||
DrawShieldPoints( pt, normal, opacity );
|
||||
DrawShieldDecals( pt, true );
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
|
||||
//============================================================================================================
|
||||
// SHIELD POWERLEVEL PROXY
|
||||
//============================================================================================================
|
||||
class CShieldPowerLevelProxy : public CResultProxy
|
||||
{
|
||||
public:
|
||||
void OnBind( void *pC_BaseEntity );
|
||||
};
|
||||
|
||||
void CShieldPowerLevelProxy::OnBind( void *pRenderable )
|
||||
{
|
||||
IClientRenderable *pRend = (IClientRenderable *)pRenderable;
|
||||
C_BaseEntity *pEntity = pRend->GetIClientUnknown()->GetBaseEntity();
|
||||
C_Shield *pShield = dynamic_cast<C_Shield*>(pEntity);
|
||||
if (!pShield)
|
||||
return;
|
||||
|
||||
SetFloatResult( pShield->GetPowerLevel() );
|
||||
}
|
||||
|
||||
EXPOSE_INTERFACE( CShieldPowerLevelProxy, IMaterialProxy, "ShieldPowerLevel" IMATERIAL_PROXY_INTERFACE_VERSION );
|
||||
@@ -0,0 +1,199 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose: Client's sheild entity
|
||||
//
|
||||
// $Workfile: $
|
||||
// $Date: $
|
||||
// $NoKeywords: $
|
||||
//=============================================================================//
|
||||
|
||||
#ifndef C_SHIELD_H
|
||||
#define C_SHIELD_H
|
||||
|
||||
#ifdef _WIN32
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include "SplinePatch.h"
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Shield:
|
||||
//-----------------------------------------------------------------------------
|
||||
class C_Shield : public C_BaseEntity
|
||||
{
|
||||
public:
|
||||
DECLARE_CLASS( C_Shield, C_BaseEntity );
|
||||
DECLARE_CLIENTCLASS();
|
||||
|
||||
// constructor, destructor
|
||||
C_Shield();
|
||||
~C_Shield();
|
||||
|
||||
// Inherited classes should call this in their constructor to indicate size...
|
||||
void InitShield( int w, int h, int subdivisions );
|
||||
|
||||
void OnDataChanged( DataUpdateType_t updateType );
|
||||
int DrawModel( int flags );
|
||||
void ReceiveMessage( int classID, bf_read &msg );
|
||||
|
||||
void CreateShieldDeflection( int hitgroup, const Vector &dir, bool partialBlock );
|
||||
|
||||
virtual bool ShouldDraw();
|
||||
virtual bool IsTransparent() { return true; }
|
||||
virtual void SetAlwaysOrient( bool bOrient ) {}
|
||||
virtual bool IsAlwaysOrienting( ) { return false; }
|
||||
virtual void SetCenterAngles( const QAngle & ) {}
|
||||
virtual void SetAttachmentIndex( int nAttachmentIndex ) {}
|
||||
|
||||
// returns the address of a variable that stores the material animation frame
|
||||
float GetTextureAnimationStartTime();
|
||||
|
||||
// Indicates that a texture animation has wrapped
|
||||
void TextureAnimationWrapped();
|
||||
|
||||
virtual bool ShouldCollide( int collisionGroup, int contentsMask ) const;
|
||||
|
||||
// Collision detection
|
||||
// Activates/deactivates a shield for collision purposes
|
||||
void ActivateCollisions( bool activate );
|
||||
|
||||
// Deactivates all shields of players on a particular team
|
||||
// If you don't specify a team, it'll affect all shields
|
||||
static void ActivateShields( bool activate, int team = -1 );
|
||||
virtual const Vector& GetPoint( int x, int y ) { return vec3_origin; }
|
||||
|
||||
// For collision testing
|
||||
bool TestCollision( const Ray_t& ray, unsigned int mask, trace_t& trace );
|
||||
|
||||
// Called when we hit something that we deflect...
|
||||
void RegisterDeflection(const Vector& vecDir, int bitsDamageType, trace_t *ptr);
|
||||
|
||||
float GetPowerLevel( void ) { return m_flPowerLevel; }
|
||||
|
||||
bool IsEMPed() const;
|
||||
void SetEMPed( bool bIsEmped );
|
||||
|
||||
protected:
|
||||
//
|
||||
// Inheriting classes must implement these methods!!!
|
||||
//
|
||||
|
||||
// Return true if the panel is active
|
||||
virtual bool IsPanelActive( int x, int y ) { assert(0); return false; }
|
||||
|
||||
// Gets at the control point data; who knows how it was made?
|
||||
virtual void GetShieldData( Vector const** ppVerts, float* pOpacity, float* pBlend ) { assert(0); }
|
||||
|
||||
private:
|
||||
void DrawWireframeModel( Vector const** pPositions );
|
||||
void ComputePoint( float s, float t, Vector& pt, Vector& normal, float& opacity );
|
||||
void ComputeShieldPoints( Vector* pt, Vector* normal, float* opacity );
|
||||
void RippleShieldPoints( Vector* pt, float* opacity );
|
||||
void DrawShieldPoints(Vector* pt, Vector* normal, float* opacity);
|
||||
void DrawShieldDecals(Vector* pt, bool hitDecals );
|
||||
void SetCurrentDecal( int idx );
|
||||
|
||||
int Width() const;
|
||||
int Height() const;
|
||||
|
||||
protected:
|
||||
// Used to fade out the shield
|
||||
float m_FadeValue;
|
||||
|
||||
// Used to make the shield more or less curvy
|
||||
float m_CurveValue;
|
||||
|
||||
private:
|
||||
// no copy constructor
|
||||
C_Shield( const C_Shield& );
|
||||
|
||||
// Data needs to ripple the shield control points
|
||||
struct Ripple_t
|
||||
{
|
||||
float m_RippleU;
|
||||
float m_RippleV;
|
||||
float m_Amplitude;
|
||||
float m_Radius;
|
||||
float m_StartTime;
|
||||
Vector m_Direction;
|
||||
};
|
||||
|
||||
struct Decal_t
|
||||
{
|
||||
float m_RippleU;
|
||||
float m_RippleV;
|
||||
float m_Radius;
|
||||
float m_StartTime;
|
||||
};
|
||||
|
||||
// Owner entity
|
||||
int m_nOwningPlayerIndex;
|
||||
|
||||
// number of subdivisions
|
||||
int m_SubdivisionCount;
|
||||
float m_InvSubdivisionCount;
|
||||
|
||||
// Shield powerlevel
|
||||
float m_flPowerLevel;
|
||||
|
||||
// Texture animation
|
||||
float m_StartTime;
|
||||
|
||||
bool m_bCollisionsActive;
|
||||
bool m_bIsEMPed;
|
||||
|
||||
// Used to do spline queries
|
||||
CSplinePatch m_SplinePatch;
|
||||
|
||||
// List of all ripples + decals
|
||||
int m_CurrentDecal;
|
||||
CUtlVector< Ripple_t > m_Ripples;
|
||||
CUtlVector< Decal_t > m_Decals;
|
||||
|
||||
// All the various materials we use
|
||||
CMaterialReference m_pWireframe;
|
||||
CMaterialReference m_pShield;
|
||||
CMaterialReference m_pHitDecal;
|
||||
CMaterialReference m_pPassDecal;
|
||||
CMaterialReference m_pPassDecal2;
|
||||
|
||||
// A little state used only during rendering, but I didn't want
|
||||
// to pass these as arguments to a bunch of functions
|
||||
bool m_ShieldOwnedByLocalPlayer;
|
||||
Vector m_ViewDir;
|
||||
|
||||
// List of all active shields
|
||||
static CUtlVector< C_Shield* > s_Shields;
|
||||
};
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Inline methods
|
||||
//-----------------------------------------------------------------------------
|
||||
inline int C_Shield::Width() const
|
||||
{
|
||||
return m_SplinePatch.Width();
|
||||
}
|
||||
|
||||
inline int C_Shield::Height() const
|
||||
{
|
||||
return m_SplinePatch.Height();
|
||||
}
|
||||
|
||||
inline bool C_Shield::IsEMPed() const
|
||||
{
|
||||
return m_bIsEMPed;
|
||||
}
|
||||
|
||||
inline void C_Shield::SetEMPed( bool bIsEmped )
|
||||
{
|
||||
m_bIsEMPed = bIsEmped;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Class factory methods to create the various versions of the shield
|
||||
//-----------------------------------------------------------------------------
|
||||
C_Shield* CreateMobileShield( C_BaseEntity *owner, float flFrontDistance = 0 );
|
||||
|
||||
#endif // C_SHIELD_H
|
||||
@@ -0,0 +1,350 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose: Client's sheild entity
|
||||
//
|
||||
// $Workfile: $
|
||||
// $Date: $
|
||||
// $NoKeywords: $
|
||||
//=============================================================================//
|
||||
#include "cbase.h"
|
||||
#include "C_Shield.h"
|
||||
#include "tf_shieldshared.h"
|
||||
#include "c_basetfplayer.h"
|
||||
|
||||
enum
|
||||
{
|
||||
NUM_SUBDIVISIONS = 21,
|
||||
};
|
||||
|
||||
#define EMP_WAVE_AMPLITUDE 6.0f
|
||||
#define EMP_GROW_WIDTH_DELAY 0.2f
|
||||
#define EMP_GROW_TIME 0.6f
|
||||
#define EMP_GROW_ATTEN 0.5f
|
||||
#define EMP_MIN_WIDTH 5.0f
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Flat version of the shield
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
class C_ShieldFlat : public C_Shield
|
||||
{
|
||||
public:
|
||||
DECLARE_CLASS( C_ShieldFlat, C_Shield );
|
||||
DECLARE_CLIENTCLASS();
|
||||
|
||||
C_ShieldFlat();
|
||||
~C_ShieldFlat();
|
||||
|
||||
virtual void GetBounds( Vector& mins, Vector& maxs );
|
||||
|
||||
virtual void AddEntity( );
|
||||
|
||||
virtual void SetDormant( bool bDormant );
|
||||
|
||||
// Return true if the panel is active
|
||||
virtual bool IsPanelActive( int x, int y );
|
||||
|
||||
// Gets at the control point data; who knows how it was made?
|
||||
virtual void GetShieldData( Vector const** ppVerts, float* pOpacity, float* pBlend );
|
||||
virtual const Vector& GetPoint( int x, int y );
|
||||
|
||||
// Draws the model
|
||||
virtual int DrawModel( int flags );
|
||||
|
||||
public:
|
||||
// networked data
|
||||
unsigned char m_ShieldState;
|
||||
float m_Width;
|
||||
float m_Height;
|
||||
|
||||
float m_DeathFade;
|
||||
float m_EMPFade;
|
||||
|
||||
private:
|
||||
void ShieldMoved( void );
|
||||
|
||||
private:
|
||||
C_ShieldFlat( const C_ShieldFlat& );
|
||||
void ComputeEMPFade();
|
||||
void ComputeDeathFade();
|
||||
void ComputeSize( float& w, float& h );
|
||||
void PreRender( );
|
||||
|
||||
Vector m_pPositions[4];
|
||||
Vector m_Forward;
|
||||
float m_EnterPVSTime;
|
||||
|
||||
QAngle m_LastAngles;
|
||||
Vector m_LastPosition;
|
||||
Vector m_Pos[4];
|
||||
};
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Data table
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
IMPLEMENT_CLIENTCLASS_DT(C_ShieldFlat, DT_Shield_Flat, CShieldFlat)
|
||||
|
||||
RecvPropInt( RECVINFO(m_ShieldState) ),
|
||||
RecvPropFloat( RECVINFO(m_Width) ),
|
||||
RecvPropFloat( RECVINFO(m_Height) ),
|
||||
|
||||
END_RECV_TABLE()
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Constructor, destructor
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
C_ShieldFlat::C_ShieldFlat()
|
||||
{
|
||||
m_DeathFade = 1.0f;
|
||||
m_EMPFade = 1.0f;
|
||||
|
||||
InitShield( 2, 2, 6 );
|
||||
}
|
||||
|
||||
C_ShieldFlat::~C_ShieldFlat()
|
||||
{
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Leaving/entering the PVS on the server.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
void C_ShieldFlat::SetDormant( bool bDormant )
|
||||
{
|
||||
if (!bDormant)
|
||||
{
|
||||
if (m_ShieldState & SHIELD_FLAT_EMP)
|
||||
{
|
||||
m_EMPFade = 0.0f;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_EMPFade = 1.0f;
|
||||
}
|
||||
|
||||
m_EnterPVSTime = 0.0f;
|
||||
if (m_ShieldState & SHIELD_FLAT_INACTIVE)
|
||||
{
|
||||
m_DeathFade = 0.0f;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_EnterPVSTime = gpGlobals->curtime;
|
||||
m_DeathFade = 1.0f;
|
||||
}
|
||||
}
|
||||
|
||||
BaseClass::SetDormant(bDormant);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Figures the EMP fade factor
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
void C_ShieldFlat::ComputeEMPFade()
|
||||
{
|
||||
if (m_ShieldState & SHIELD_FLAT_EMP)
|
||||
{
|
||||
// Decay fade if we've been EMPed or if we're inactive
|
||||
if (m_EMPFade > 0.0f)
|
||||
{
|
||||
m_EMPFade -= gpGlobals->frametime / SHIELD_EMP_FADE_TIME;
|
||||
if (m_EMPFade < 0.0f)
|
||||
{
|
||||
m_EMPFade = 0.0f;
|
||||
}
|
||||
else
|
||||
{
|
||||
Vector dir;
|
||||
|
||||
// Futz with the control points if we've been EMPed
|
||||
for (int i = 0; i < 4; ++i)
|
||||
{
|
||||
float dist = -EMP_WAVE_AMPLITUDE * sin( i * M_PI * 0.5f + gpGlobals->curtime * M_PI / SHIELD_EMP_WOBBLE_TIME );
|
||||
VectorMA( m_pPositions[i], dist, m_Forward, m_pPositions[i] );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Fade back in, no longer EMPed
|
||||
if (m_EMPFade < 1.0f)
|
||||
{
|
||||
m_EMPFade += gpGlobals->frametime / SHIELD_EMP_FADE_TIME;
|
||||
if (m_EMPFade >= 1.0f)
|
||||
{
|
||||
m_EMPFade = 1.0f;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Figures the networked fade factor
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
void C_ShieldFlat::ComputeDeathFade()
|
||||
{
|
||||
if (m_ShieldState & SHIELD_FLAT_INACTIVE)
|
||||
{
|
||||
// Fade out when we become inactive
|
||||
if (m_DeathFade > 0.0f)
|
||||
{
|
||||
m_DeathFade -= gpGlobals->frametime / SHIELD_FLAT_SHUTDOWN_TIME;
|
||||
if (m_DeathFade < 0.0f)
|
||||
{
|
||||
m_DeathFade = 0.0f;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Active? We should be visible
|
||||
m_DeathFade = 1.0f;
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// A little pre-render processing
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
void C_ShieldFlat::ComputeSize( float& w, float& h )
|
||||
{
|
||||
w = m_Width;
|
||||
h = m_Height;
|
||||
|
||||
float dt = gpGlobals->curtime - m_EnterPVSTime;
|
||||
if (dt > EMP_GROW_TIME)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (dt < 0)
|
||||
dt = 0.0f;
|
||||
|
||||
// Attenuate it up
|
||||
w *= 1.0f - pow ( EMP_GROW_ATTEN, 10 * (dt / EMP_GROW_TIME ));
|
||||
|
||||
if (w < EMP_MIN_WIDTH)
|
||||
w = EMP_MIN_WIDTH;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// A little pre-render processing
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
void C_ShieldFlat::PreRender( )
|
||||
{
|
||||
// Compute the shield positions...
|
||||
Vector right, up;
|
||||
AngleVectors( GetRenderAngles(), &m_Forward, &right, &up );
|
||||
|
||||
float w, h;
|
||||
ComputeSize( w, h );
|
||||
|
||||
VectorMA( GetRenderOrigin(), -w * 0.5, right, m_pPositions[0] );
|
||||
VectorMA( m_pPositions[0], -h * 0.5, up, m_pPositions[0] );
|
||||
VectorMA( m_pPositions[0], w, right, m_pPositions[1] );
|
||||
VectorMA( m_pPositions[0], h, up, m_pPositions[2] );
|
||||
VectorMA( m_pPositions[2], w, right, m_pPositions[3] );
|
||||
|
||||
ComputeEMPFade();
|
||||
ComputeDeathFade();
|
||||
|
||||
m_FadeValue = m_DeathFade * m_EMPFade;
|
||||
}
|
||||
|
||||
void C_ShieldFlat::AddEntity( )
|
||||
{
|
||||
BaseClass::AddEntity( );
|
||||
PreRender();
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Bounds computation
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
void C_ShieldFlat::GetBounds( Vector& mins, Vector& maxs )
|
||||
{
|
||||
mins.Init( -1.0/16.0f, -m_Width * 0.5f, -m_Height * 0.5f );
|
||||
maxs.Init( 1.0/16.0f, m_Width * 0.5f, m_Height * 0.5f );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Return true if the panel is active
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
bool C_ShieldFlat::IsPanelActive( int x, int y )
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Gets at the control point data; who knows how it was made?
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
void C_ShieldFlat::GetShieldData( Vector const** ppVerts, float* pOpacity, float* pBlend )
|
||||
{
|
||||
for ( int i = 0; i < 4; ++i )
|
||||
{
|
||||
ppVerts[i] = &m_pPositions[i];
|
||||
pOpacity[i] = 32.0f;
|
||||
pBlend[i] = 0.0f;
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Shield points
|
||||
//-----------------------------------------------------------------------------
|
||||
const Vector& C_ShieldFlat::GetPoint( int x, int y )
|
||||
{
|
||||
if ((m_LastAngles != GetAbsAngles()) || (m_LastPosition != GetAbsOrigin() ))
|
||||
{
|
||||
ShieldMoved();
|
||||
}
|
||||
|
||||
int i = (x >= 1);
|
||||
i += (y >= 1) * 2;
|
||||
return m_Pos[i];
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Computes the shield bounding box
|
||||
//-----------------------------------------------------------------------------
|
||||
void C_ShieldFlat::ShieldMoved( void )
|
||||
{
|
||||
Vector forward, right, up;
|
||||
AngleVectors( GetAbsAngles(), &forward, &right, &up );
|
||||
|
||||
VectorMA( GetAbsOrigin(), -m_Width * 0.5, right, m_Pos[0] );
|
||||
VectorMA( m_Pos[0], -m_Height * 0.5, up, m_Pos[0] );
|
||||
VectorMA( m_Pos[0], m_Width, right, m_Pos[1] );
|
||||
VectorMA( m_Pos[0], m_Height, up, m_Pos[2] );
|
||||
VectorMA( m_Pos[2], m_Width, right, m_Pos[3] );
|
||||
|
||||
m_LastAngles = GetAbsAngles();
|
||||
m_LastPosition = GetAbsOrigin();
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Suppress rendering if the player owns it
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
int C_ShieldFlat::DrawModel( int flags )
|
||||
{
|
||||
if ( !m_bReadyToDraw )
|
||||
return 0;
|
||||
|
||||
// Don't draw it if the owner is the local player
|
||||
// if ( m_OwnerEntity == C_BasePlayer::GetLocalPlayer()->index )
|
||||
// return 0;
|
||||
|
||||
return BaseClass::DrawModel( flags );
|
||||
}
|
||||
|
||||
@@ -0,0 +1,274 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose: Client's sheild entity
|
||||
//
|
||||
// $Workfile: $
|
||||
// $NoKeywords: $
|
||||
//=============================================================================//
|
||||
#include "cbase.h"
|
||||
#include "C_Shield.h"
|
||||
#include "tf_shieldshared.h"
|
||||
|
||||
enum
|
||||
{
|
||||
NUM_SUBDIVISIONS = 21,
|
||||
};
|
||||
|
||||
#define EMP_WAVE_AMPLITUDE 8.0f
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Mobile version of the shield
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
class C_ShieldMobile;
|
||||
class C_ShieldMobileActiveVertList : public IActiveVertList
|
||||
{
|
||||
public:
|
||||
void Init( C_ShieldMobile *pShield, unsigned char *pVertList );
|
||||
|
||||
// IActiveVertList overrides.
|
||||
public:
|
||||
|
||||
virtual int GetActiveVertState( int iVert );
|
||||
virtual void SetActiveVertState( int iVert, int bOn );
|
||||
|
||||
private:
|
||||
C_ShieldMobile *m_pShield;
|
||||
unsigned char *m_pVertsActive;
|
||||
};
|
||||
|
||||
|
||||
class C_ShieldMobile : public C_Shield
|
||||
{
|
||||
DECLARE_CLASS( C_ShieldMobile, C_Shield );
|
||||
public:
|
||||
DECLARE_CLIENTCLASS();
|
||||
|
||||
C_ShieldMobile();
|
||||
~C_ShieldMobile();
|
||||
|
||||
void OnDataChanged( DataUpdateType_t updateType );
|
||||
virtual void GetBounds( Vector& mins, Vector& maxs );
|
||||
|
||||
virtual void AddEntity( );
|
||||
|
||||
// Return true if the panel is active
|
||||
virtual bool IsPanelActive( int x, int y );
|
||||
|
||||
// Gets at the control point data; who knows how it was made?
|
||||
virtual void GetShieldData( Vector const** ppVerts, float* pOpacity, float* pBlend );
|
||||
virtual const Vector& GetPoint( int x, int y ) { return m_ShieldEffect.GetPoint( x, y ); }
|
||||
|
||||
virtual void SetThetaPhi( float flTheta, float flPhi ) { m_ShieldEffect.SetThetaPhi(flTheta,flPhi); }
|
||||
|
||||
public:
|
||||
// networked data
|
||||
unsigned char m_pVertsActive[SHIELD_VERTEX_BYTES];
|
||||
unsigned char m_ShieldState;
|
||||
|
||||
private:
|
||||
C_ShieldMobile( const C_ShieldMobile& );
|
||||
|
||||
// Is a particular panel an edge?
|
||||
bool IsVertexValid( float s, float t ) const;
|
||||
void PreRender( );
|
||||
|
||||
private:
|
||||
CShieldEffect m_ShieldEffect;
|
||||
C_ShieldMobileActiveVertList m_VertList;
|
||||
float m_flTheta;
|
||||
float m_flPhi;
|
||||
};
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// C_ShieldMobileActiveVertList functions
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
void C_ShieldMobileActiveVertList::Init( C_ShieldMobile *pShield, unsigned char *pVertList )
|
||||
{
|
||||
m_pShield = pShield;
|
||||
m_pVertsActive = pVertList;
|
||||
}
|
||||
|
||||
|
||||
int C_ShieldMobileActiveVertList::GetActiveVertState( int iVert )
|
||||
{
|
||||
return m_pVertsActive[iVert>>3] & (1 << (iVert & 7));
|
||||
}
|
||||
|
||||
|
||||
void C_ShieldMobileActiveVertList::SetActiveVertState( int iVert, int bOn )
|
||||
{
|
||||
if ( bOn )
|
||||
m_pVertsActive[iVert>>3] |= (1 << (iVert & 7));
|
||||
else
|
||||
m_pVertsActive[iVert>>3] &= ~(1 << (iVert & 7));
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Data table
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
IMPLEMENT_CLIENTCLASS_DT(C_ShieldMobile, DT_Shield_Mobile, CShieldMobile)
|
||||
|
||||
RecvPropInt( RECVINFO(m_ShieldState) ),
|
||||
RecvPropArray(
|
||||
RecvPropInt( RECVINFO(m_pVertsActive[0])),
|
||||
m_pVertsActive
|
||||
),
|
||||
RecvPropFloat( RECVINFO(m_flTheta) ),
|
||||
RecvPropFloat( RECVINFO(m_flPhi) ),
|
||||
|
||||
END_RECV_TABLE()
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Various raycasting routines
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
|
||||
void ShieldTraceLine(const Vector &vecStart, const Vector &vecEnd,
|
||||
unsigned int mask, int collisionGroup, trace_t *ptr)
|
||||
{
|
||||
UTIL_TraceLine(vecStart, vecEnd, mask, NULL, collisionGroup, ptr );
|
||||
}
|
||||
|
||||
void ShieldTraceHull(const Vector &vecStart, const Vector &vecEnd,
|
||||
const Vector &hullMin, const Vector &hullMax,
|
||||
unsigned int mask, int collisionGroup, trace_t *ptr)
|
||||
{
|
||||
CTraceFilterWorldOnly traceFilter;
|
||||
enginetrace->TraceHull( vecStart, vecEnd, hullMin, hullMax, mask, &traceFilter, ptr );
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Constructor, destructor
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
C_ShieldMobile::C_ShieldMobile() : m_ShieldEffect(ShieldTraceLine, ShieldTraceHull)
|
||||
{
|
||||
m_VertList.Init( this, m_pVertsActive );
|
||||
m_ShieldEffect.SetActiveVertexList( &m_VertList );
|
||||
m_ShieldEffect.Spawn(vec3_origin, vec3_angle);
|
||||
InitShield( SHIELD_NUM_HORIZONTAL_POINTS, SHIELD_NUM_VERTICAL_POINTS, NUM_SUBDIVISIONS );
|
||||
}
|
||||
|
||||
C_ShieldMobile::~C_ShieldMobile()
|
||||
{
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Get this after the data changes
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
void C_ShieldMobile::OnDataChanged( DataUpdateType_t updateType )
|
||||
{
|
||||
BaseClass::OnDataChanged( updateType );
|
||||
|
||||
m_ShieldEffect.SetCurrentPosition( GetAbsOrigin() );
|
||||
m_ShieldEffect.SetCurrentAngles( GetAbsAngles() );
|
||||
m_ShieldEffect.SetThetaPhi( m_flTheta, m_flPhi );
|
||||
|
||||
// No need to simulate, just compute active panels from network data
|
||||
m_ShieldEffect.ComputeControlPoints();
|
||||
m_ShieldEffect.ComputePanelActivity();
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// A little pre-render processing
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
void C_ShieldMobile::PreRender( )
|
||||
{
|
||||
if (m_ShieldState & SHIELD_MOBILE_EMP)
|
||||
{
|
||||
// Decay fade if we've been EMPed or if we're inactive
|
||||
if (m_FadeValue > 0.0f)
|
||||
{
|
||||
m_FadeValue -= gpGlobals->frametime / SHIELD_EMP_FADE_TIME;
|
||||
if (m_FadeValue < 0.0f)
|
||||
{
|
||||
m_FadeValue = 0.0f;
|
||||
|
||||
// Reset the shield to un-wobbled state
|
||||
m_ShieldEffect.ComputeControlPoints();
|
||||
}
|
||||
else
|
||||
{
|
||||
Vector dir;
|
||||
AngleVectors( m_ShieldEffect.GetCurrentAngles(), & dir );
|
||||
|
||||
// Futz with the control points if we've been EMPed
|
||||
for (int i = 0; i < SHIELD_NUM_CONTROL_POINTS; ++i)
|
||||
{
|
||||
// Get the direction for the point
|
||||
float factor = -EMP_WAVE_AMPLITUDE * sin( i * M_PI * 0.5f + gpGlobals->curtime * M_PI / SHIELD_EMP_WOBBLE_TIME );
|
||||
m_ShieldEffect.GetPoint(i) += dir * factor;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Fade back in, no longer EMPed
|
||||
if (m_FadeValue < 1.0f)
|
||||
{
|
||||
m_FadeValue += gpGlobals->frametime / SHIELD_EMP_FADE_TIME;
|
||||
if (m_FadeValue >= 1.0f)
|
||||
{
|
||||
m_FadeValue = 1.0f;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void C_ShieldMobile::AddEntity( )
|
||||
{
|
||||
BaseClass::AddEntity( );
|
||||
PreRender();
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Bounds computation
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
void C_ShieldMobile::GetBounds( Vector& mins, Vector& maxs )
|
||||
{
|
||||
m_ShieldEffect.ComputeBounds( mins, maxs );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Return true if the panel is active
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
bool C_ShieldMobile::IsPanelActive( int x, int y )
|
||||
{
|
||||
return m_ShieldEffect.IsPanelActive(x, y);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Gets at the control point data; who knows how it was made?
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
void C_ShieldMobile::GetShieldData( Vector const** ppVerts, float* pOpacity, float* pBlend )
|
||||
{
|
||||
for ( int i = 0; i < SHIELD_NUM_CONTROL_POINTS; ++i )
|
||||
{
|
||||
ppVerts[i] = &m_ShieldEffect.GetControlPoint(i);
|
||||
|
||||
if ( m_pVertsActive[i >> 3] & (1 << (i & 0x7)) )
|
||||
{
|
||||
pOpacity[i] = m_ShieldEffect.ComputeOpacity( *ppVerts[i], GetAbsOrigin() );
|
||||
pBlend[i] = 1.0f;
|
||||
}
|
||||
else
|
||||
{
|
||||
pOpacity[i] = 192.0f;
|
||||
pBlend[i] = 0.0f;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user