mirror of
https://github.com/nillerusr/source-engine.git
synced 2026-08-03 11:23:38 +00:00
1
This commit is contained in:
@@ -0,0 +1,120 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
// c_bot_npc.cpp
|
||||
|
||||
#include "cbase.h"
|
||||
#include "NextBot/C_NextBot.h"
|
||||
#include "c_bot_npc.h"
|
||||
|
||||
// memdbgon must be the last include file in a .cpp file!!!
|
||||
#include "tier0/memdbgon.h"
|
||||
|
||||
#undef NextBot
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
IMPLEMENT_CLIENTCLASS_DT( C_BotNPC, DT_BotNPC, CBotNPC )
|
||||
|
||||
RecvPropEHandle( RECVINFO( m_laserTarget ) ),
|
||||
RecvPropBool( RECVINFO( m_isNuking ) ),
|
||||
|
||||
END_RECV_TABLE()
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
C_BotNPC::C_BotNPC()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
C_BotNPC::~C_BotNPC()
|
||||
{
|
||||
if ( m_laserBeamEffect )
|
||||
{
|
||||
ParticleProp()->StopEmissionAndDestroyImmediately( m_laserBeamEffect );
|
||||
m_laserBeamEffect = NULL;
|
||||
}
|
||||
|
||||
if ( m_nukeEffect )
|
||||
{
|
||||
ParticleProp()->StopEmissionAndDestroyImmediately( m_nukeEffect );
|
||||
m_nukeEffect = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
void C_BotNPC::Spawn( void )
|
||||
{
|
||||
BaseClass::Spawn();
|
||||
|
||||
m_vecViewOffset = Vector( 0, 0, 180.0f );
|
||||
|
||||
SetNextClientThink( CLIENT_THINK_ALWAYS );
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
void C_BotNPC::ClientThink( void )
|
||||
{
|
||||
if ( m_laserTarget )
|
||||
{
|
||||
if ( !m_laserBeamEffect )
|
||||
{
|
||||
m_laserBeamEffect = ParticleProp()->Create( "laser_sight_beam", PATTACH_POINT_FOLLOW, LookupAttachment( "head" ) );
|
||||
}
|
||||
|
||||
if ( m_laserBeamEffect )
|
||||
{
|
||||
m_laserBeamEffect->SetSortOrigin( m_laserBeamEffect->GetRenderOrigin() );
|
||||
m_laserBeamEffect->SetControlPoint( 2, Vector( 0, 255, 0 ) );
|
||||
m_laserBeamEffect->SetControlPoint( 1, m_laserTarget->WorldSpaceCenter() );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// shut off the laser
|
||||
if ( m_laserBeamEffect )
|
||||
{
|
||||
ParticleProp()->StopEmissionAndDestroyImmediately( m_laserBeamEffect );
|
||||
m_laserBeamEffect = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
if ( m_isNuking )
|
||||
{
|
||||
if ( !m_nukeEffect )
|
||||
{
|
||||
m_nukeEffect = ParticleProp()->Create( "charge_up", PATTACH_POINT_FOLLOW, LookupAttachment( "head" ) );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( m_nukeEffect )
|
||||
{
|
||||
ParticleProp()->StopEmissionAndDestroyImmediately( m_nukeEffect );
|
||||
m_nukeEffect = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Return the origin for player observers tracking this target
|
||||
Vector C_BotNPC::GetObserverCamOrigin( void )
|
||||
{
|
||||
return EyePosition();
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
void C_BotNPC::FireEvent( const Vector& origin, const QAngle& angles, int event, const char *options )
|
||||
{
|
||||
if ( event == 7001 )
|
||||
{
|
||||
EmitSound( "RobotBoss.Footstep" );
|
||||
|
||||
/*
|
||||
ParticleProp()->Create( "halloween_boss_foot_impact", PATTACH_ABSORIGIN, 0 );
|
||||
*/
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
#ifndef C_BOT_NPC_H
|
||||
#define C_BOT_NPC_H
|
||||
|
||||
#include "c_ai_basenpc.h"
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------------
|
||||
/**
|
||||
* The client-side implementation of Bot NPC
|
||||
*/
|
||||
class C_BotNPC : public C_NextBotCombatCharacter
|
||||
{
|
||||
public:
|
||||
DECLARE_CLASS( C_BotNPC, C_NextBotCombatCharacter );
|
||||
DECLARE_CLIENTCLASS();
|
||||
|
||||
C_BotNPC();
|
||||
virtual ~C_BotNPC();
|
||||
|
||||
public:
|
||||
virtual void Spawn( void );
|
||||
virtual bool IsNextBot() { return true; }
|
||||
|
||||
virtual Vector GetObserverCamOrigin( void ); // Return the origin for player observers tracking this target
|
||||
|
||||
virtual void FireEvent( const Vector& origin, const QAngle& angles, int event, const char *options );
|
||||
|
||||
virtual void ClientThink();
|
||||
|
||||
private:
|
||||
C_BotNPC( const C_BotNPC & ); // not defined, not accessible
|
||||
|
||||
CNetworkHandle( C_BaseEntity, m_laserTarget );
|
||||
HPARTICLEFFECT m_laserBeamEffect;
|
||||
|
||||
CNetworkVar( bool, m_isNuking );
|
||||
HPARTICLEFFECT m_nukeEffect;
|
||||
};
|
||||
|
||||
|
||||
#endif // C_BOT_NPC_H
|
||||
@@ -0,0 +1,115 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
// c_bot_npc_minion.cpp
|
||||
|
||||
#include "cbase.h"
|
||||
#include "NextBot/C_NextBot.h"
|
||||
#include "c_bot_npc_minion.h"
|
||||
|
||||
// memdbgon must be the last include file in a .cpp file!!!
|
||||
#include "tier0/memdbgon.h"
|
||||
|
||||
#undef NextBot
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
IMPLEMENT_CLIENTCLASS_DT( C_BotNPCMinion, DT_BotNPCMinion, CBotNPCMinion )
|
||||
|
||||
RecvPropEHandle( RECVINFO( m_stunTarget ) ),
|
||||
|
||||
END_RECV_TABLE()
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
C_BotNPCMinion::C_BotNPCMinion()
|
||||
{
|
||||
m_stunEffect = NULL;
|
||||
m_stunBeamEffect = NULL;
|
||||
m_scanEffect = NULL;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
C_BotNPCMinion::~C_BotNPCMinion()
|
||||
{
|
||||
if ( m_stunEffect )
|
||||
{
|
||||
ParticleProp()->StopEmissionAndDestroyImmediately( m_stunEffect );
|
||||
m_stunEffect = NULL;
|
||||
}
|
||||
|
||||
if ( m_stunBeamEffect )
|
||||
{
|
||||
ParticleProp()->StopEmissionAndDestroyImmediately( m_stunBeamEffect );
|
||||
m_stunBeamEffect = NULL;
|
||||
}
|
||||
|
||||
if ( m_scanEffect )
|
||||
{
|
||||
ParticleProp()->StopEmissionAndDestroyImmediately( m_scanEffect );
|
||||
m_scanEffect = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
void C_BotNPCMinion::Spawn( void )
|
||||
{
|
||||
BaseClass::Spawn();
|
||||
|
||||
SetNextClientThink( CLIENT_THINK_ALWAYS );
|
||||
|
||||
//m_scanEffect = ParticleProp()->Create( "minion_scan", PATTACH_ABSORIGIN_FOLLOW );
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
void C_BotNPCMinion::ClientThink( void )
|
||||
{
|
||||
if ( m_stunTarget )
|
||||
{
|
||||
if ( !m_stunEffect )
|
||||
{
|
||||
m_stunEffect = ParticleProp()->Create( "cart_flashinglight", PATTACH_ABSORIGIN_FOLLOW );
|
||||
}
|
||||
|
||||
if ( !m_stunBeamEffect )
|
||||
{
|
||||
m_stunBeamEffect = ParticleProp()->Create( "laser_sight_beam", PATTACH_ABSORIGIN_FOLLOW );
|
||||
}
|
||||
|
||||
if ( m_stunBeamEffect )
|
||||
{
|
||||
m_stunBeamEffect->SetSortOrigin( m_stunBeamEffect->GetRenderOrigin() );
|
||||
m_stunBeamEffect->SetControlPoint( 2, Vector( 255, 0, 255 ) );
|
||||
m_stunBeamEffect->SetControlPoint( 1, m_stunTarget->WorldSpaceCenter() );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// shut off the effect
|
||||
if ( m_stunEffect )
|
||||
{
|
||||
ParticleProp()->StopEmissionAndDestroyImmediately( m_stunEffect );
|
||||
m_stunEffect = NULL;
|
||||
}
|
||||
|
||||
if ( m_stunBeamEffect )
|
||||
{
|
||||
ParticleProp()->StopEmissionAndDestroyImmediately( m_stunBeamEffect );
|
||||
m_stunBeamEffect = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Return the origin for player observers tracking this target
|
||||
Vector C_BotNPCMinion::GetObserverCamOrigin( void )
|
||||
{
|
||||
return GetAbsOrigin();
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
void C_BotNPCMinion::FireEvent( const Vector& origin, const QAngle& angles, int event, const char *options )
|
||||
{
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
#ifndef C_BOT_NPC_MINION_H
|
||||
#define C_BOT_NPC_MINION_H
|
||||
|
||||
#include "c_ai_basenpc.h"
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------------
|
||||
/**
|
||||
* The client-side implementation of Bot NPC Minion
|
||||
*/
|
||||
class C_BotNPCMinion : public C_NextBotCombatCharacter
|
||||
{
|
||||
public:
|
||||
DECLARE_CLASS( C_BotNPCMinion, C_NextBotCombatCharacter );
|
||||
DECLARE_CLIENTCLASS();
|
||||
|
||||
C_BotNPCMinion();
|
||||
virtual ~C_BotNPCMinion();
|
||||
|
||||
public:
|
||||
virtual void Spawn( void );
|
||||
virtual bool IsNextBot() { return true; }
|
||||
|
||||
virtual Vector GetObserverCamOrigin( void ); // Return the origin for player observers tracking this target
|
||||
|
||||
virtual void FireEvent( const Vector& origin, const QAngle& angles, int event, const char *options );
|
||||
|
||||
virtual void ClientThink();
|
||||
|
||||
private:
|
||||
C_BotNPCMinion( const C_BotNPCMinion & ); // not defined, not accessible
|
||||
|
||||
CNetworkHandle( C_BaseEntity, m_stunTarget );
|
||||
HPARTICLEFFECT m_stunEffect;
|
||||
HPARTICLEFFECT m_stunBeamEffect;
|
||||
HPARTICLEFFECT m_scanEffect;
|
||||
};
|
||||
|
||||
|
||||
#endif // C_BOT_NPC_MINION_H
|
||||
@@ -0,0 +1,77 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
//
|
||||
//
|
||||
//=============================================================================
|
||||
#include "cbase.h"
|
||||
#include "c_tf_bot_hint_engineer_nest.h"
|
||||
|
||||
IMPLEMENT_CLIENTCLASS_DT(C_TFBotHintEngineerNest, DT_TFBotHintEngineerNest, CTFBotHintEngineerNest)
|
||||
RecvPropBool( RECVINFO(m_bHasActiveTeleporter) ),
|
||||
END_RECV_TABLE()
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
C_TFBotHintEngineerNest::C_TFBotHintEngineerNest( void )
|
||||
{
|
||||
m_bHasActiveTeleporter = false;
|
||||
m_bHadActiveTeleporter = false;
|
||||
m_pMvMActiveTeleporter = NULL;
|
||||
}
|
||||
|
||||
|
||||
C_TFBotHintEngineerNest::~C_TFBotHintEngineerNest()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
|
||||
void C_TFBotHintEngineerNest::UpdateOnRemove()
|
||||
{
|
||||
StopEffect();
|
||||
BaseClass::UpdateOnRemove();
|
||||
}
|
||||
|
||||
|
||||
void C_TFBotHintEngineerNest::OnPreDataChanged( DataUpdateType_t type )
|
||||
{
|
||||
BaseClass::OnPreDataChanged( type );
|
||||
|
||||
m_bHadActiveTeleporter = m_bHasActiveTeleporter;
|
||||
}
|
||||
|
||||
|
||||
void C_TFBotHintEngineerNest::OnDataChanged( DataUpdateType_t type )
|
||||
{
|
||||
BaseClass::OnDataChanged( type );
|
||||
|
||||
if ( m_bHadActiveTeleporter != m_bHasActiveTeleporter )
|
||||
{
|
||||
if ( m_bHasActiveTeleporter )
|
||||
{
|
||||
StartEffect();
|
||||
}
|
||||
else
|
||||
{
|
||||
StopEffect();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void C_TFBotHintEngineerNest::StartEffect()
|
||||
{
|
||||
if ( !m_pMvMActiveTeleporter )
|
||||
{
|
||||
m_pMvMActiveTeleporter = ParticleProp()->Create( "teleporter_mvm_bot_persist", PATTACH_ABSORIGIN );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void C_TFBotHintEngineerNest::StopEffect()
|
||||
{
|
||||
if ( m_pMvMActiveTeleporter )
|
||||
{
|
||||
ParticleProp()->StopEmission( m_pMvMActiveTeleporter );
|
||||
m_pMvMActiveTeleporter = NULL;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
//
|
||||
//
|
||||
//=============================================================================
|
||||
#ifndef TF_BOT_HINT_ENGINEER_NEST_H
|
||||
#define TF_BOT_HINT_ENGINEER_NEST_H
|
||||
|
||||
#include "c_baseentity.h"
|
||||
|
||||
class C_TFBotHintEngineerNest : public C_BaseEntity
|
||||
{
|
||||
DECLARE_CLASS( C_TFBotHintEngineerNest, C_BaseEntity );
|
||||
public:
|
||||
DECLARE_CLIENTCLASS();
|
||||
|
||||
C_TFBotHintEngineerNest( void );
|
||||
virtual ~C_TFBotHintEngineerNest();
|
||||
|
||||
virtual void UpdateOnRemove() OVERRIDE;
|
||||
virtual void OnPreDataChanged( DataUpdateType_t type ) OVERRIDE;
|
||||
virtual void OnDataChanged( DataUpdateType_t type ) OVERRIDE;
|
||||
private:
|
||||
bool m_bHadActiveTeleporter;
|
||||
CNetworkVar( bool, m_bHasActiveTeleporter );
|
||||
|
||||
void StartEffect();
|
||||
void StopEffect();
|
||||
CNewParticleEffect *m_pMvMActiveTeleporter;
|
||||
};
|
||||
|
||||
#endif // TF_BOT_HINT_ENGINEER_NEST_H
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,311 @@
|
||||
//========= 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 "particlemgr.h"
|
||||
#include "particle_prototype.h"
|
||||
#include "particle_util.h"
|
||||
#include "c_basecombatcharacter.h"
|
||||
#include "ihasbuildpoints.h"
|
||||
#include <vgui/ILocalize.h>
|
||||
|
||||
class C_TFPlayer;
|
||||
|
||||
// Max Length of ID Strings
|
||||
#define MAX_ID_STRING 256
|
||||
|
||||
extern mstudioevent_t *GetEventIndexForSequence( mstudioseqdesc_t &seqdesc );
|
||||
|
||||
DECLARE_AUTO_LIST( IBaseObjectAutoList );
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
class C_BaseObject : public C_BaseCombatCharacter, public IHasBuildPoints, public ITargetIDProvidesHint, public IBaseObjectAutoList
|
||||
{
|
||||
DECLARE_CLASS( C_BaseObject, C_BaseCombatCharacter );
|
||||
public:
|
||||
DECLARE_CLIENTCLASS();
|
||||
|
||||
C_BaseObject();
|
||||
~C_BaseObject( void );
|
||||
|
||||
virtual void Spawn( void );
|
||||
|
||||
virtual bool IsBaseObject( void ) const { return true; }
|
||||
virtual bool IsAnUpgrade(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 ResetClientsideFrame( void );
|
||||
|
||||
virtual void PreDataUpdate( DataUpdateType_t updateType );
|
||||
virtual void OnDataChanged( DataUpdateType_t updateType );
|
||||
|
||||
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 const char *GetTargetDescription( void ) const;
|
||||
virtual const char *GetIDString( void );
|
||||
virtual bool IsValidIDTarget( void );
|
||||
|
||||
virtual void GetTargetIDString( OUT_Z_BYTECAP(iMaxLenInBytes) wchar_t *sIDString, int iMaxLenInBytes, bool bSpectator );
|
||||
virtual void GetTargetIDDataString( OUT_Z_BYTECAP(iMaxLenInBytes) wchar_t *sDataString, int iMaxLenInBytes );
|
||||
|
||||
virtual bool ShouldBeActive( void );
|
||||
virtual void OnGoActive( void );
|
||||
virtual void OnGoInactive( void );
|
||||
|
||||
virtual void UpdateOnRemove( void );
|
||||
|
||||
C_TFPlayer *GetBuilder( void ) { return m_hBuilder; }
|
||||
|
||||
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;
|
||||
|
||||
virtual void RecalculateIDString( void );
|
||||
|
||||
int GetType() const { return m_iObjectType; }
|
||||
bool IsOwnedByLocalPlayer() const;
|
||||
C_TFPlayer *GetOwner();
|
||||
|
||||
virtual void Simulate();
|
||||
|
||||
virtual int DrawModel( int flags );
|
||||
|
||||
float GetPercentageConstructed( void ) { return m_flPercentageConstructed; }
|
||||
|
||||
bool IsPlacing( void ) const { return m_bPlacing; }
|
||||
bool IsBuilding( void ) const { return m_bBuilding; }
|
||||
virtual bool IsUpgrading( void ) const { return false; }
|
||||
bool IsCarried( void ) const { return m_bCarried; }
|
||||
|
||||
float GetReversesBuildingConstructionSpeed( void );
|
||||
|
||||
virtual void FinishedBuilding( void ) { return; }
|
||||
|
||||
virtual const char* GetStatusName() const;
|
||||
|
||||
// Object Previews
|
||||
void HighlightBuildPoints( int flags );
|
||||
|
||||
bool HasSapper( void );
|
||||
|
||||
bool IsPlasmaDisabled( void );
|
||||
|
||||
virtual void OnStartDisabled( void );
|
||||
virtual void OnEndDisabled( void );
|
||||
|
||||
virtual bool ShouldCollide( int collisionGroup, int contentsMask ) const;
|
||||
virtual bool ShouldPlayersAvoid( void );
|
||||
|
||||
bool MustBeBuiltOnAttachmentPoint( void ) const;
|
||||
|
||||
virtual bool IsHostileUpgrade( void ) { return false; }
|
||||
|
||||
// For ordering in hud building status
|
||||
virtual int GetDisplayPriority( void );
|
||||
|
||||
virtual const char *GetHudStatusIcon( void );
|
||||
|
||||
virtual BuildingHudAlert_t GetBuildingAlertLevel( void );
|
||||
|
||||
// Upgrading
|
||||
virtual int GetUpgradeLevel( void ) { return m_iUpgradeLevel; }
|
||||
int GetUpgradeMetal( void ) { return m_iUpgradeMetal; }
|
||||
virtual int GetUpgradeMetalRequired( void ) { return m_iUpgradeMetalRequired; }
|
||||
virtual void UpgradeLevelChanged() { return; }
|
||||
int GetHighestUpgradeLevel( void ) { return m_iHighestUpgradeLevel; }
|
||||
|
||||
int GetObjectMode( void ) const { return m_iObjectMode; }
|
||||
|
||||
// Shadows
|
||||
virtual ShadowType_t ShadowCastType( void ) OVERRIDE;
|
||||
|
||||
// Stealth
|
||||
virtual float GetInvisibilityLevel( void );
|
||||
virtual void SetInvisibilityLevel( float flValue );
|
||||
bool IsEnteringOrExitingFullyInvisible( float flValue ) { return ( ( m_flInvisibilityPercent != 1.f && flValue == 1.f ) || ( m_flInvisibilityPercent == 1.f && flValue != 1.f ) ); }
|
||||
|
||||
private:
|
||||
void StopAnimGeneratedSounds( void );
|
||||
|
||||
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.IsValid(); }
|
||||
void AttachObjectToObject( CBaseEntity *pEntity, int iPoint, Vector &vecOrigin );
|
||||
CBaseObject *GetParentObject( void );
|
||||
CBaseEntity *GetParentEntity( void );
|
||||
void SetBuildPointPassenger( int iPoint, int iPassenger );
|
||||
|
||||
// Build points
|
||||
CUtlVector<BuildPoint_t> m_BuildPoints;
|
||||
|
||||
bool IsDisabled( void ) { return m_bDisabled || m_bCarried; }
|
||||
|
||||
// Shared placement
|
||||
bool VerifyCorner( const Vector &vBottomCenter, float xOffset, float yOffset );
|
||||
virtual bool IsPlacementPosValid( void );
|
||||
virtual float GetNearbyObjectCheckRadius( void ) { return 30.0; }
|
||||
|
||||
virtual void OnPlacementStateChanged( bool bValidPlacement );
|
||||
|
||||
bool ServerValidPlacement( void ); // allow server to trump our placement state
|
||||
|
||||
bool WasLastPlacementPosValid( void ); // query if we're in a valid place, when we last tried to calculate it
|
||||
|
||||
// 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 CBaseObject *GetObjectOfTypeOnMe( int iObjectType );
|
||||
virtual void RemoveAllObjects( void );
|
||||
virtual int FindObjectOnBuildPoint( CBaseObject *pObject );
|
||||
|
||||
virtual bool TestHitboxes( const Ray_t &ray, unsigned int fContentsMask, trace_t& tr );
|
||||
|
||||
bool IsMiniBuilding() { return m_bMiniBuilding; }
|
||||
bool IsDisposableBuilding( void ) const { return m_bDisposableBuilding; }
|
||||
|
||||
// ITargetIDProvidesHint
|
||||
public:
|
||||
virtual void DisplayHintTo( C_BasePlayer *pPlayer );
|
||||
|
||||
virtual void GetGlowEffectColor( float *r, float *g, float *b );
|
||||
|
||||
bool IsMapPlaced( void ){ return m_bWasMapPlaced; }
|
||||
|
||||
protected:
|
||||
virtual void UpdateDamageEffects( BuildingDamageLevel_t damageLevel ) {} // default is no effects
|
||||
|
||||
void UpdateDesiredBuildRotation( float flFrameTime );
|
||||
|
||||
bool CalculatePlacementPos( void );
|
||||
|
||||
protected:
|
||||
|
||||
BuildingDamageLevel_t CalculateDamageLevel( void );
|
||||
|
||||
char m_szIDString[ MAX_ID_STRING ];
|
||||
|
||||
BuildingDamageLevel_t m_damageLevel;
|
||||
|
||||
Vector m_vecBuildOrigin;
|
||||
Vector m_vecBuildCenterOfMass;
|
||||
|
||||
// Upgrading
|
||||
int m_iUpgradeLevel;
|
||||
int m_iOldUpgradeLevel;
|
||||
int m_iUpgradeMetal;
|
||||
int m_iHighestUpgradeLevel;
|
||||
int m_iUpgradeMetalRequired;
|
||||
|
||||
HPARTICLEFFECT m_hDamageEffects;
|
||||
|
||||
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_TFPlayer > m_hOldOwner;
|
||||
CHandle< C_TFPlayer > 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_bWasPlacing;
|
||||
bool m_bPlacing;
|
||||
bool m_bDisabled;
|
||||
bool m_bOldDisabled;
|
||||
bool m_bCarried;
|
||||
bool m_bCarryDeploy;
|
||||
bool m_bOldCarryDeploy;
|
||||
bool m_bMiniBuilding;
|
||||
bool m_bDisposableBuilding;
|
||||
float m_flPercentageConstructed;
|
||||
EHANDLE m_hBuiltOnEntity;
|
||||
int m_iObjectMode;
|
||||
bool m_bPlasmaDisable;
|
||||
|
||||
CNetworkVector( m_vecBuildMaxs );
|
||||
CNetworkVector( m_vecBuildMins );
|
||||
|
||||
CNetworkVar( int, m_iDesiredBuildRotations );
|
||||
float m_flCurrentBuildRotation;
|
||||
|
||||
int m_iLastPlacementPosValid; // -1 - init, 0 - invalid, 1 - valid
|
||||
|
||||
CNetworkVar( bool, m_bServerOverridePlacement );
|
||||
|
||||
int m_nObjectOldSequence;
|
||||
|
||||
// used when calculating the placement position
|
||||
Vector m_vecBuildForward;
|
||||
float m_flBuildDistance;
|
||||
|
||||
// Stealth
|
||||
float m_flInvisibilityPercent;
|
||||
float m_flPrevInvisibilityPercent;
|
||||
|
||||
CNetworkVar( bool, m_bWasMapPlaced );
|
||||
|
||||
private:
|
||||
C_BaseObject( const C_BaseObject & ); // not defined, not accessible
|
||||
};
|
||||
|
||||
#endif // C_BASEOBJECT_H
|
||||
@@ -0,0 +1,170 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose: Dove entity for the Meet the Medic tease.
|
||||
//
|
||||
//=============================================================================//
|
||||
|
||||
#include "cbase.h"
|
||||
#include "tf_gamerules.h"
|
||||
#include "c_baseanimating.h"
|
||||
|
||||
#define ENTITY_FLYING_BIRD_MODEL "models/props_forest/dove.mdl"
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
class C_EntityFlyingBird : public CBaseAnimating
|
||||
{
|
||||
DECLARE_CLASS( C_EntityFlyingBird, CBaseAnimating );
|
||||
public:
|
||||
void InitFromServerData( float flyAngle, float flyAngleRate, float flAccelZ, float flSpeed, float flGlideTime );
|
||||
virtual void Touch( CBaseEntity *pOther );
|
||||
|
||||
private:
|
||||
virtual void ClientThink( void );
|
||||
void UpdateFlyDirection( void );
|
||||
|
||||
private:
|
||||
Vector m_flyForward;
|
||||
float m_flyAngle;
|
||||
float m_flyAngleRate;
|
||||
float m_flyZ;
|
||||
float m_accelZ;
|
||||
float m_speed;
|
||||
float m_timestamp;
|
||||
|
||||
CountdownTimer m_lifetimeTimer;
|
||||
CountdownTimer m_glideTimer;
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Server message that tells us to create a dove
|
||||
//-----------------------------------------------------------------------------
|
||||
void __MsgFunc_SpawnFlyingBird( bf_read &msg )
|
||||
{
|
||||
Vector vecPos;
|
||||
msg.ReadBitVec3Coord( vecPos );
|
||||
float flyAngle = msg.ReadFloat();
|
||||
float flyAngleRate = msg.ReadFloat();
|
||||
float flAccelZ = msg.ReadFloat();
|
||||
float flSpeed = msg.ReadFloat();
|
||||
float flGlideTime = msg.ReadFloat();
|
||||
|
||||
C_EntityFlyingBird *pBird = new C_EntityFlyingBird();
|
||||
if ( !pBird )
|
||||
return;
|
||||
|
||||
pBird->SetAbsOrigin( vecPos );
|
||||
pBird->InitFromServerData( flyAngle, flyAngleRate, flAccelZ, flSpeed, flGlideTime );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void C_EntityFlyingBird::UpdateFlyDirection( void )
|
||||
{
|
||||
Vector forward;
|
||||
|
||||
forward.x = cos( m_flyAngle );
|
||||
forward.y = sin( m_flyAngle );
|
||||
forward.z = m_flyZ;
|
||||
forward.NormalizeInPlace();
|
||||
|
||||
SetAbsVelocity( forward * m_speed );
|
||||
|
||||
QAngle angles;
|
||||
VectorAngles( forward, angles );
|
||||
|
||||
SetAbsAngles( angles );
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void C_EntityFlyingBird::InitFromServerData( float flyAngle, float flyAngleRate, float flAccelZ, float flSpeed, float flGlideTime )
|
||||
{
|
||||
if ( InitializeAsClientEntity( ENTITY_FLYING_BIRD_MODEL, RENDER_GROUP_OPAQUE_ENTITY ) == false )
|
||||
{
|
||||
Release();
|
||||
return;
|
||||
}
|
||||
|
||||
SetMoveType( MOVETYPE_FLY );
|
||||
SetSolid( SOLID_BBOX );
|
||||
SetCollisionGroup( COLLISION_GROUP_DEBRIS );
|
||||
SetSize( -Vector(8,8,0), Vector(8,8,16) );
|
||||
|
||||
m_flyAngle = flyAngle;
|
||||
m_flyAngleRate = flyAngleRate;
|
||||
m_accelZ = flAccelZ;
|
||||
m_flyZ = 0.0;
|
||||
m_speed = flSpeed;
|
||||
|
||||
UpdateFlyDirection();
|
||||
|
||||
SetSequence( 0 );
|
||||
SetPlaybackRate( 1.0f );
|
||||
SetCycle( 0 );
|
||||
ResetSequenceInfo();
|
||||
|
||||
// make sure the bird is removed
|
||||
m_lifetimeTimer.Start( 10.0f );
|
||||
|
||||
m_glideTimer.Start( flGlideTime );
|
||||
|
||||
SetNextClientThink( CLIENT_THINK_ALWAYS );
|
||||
m_timestamp = gpGlobals->curtime;
|
||||
|
||||
SetModelScale( 0.1f );
|
||||
SetModelScale( 1.0f, 0.5f );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Fly away!
|
||||
//-----------------------------------------------------------------------------
|
||||
void C_EntityFlyingBird::ClientThink( void )
|
||||
{
|
||||
if ( m_lifetimeTimer.IsElapsed() )
|
||||
{
|
||||
Release();
|
||||
return;
|
||||
}
|
||||
|
||||
if ( m_glideTimer.HasStarted() && m_glideTimer.IsElapsed() )
|
||||
{
|
||||
SetSequence( 1 );
|
||||
SetPlaybackRate( 1.0f );
|
||||
SetCycle( 0 );
|
||||
ResetSequenceInfo();
|
||||
m_glideTimer.Invalidate();
|
||||
}
|
||||
|
||||
StudioFrameAdvance();
|
||||
|
||||
PhysicsSimulate();
|
||||
|
||||
const float deltaT = gpGlobals->curtime - m_timestamp;
|
||||
m_flyAngle += m_flyAngleRate * deltaT;
|
||||
m_flyZ += m_accelZ * deltaT;
|
||||
|
||||
UpdateFlyDirection();
|
||||
|
||||
m_timestamp = gpGlobals->curtime;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void C_EntityFlyingBird::Touch( CBaseEntity *pOther )
|
||||
{
|
||||
if ( !pOther || !pOther->IsWorld() )
|
||||
return;
|
||||
|
||||
BaseClass::Touch( pOther );
|
||||
|
||||
// Die at next think. Not safe to remove ourselves during physics touch.
|
||||
m_lifetimeTimer.Invalidate();
|
||||
}
|
||||
|
||||
@@ -0,0 +1,93 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
#include "cbase.h"
|
||||
|
||||
#include "c_entity_currencypack.h"
|
||||
#include "c_tf_player.h"
|
||||
|
||||
IMPLEMENT_CLIENTCLASS_DT( C_CurrencyPack, DT_CurrencyPack, CCurrencyPack )
|
||||
RecvPropBool( RECVINFO( m_bDistributed ) ),
|
||||
END_RECV_TABLE()
|
||||
|
||||
C_CurrencyPack::C_CurrencyPack()
|
||||
{
|
||||
m_bDistributed = false;
|
||||
|
||||
m_pGlowEffect = NULL;
|
||||
m_bShouldGlowForLocalPlayer = false;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
C_CurrencyPack::~C_CurrencyPack()
|
||||
{
|
||||
DestroyGlowEffect();
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void C_CurrencyPack::OnDataChanged( DataUpdateType_t updateType )
|
||||
{
|
||||
BaseClass::OnDataChanged( updateType );
|
||||
|
||||
if ( updateType == DATA_UPDATE_CREATED )
|
||||
{
|
||||
SetNextClientThink( CLIENT_THINK_ALWAYS );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void C_CurrencyPack::ClientThink()
|
||||
{
|
||||
#ifdef STAGING_ONLY
|
||||
int iSeeCashThroughWall = 0;
|
||||
C_TFPlayer *pTFPlayer = C_TFPlayer::GetLocalTFPlayer();
|
||||
if ( pTFPlayer && pTFPlayer->IsAlive() )
|
||||
{
|
||||
CALL_ATTRIB_HOOK_INT_ON_OTHER( pTFPlayer, iSeeCashThroughWall, mvm_see_cash_through_wall );
|
||||
}
|
||||
|
||||
bool bShouldGlowForLocalPlayer = iSeeCashThroughWall != 0;
|
||||
if ( m_bShouldGlowForLocalPlayer != bShouldGlowForLocalPlayer )
|
||||
{
|
||||
m_bShouldGlowForLocalPlayer = bShouldGlowForLocalPlayer;
|
||||
UpdateGlowEffect();
|
||||
}
|
||||
#endif // STAGING_ONLY
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void C_CurrencyPack::UpdateGlowEffect( void )
|
||||
{
|
||||
// destroy the existing effect
|
||||
if ( m_pGlowEffect )
|
||||
{
|
||||
DestroyGlowEffect();
|
||||
}
|
||||
|
||||
// create a new effect if we have a cart
|
||||
if ( m_bShouldGlowForLocalPlayer )
|
||||
{
|
||||
Vector color = m_bDistributed ? Vector( 150, 0, 0 ) : Vector( 0, 150, 0 );
|
||||
m_pGlowEffect = new CGlowObject( this, color, 1.0, true );
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void C_CurrencyPack::DestroyGlowEffect( void )
|
||||
{
|
||||
if ( m_pGlowEffect )
|
||||
{
|
||||
delete m_pGlowEffect;
|
||||
m_pGlowEffect = NULL;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
#ifndef C_ENTITY_CURRENCYPACK_H
|
||||
#define C_ENTITY_CURRENCYPACK_H
|
||||
|
||||
class C_CurrencyPack : public C_BaseAnimating
|
||||
{
|
||||
public:
|
||||
DECLARE_CLASS( C_CurrencyPack, C_BaseAnimating );
|
||||
DECLARE_CLIENTCLASS();
|
||||
|
||||
C_CurrencyPack();
|
||||
~C_CurrencyPack();
|
||||
|
||||
virtual void OnDataChanged( DataUpdateType_t updateType ) OVERRIDE;
|
||||
virtual void ClientThink();
|
||||
|
||||
private:
|
||||
|
||||
void UpdateGlowEffect( void );
|
||||
void DestroyGlowEffect( void );
|
||||
CGlowObject *m_pGlowEffect;
|
||||
bool m_bShouldGlowForLocalPlayer;
|
||||
|
||||
bool m_bDistributed;
|
||||
};
|
||||
|
||||
#endif // C_ENTITY_CURRENCYPACK_H
|
||||
@@ -0,0 +1,18 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================
|
||||
#include "cbase.h"
|
||||
#include "tf_shareddefs.h"
|
||||
#include "c_func_capture_zone.h"
|
||||
|
||||
// memdbgon must be the last include file in a .cpp file!!!
|
||||
#include "tier0/memdbgon.h"
|
||||
|
||||
IMPLEMENT_CLIENTCLASS_DT( C_CaptureZone, DT_CaptureZone, CCaptureZone )
|
||||
RecvPropInt( RECVINFO( m_bDisabled ) ),
|
||||
END_RECV_TABLE()
|
||||
|
||||
IMPLEMENT_AUTO_LIST( ICaptureZoneAutoList );
|
||||
@@ -0,0 +1,33 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
#ifndef C_FUNC_CAPTURE_ZONE_H
|
||||
#define C_FUNC_CAPTURE_ZONE_H
|
||||
#ifdef _WIN32
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
class C_CaptureZone;
|
||||
|
||||
DECLARE_AUTO_LIST( ICaptureZoneAutoList );
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
class C_CaptureZone : public C_BaseEntity, public ICaptureZoneAutoList
|
||||
{
|
||||
DECLARE_CLASS( C_CaptureZone, C_BaseEntity );
|
||||
|
||||
public:
|
||||
DECLARE_CLIENTCLASS();
|
||||
|
||||
bool IsDisabled( void ){ return m_bDisabled; }
|
||||
|
||||
private:
|
||||
bool m_bDisabled;
|
||||
};
|
||||
|
||||
#endif // C_FUNC_CAPTURE_ZONE_H
|
||||
@@ -0,0 +1,73 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================
|
||||
#include "cbase.h"
|
||||
#include "tf_shareddefs.h"
|
||||
#include "tf_gamerules.h"
|
||||
|
||||
// memdbgon must be the last include file in a .cpp file!!!
|
||||
#include "tier0/memdbgon.h"
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
class C_FuncForceField : public C_BaseEntity
|
||||
{
|
||||
DECLARE_CLASS( C_FuncForceField, C_BaseEntity );
|
||||
public:
|
||||
DECLARE_CLIENTCLASS();
|
||||
|
||||
virtual int DrawModel( int flags ) OVERRIDE;
|
||||
virtual bool ShouldCollide( int collisionGroup, int contentsMask ) const OVERRIDE;
|
||||
};
|
||||
|
||||
IMPLEMENT_CLIENTCLASS_DT( C_FuncForceField, DT_FuncForceField, CFuncForceField )
|
||||
END_RECV_TABLE()
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
int C_FuncForceField::DrawModel( int flags )
|
||||
{
|
||||
// Don't draw for anyone during a team win
|
||||
if ( TFGameRules()->State_Get() == GR_STATE_TEAM_WIN )
|
||||
return 1;
|
||||
|
||||
return BaseClass::DrawModel( flags );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Enemy players collide with us, except during a team win
|
||||
//-----------------------------------------------------------------------------
|
||||
bool C_FuncForceField::ShouldCollide( int collisionGroup, int contentsMask ) const
|
||||
{
|
||||
// Force fields are off during a team win
|
||||
if ( TFGameRules()->State_Get() == GR_STATE_TEAM_WIN )
|
||||
return false;
|
||||
|
||||
if ( GetTeamNumber() == TEAM_UNASSIGNED )
|
||||
return false;
|
||||
|
||||
if ( collisionGroup == COLLISION_GROUP_PLAYER_MOVEMENT )
|
||||
{
|
||||
switch ( GetTeamNumber() )
|
||||
{
|
||||
case TF_TEAM_BLUE:
|
||||
if ( !( contentsMask & CONTENTS_BLUETEAM ) )
|
||||
return false;
|
||||
break;
|
||||
|
||||
case TF_TEAM_RED:
|
||||
if ( !( contentsMask & CONTENTS_REDTEAM ) )
|
||||
return false;
|
||||
break;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================//
|
||||
|
||||
// func_passtime_goal - based on func_capture_zone
|
||||
#include "cbase.h"
|
||||
#include "c_func_passtime_goal.h"
|
||||
|
||||
// memdbgon must be the last include file in a .cpp file!!!
|
||||
#include "tier0/memdbgon.h"
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
IMPLEMENT_CLIENTCLASS_DT( C_FuncPasstimeGoal, DT_FuncPasstimeGoal, CFuncPasstimeGoal )
|
||||
RecvPropBool( RECVINFO( m_bTriggerDisabled ) ),
|
||||
RecvPropInt( RECVINFO( m_iGoalType ) ),
|
||||
END_RECV_TABLE()
|
||||
@@ -0,0 +1,39 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================//
|
||||
|
||||
// func_passtime_goal - based on func_capture_zone
|
||||
#ifndef C_FUNC_PASSTIME_GOAL_H
|
||||
#define C_FUNC_PASSTIME_GOAL_H
|
||||
#ifdef _WIN32
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include "util_shared.h"
|
||||
#include "c_baseentity.h"
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
class C_FuncPasstimeGoal : public C_BaseEntity, public TAutoList<C_FuncPasstimeGoal>
|
||||
{
|
||||
public:
|
||||
DECLARE_CLASS( C_FuncPasstimeGoal, C_BaseEntity );
|
||||
DECLARE_CLIENTCLASS();
|
||||
bool BGoalTriggerDisabled() const { return m_bTriggerDisabled; }
|
||||
int GetGoalType() const { return m_iGoalType; }
|
||||
|
||||
enum GoalType
|
||||
{
|
||||
TYPE_HOOP,
|
||||
TYPE_ENDZONE,
|
||||
TYPE_TOWER,
|
||||
};
|
||||
|
||||
private:
|
||||
CNetworkVar( bool, m_bTriggerDisabled );
|
||||
CNetworkVar( int, m_iGoalType );
|
||||
};
|
||||
|
||||
#endif // C_FUNC_PASSTIME_GOAL_H
|
||||
@@ -0,0 +1,97 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================
|
||||
#include "cbase.h"
|
||||
#include "tf_shareddefs.h"
|
||||
#include "tf_gamerules.h"
|
||||
|
||||
// memdbgon must be the last include file in a .cpp file!!!
|
||||
#include "tier0/memdbgon.h"
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
class C_FuncRespawnRoom : public C_BaseEntity
|
||||
{
|
||||
DECLARE_CLASS( C_FuncRespawnRoom, C_BaseEntity );
|
||||
public:
|
||||
DECLARE_CLIENTCLASS();
|
||||
};
|
||||
|
||||
IMPLEMENT_CLIENTCLASS_DT( C_FuncRespawnRoom, DT_FuncRespawnRoom, CFuncRespawnRoom )
|
||||
END_RECV_TABLE()
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
class C_FuncRespawnRoomVisualizer : public C_BaseEntity
|
||||
{
|
||||
DECLARE_CLASS( C_FuncRespawnRoomVisualizer, C_BaseEntity );
|
||||
public:
|
||||
DECLARE_CLIENTCLASS();
|
||||
|
||||
virtual int DrawModel( int flags );
|
||||
|
||||
virtual bool ShouldCollide( int collisionGroup, int contentsMask ) const;
|
||||
};
|
||||
|
||||
IMPLEMENT_CLIENTCLASS_DT( C_FuncRespawnRoomVisualizer, DT_FuncRespawnRoomVisualizer, CFuncRespawnRoomVisualizer )
|
||||
END_RECV_TABLE()
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Don't draw for friendly players
|
||||
//-----------------------------------------------------------------------------
|
||||
int C_FuncRespawnRoomVisualizer::DrawModel( int flags )
|
||||
{
|
||||
// Don't draw for anyone in endround
|
||||
if ( TFGameRules()->State_Get() == GR_STATE_TEAM_WIN )
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Don't draw for teammates of the visualizer
|
||||
C_BasePlayer *pLocalPlayer = C_BasePlayer::GetLocalPlayer();
|
||||
if ( pLocalPlayer && pLocalPlayer->GetTeamNumber() == GetTeamNumber() )
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
return BaseClass::DrawModel( flags );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Enemy players collide with us, except in endround
|
||||
//-----------------------------------------------------------------------------
|
||||
bool C_FuncRespawnRoomVisualizer::ShouldCollide( int collisionGroup, int contentsMask ) const
|
||||
{
|
||||
// Respawn rooms are open in win state
|
||||
if ( TFGameRules()->State_Get() == GR_STATE_TEAM_WIN )
|
||||
return false;
|
||||
|
||||
if ( GetTeamNumber() == TEAM_UNASSIGNED )
|
||||
return false;
|
||||
|
||||
if ( collisionGroup == COLLISION_GROUP_PLAYER_MOVEMENT )
|
||||
{
|
||||
switch( GetTeamNumber() )
|
||||
{
|
||||
case TF_TEAM_BLUE:
|
||||
if ( !(contentsMask & CONTENTS_BLUETEAM) )
|
||||
return false;
|
||||
break;
|
||||
|
||||
case TF_TEAM_RED:
|
||||
if ( !(contentsMask & CONTENTS_REDTEAM) )
|
||||
return false;
|
||||
break;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
@@ -0,0 +1,82 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
#include "cbase.h"
|
||||
#include "c_monster_resource.h"
|
||||
#include "tf_hud_boss_health.h"
|
||||
|
||||
|
||||
// memdbgon must be the last include file in a .cpp file!!!
|
||||
#include "tier0/memdbgon.h"
|
||||
|
||||
|
||||
void RecvProxy_UpdateBossHud( const CRecvProxyData *pData, void *pStruct, void *pOut );
|
||||
|
||||
|
||||
IMPLEMENT_CLIENTCLASS_DT_NOBASE( C_MonsterResource, DT_MonsterResource, CMonsterResource )
|
||||
|
||||
RecvPropInt( RECVINFO( m_iBossHealthPercentageByte ), 0, RecvProxy_UpdateBossHud ),
|
||||
RecvPropInt( RECVINFO( m_iBossStunPercentageByte ), 0, RecvProxy_UpdateBossHud ),
|
||||
|
||||
RecvPropInt( RECVINFO( m_iSkillShotCompleteCount ) ),
|
||||
RecvPropTime( RECVINFO( m_fSkillShotComboEndTime ) ),
|
||||
|
||||
RecvPropInt( RECVINFO( m_iBossState ), 0, RecvProxy_UpdateBossHud ),
|
||||
|
||||
END_RECV_TABLE()
|
||||
|
||||
C_MonsterResource *g_pMonsterResource = NULL;
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Update the HUD meter when the Boss' data changes
|
||||
void RecvProxy_UpdateBossHud( const CRecvProxyData *pData, void *pStruct, void *pOut )
|
||||
{
|
||||
int *out = (int *)pOut;
|
||||
|
||||
*out = pData->m_Value.m_Int;
|
||||
|
||||
CHudBossHealthMeter *meter = GET_HUDELEMENT( CHudBossHealthMeter );
|
||||
if ( meter )
|
||||
{
|
||||
meter->Update();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
C_MonsterResource::C_MonsterResource()
|
||||
{
|
||||
m_iBossHealthPercentageByte = 0;
|
||||
m_iBossStunPercentageByte = 0;
|
||||
|
||||
m_iSkillShotCompleteCount = 0;
|
||||
m_fSkillShotComboEndTime = 0;
|
||||
|
||||
m_iBossState = 0;
|
||||
|
||||
// do this here because entity is created via network messages from the server entity's creation
|
||||
Assert( g_pMonsterResource == NULL );
|
||||
g_pMonsterResource = this;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
C_MonsterResource::~C_MonsterResource()
|
||||
{
|
||||
Assert( g_pMonsterResource == this );
|
||||
g_pMonsterResource = NULL;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
float C_MonsterResource::GetBossHealthPercentage( void )
|
||||
{
|
||||
return (float)m_iBossHealthPercentageByte / 255.0f;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
float C_MonsterResource::GetBossStunPercentage( void )
|
||||
{
|
||||
return (float)m_iBossStunPercentageByte / 255.0f;
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
#ifndef C_MONSTER_RESOURCE
|
||||
#define C_MONSTER_RESOURCE
|
||||
#ifdef _WIN32
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
|
||||
class C_MonsterResource : public C_BaseEntity
|
||||
{
|
||||
DECLARE_CLASS( C_MonsterResource, C_BaseEntity );
|
||||
public:
|
||||
DECLARE_CLIENTCLASS();
|
||||
|
||||
C_MonsterResource();
|
||||
virtual ~C_MonsterResource();
|
||||
|
||||
float GetBossHealthPercentage( void );
|
||||
float GetBossStunPercentage( void );
|
||||
|
||||
int GetSkillShotCompleteCount( void ){ return m_iSkillShotCompleteCount; }
|
||||
float GetSkillShotComboEndTime( void ){ return m_fSkillShotComboEndTime; }
|
||||
|
||||
int GetBossState() const { return m_iBossState; }
|
||||
|
||||
private:
|
||||
int m_iBossHealthPercentageByte;
|
||||
int m_iBossStunPercentageByte;
|
||||
|
||||
int m_iSkillShotCompleteCount; // the number of consecutive skill shots that have been completed. 0 = don't show combo HUD
|
||||
float m_fSkillShotComboEndTime; // the time when the current skill shot combo window closes
|
||||
|
||||
int m_iBossState;
|
||||
};
|
||||
|
||||
extern C_MonsterResource *g_pMonsterResource;
|
||||
|
||||
|
||||
#endif // C_MONSTER_RESOURCE
|
||||
@@ -0,0 +1,393 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose: Client's CObjectSentrygun
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================//
|
||||
#include "cbase.h"
|
||||
#include "c_baseobject.h"
|
||||
#include "c_tf_player.h"
|
||||
#include "vgui/ILocalize.h"
|
||||
#include "c_obj_dispenser.h"
|
||||
|
||||
// NVNT haptics system interface
|
||||
#include "c_tf_haptics.h"
|
||||
|
||||
// memdbgon must be the last include file in a .cpp file!!!
|
||||
#include "tier0/memdbgon.h"
|
||||
|
||||
using namespace vgui;
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: RecvProxy that converts the Team's player UtlVector to entindexes
|
||||
//-----------------------------------------------------------------------------
|
||||
void RecvProxy_HealingList( const CRecvProxyData *pData, void *pStruct, void *pOut )
|
||||
{
|
||||
C_ObjectDispenser *pDispenser = (C_ObjectDispenser*)pStruct;
|
||||
|
||||
CBaseHandle *pHandle = (CBaseHandle*)(&(pDispenser->m_hHealingTargets[pData->m_iElement]));
|
||||
RecvProxy_IntToEHandle( pData, pStruct, pHandle );
|
||||
|
||||
// update the heal beams
|
||||
pDispenser->m_bUpdateHealingTargets = true;
|
||||
}
|
||||
|
||||
void RecvProxyArrayLength_HealingArray( void *pStruct, int objectID, int currentArrayLength )
|
||||
{
|
||||
C_ObjectDispenser *pDispenser = (C_ObjectDispenser*)pStruct;
|
||||
|
||||
if ( pDispenser->m_hHealingTargets.Size() != currentArrayLength )
|
||||
pDispenser->m_hHealingTargets.SetSize( currentArrayLength );
|
||||
|
||||
// update the heal beams
|
||||
pDispenser->m_bUpdateHealingTargets = true;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Dispenser object
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
IMPLEMENT_CLIENTCLASS_DT(C_ObjectDispenser, DT_ObjectDispenser, CObjectDispenser)
|
||||
RecvPropInt( RECVINFO( m_iState ) ),
|
||||
RecvPropInt( RECVINFO( m_iAmmoMetal ) ),
|
||||
RecvPropInt( RECVINFO( m_iMiniBombCounter ) ),
|
||||
|
||||
RecvPropArray2(
|
||||
RecvProxyArrayLength_HealingArray,
|
||||
RecvPropInt( "healing_array_element", 0, SIZEOF_IGNORE, 0, RecvProxy_HealingList ),
|
||||
MAX_PLAYERS,
|
||||
0,
|
||||
"healing_array"
|
||||
)
|
||||
END_RECV_TABLE()
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
C_ObjectDispenser::C_ObjectDispenser()
|
||||
{
|
||||
m_bUpdateHealingTargets = false;
|
||||
m_bPlayingSound = false;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
C_ObjectDispenser::~C_ObjectDispenser()
|
||||
{
|
||||
StopSound( "Building_Dispenser.Heal" );
|
||||
// NVNT see if local player is in the list of targets
|
||||
// temp. fix if dispener is destroyed will stop all healers.
|
||||
if(m_bPlayingSound)
|
||||
{
|
||||
if(tfHaptics.healingDispenserCount>0) {
|
||||
tfHaptics.healingDispenserCount --;
|
||||
if(tfHaptics.healingDispenserCount==0 && !tfHaptics.wasBeingHealedMedic)
|
||||
tfHaptics.isBeingHealed = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
// Input : updateType -
|
||||
//-----------------------------------------------------------------------------
|
||||
void C_ObjectDispenser::OnDataChanged( DataUpdateType_t updateType )
|
||||
{
|
||||
BaseClass::OnDataChanged( updateType );
|
||||
|
||||
#ifdef STAGING_ONLY
|
||||
if ( updateType == DATA_UPDATE_CREATED )
|
||||
{
|
||||
SetNextClientThink( CLIENT_THINK_ALWAYS );
|
||||
}
|
||||
#endif // STAGING_ONLY
|
||||
|
||||
if ( m_bUpdateHealingTargets )
|
||||
{
|
||||
UpdateEffects();
|
||||
m_bUpdateHealingTargets = false;
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void C_ObjectDispenser::ClientThink()
|
||||
{
|
||||
BaseClass::ClientThink();
|
||||
|
||||
#ifdef STAGING_ONLY
|
||||
C_TFPlayer *pTFOwner = GetOwner();
|
||||
if ( pTFOwner && pTFOwner->m_Shared.IsEnteringOrExitingFullyInvisible() )
|
||||
{
|
||||
UpdateEffects();
|
||||
}
|
||||
#endif // STAGING_ONLY
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void C_ObjectDispenser::SetInvisibilityLevel( float flValue )
|
||||
{
|
||||
if ( IsEnteringOrExitingFullyInvisible( flValue ) )
|
||||
{
|
||||
UpdateEffects();
|
||||
}
|
||||
|
||||
BaseClass::SetInvisibilityLevel( flValue );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void C_ObjectDispenser::UpdateEffects( void )
|
||||
{
|
||||
C_TFPlayer *pOwner = GetOwner();
|
||||
|
||||
if ( GetInvisibilityLevel() == 1.f || ( pOwner && pOwner->m_Shared.IsFullyInvisible() ) )
|
||||
{
|
||||
StopEffects( true );
|
||||
return;
|
||||
}
|
||||
|
||||
StopEffects();
|
||||
|
||||
// Now add any new targets
|
||||
for ( int i = 0; i < m_hHealingTargets.Count(); i++ )
|
||||
{
|
||||
C_BaseEntity *pTarget = m_hHealingTargets[i].Get();
|
||||
|
||||
// Loops through the healing targets, and make sure we have an effect for each of them
|
||||
if ( pTarget )
|
||||
{
|
||||
// don't want to show this effect for stealthed spies
|
||||
C_TFPlayer *pPlayer = dynamic_cast< C_TFPlayer * >( pTarget );
|
||||
if ( pPlayer && ( pPlayer->m_Shared.IsStealthed() || pPlayer->m_Shared.InCond( TF_COND_STEALTHED_BLINK ) ) )
|
||||
continue;
|
||||
|
||||
bool bHaveEffect = false;
|
||||
for ( int targets = 0; targets < m_hHealingTargetEffects.Count(); targets++ )
|
||||
{
|
||||
if ( m_hHealingTargetEffects[targets].pTarget == pTarget )
|
||||
{
|
||||
bHaveEffect = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if ( bHaveEffect )
|
||||
continue;
|
||||
// NVNT if the dispenser has started to heal the local player
|
||||
// notify the haptics system
|
||||
if(pTarget==C_BasePlayer::GetLocalPlayer())
|
||||
{
|
||||
tfHaptics.healingDispenserCount++;
|
||||
if(!tfHaptics.wasBeingHealedMedic) {
|
||||
tfHaptics.isBeingHealed = true;
|
||||
}
|
||||
}
|
||||
|
||||
const char *pszEffectName;
|
||||
if ( GetTeamNumber() == TF_TEAM_RED )
|
||||
{
|
||||
pszEffectName = "dispenser_heal_red";
|
||||
}
|
||||
else
|
||||
{
|
||||
pszEffectName = "dispenser_heal_blue";
|
||||
}
|
||||
|
||||
CNewParticleEffect *pEffect;
|
||||
|
||||
// if we don't have a model, attach at the origin, otherwise use attachment 'heal_origin'
|
||||
if ( FBitSet( GetObjectFlags(), OF_DOESNT_HAVE_A_MODEL ) )
|
||||
{
|
||||
// offset the origin to player's chest
|
||||
if ( FBitSet( GetObjectFlags(), OF_PLAYER_DESTRUCTION ) )
|
||||
{
|
||||
pEffect = ParticleProp()->Create( pszEffectName, PATTACH_ABSORIGIN_FOLLOW, NULL, Vector( 0, 0, 50 ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
pEffect = ParticleProp()->Create( pszEffectName, PATTACH_ABSORIGIN_FOLLOW );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
pEffect = ParticleProp()->Create( pszEffectName, PATTACH_POINT_FOLLOW, "heal_origin" );
|
||||
}
|
||||
|
||||
ParticleProp()->AddControlPoint( pEffect, 1, pTarget, PATTACH_ABSORIGIN_FOLLOW, NULL, Vector(0,0,50) );
|
||||
|
||||
int iIndex = m_hHealingTargetEffects.AddToTail();
|
||||
m_hHealingTargetEffects[iIndex].pTarget = pTarget;
|
||||
m_hHealingTargetEffects[iIndex].pEffect = pEffect;
|
||||
|
||||
// Start the sound over again every time we start a new beam
|
||||
StopSound( "Building_Dispenser.Heal" );
|
||||
|
||||
CLocalPlayerFilter filter;
|
||||
EmitSound( filter, entindex(), "Building_Dispenser.Heal" );
|
||||
|
||||
m_bPlayingSound = true;
|
||||
}
|
||||
}
|
||||
|
||||
// Stop the sound if we're not healing anyone
|
||||
if ( m_bPlayingSound && m_hHealingTargets.Count() == 0 )
|
||||
{
|
||||
m_bPlayingSound = false;
|
||||
|
||||
// stop the sound
|
||||
StopSound( "Building_Dispenser.Heal" );
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void C_ObjectDispenser::StopEffects( bool bRemoveAll /* = false */ )
|
||||
{
|
||||
// Find all the targets we've stopped healing
|
||||
bool bStillHealing[MAX_DISPENSER_HEALING_TARGETS] = { 0 };
|
||||
for ( int i = 0; i < m_hHealingTargetEffects.Count(); i++ )
|
||||
{
|
||||
bStillHealing[i] = false;
|
||||
|
||||
// Are we still healing this target?
|
||||
if ( !bRemoveAll )
|
||||
{
|
||||
for ( int target = 0; target < m_hHealingTargets.Count(); target++ )
|
||||
{
|
||||
if ( m_hHealingTargets[target] && m_hHealingTargets[target] == m_hHealingTargetEffects[i].pTarget )
|
||||
{
|
||||
bStillHealing[i] = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Now remove all the dead effects
|
||||
for ( int i = m_hHealingTargetEffects.Count()-1; i >= 0; i-- )
|
||||
{
|
||||
if ( !bStillHealing[i] )
|
||||
{
|
||||
|
||||
// NVNT if the healing target of this dispenser is the local player.
|
||||
// inform the haptics system interface we are no longer healing.
|
||||
if(m_hHealingTargetEffects[i].pTarget==C_BasePlayer::GetLocalPlayer())
|
||||
{
|
||||
if(tfHaptics.healingDispenserCount>0) {
|
||||
tfHaptics.healingDispenserCount --;
|
||||
if(tfHaptics.healingDispenserCount==0 && !tfHaptics.wasBeingHealedMedic)
|
||||
tfHaptics.isBeingHealed = false;
|
||||
}
|
||||
}
|
||||
|
||||
ParticleProp()->StopEmission( m_hHealingTargetEffects[i].pEffect );
|
||||
m_hHealingTargetEffects.Remove(i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Damage level has changed, update our effects
|
||||
//-----------------------------------------------------------------------------
|
||||
void C_ObjectDispenser::UpdateDamageEffects( BuildingDamageLevel_t damageLevel )
|
||||
{
|
||||
if ( m_hDamageEffects )
|
||||
{
|
||||
m_hDamageEffects->StopEmission( false, false );
|
||||
m_hDamageEffects = NULL;
|
||||
}
|
||||
|
||||
const char *pszEffect = "";
|
||||
|
||||
switch( damageLevel )
|
||||
{
|
||||
case BUILDING_DAMAGE_LEVEL_LIGHT:
|
||||
pszEffect = "dispenserdamage_1";
|
||||
break;
|
||||
case BUILDING_DAMAGE_LEVEL_MEDIUM:
|
||||
pszEffect = "dispenserdamage_2";
|
||||
break;
|
||||
case BUILDING_DAMAGE_LEVEL_HEAVY:
|
||||
pszEffect = "dispenserdamage_3";
|
||||
break;
|
||||
case BUILDING_DAMAGE_LEVEL_CRITICAL:
|
||||
pszEffect = "dispenserdamage_4";
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if ( Q_strlen(pszEffect) > 0 )
|
||||
{
|
||||
m_hDamageEffects = ParticleProp()->Create( pszEffect, PATTACH_ABSORIGIN );
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
int C_ObjectDispenser::GetMaxMetal( void )
|
||||
{
|
||||
return DISPENSER_MAX_METAL_AMMO;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Control screen
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
DECLARE_VGUI_SCREEN_FACTORY( CDispenserControlPanel, "screen_obj_dispenser_blue" );
|
||||
DECLARE_VGUI_SCREEN_FACTORY( CDispenserControlPanel_Red, "screen_obj_dispenser_red" );
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Constructor:
|
||||
//-----------------------------------------------------------------------------
|
||||
CDispenserControlPanel::CDispenserControlPanel( vgui::Panel *parent, const char *panelName )
|
||||
: BaseClass( parent, "CDispenserControlPanel" )
|
||||
{
|
||||
m_pAmmoProgress = new RotatingProgressBar( this, "MeterArrow" );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Deactivates buttons we can't afford
|
||||
//-----------------------------------------------------------------------------
|
||||
void CDispenserControlPanel::OnTickActive( C_BaseObject *pObj, C_TFPlayer *pLocalPlayer )
|
||||
{
|
||||
BaseClass::OnTickActive( pObj, pLocalPlayer );
|
||||
|
||||
Assert( dynamic_cast< C_ObjectDispenser* >( pObj ) );
|
||||
m_hDispenser = static_cast< C_ObjectDispenser* >( pObj );
|
||||
|
||||
float flProgress = m_hDispenser ? m_hDispenser->GetMetalAmmoCount() / (float)m_hDispenser->GetMaxMetal() : 0.f;
|
||||
|
||||
m_pAmmoProgress->SetProgress( flProgress );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
bool CDispenserControlPanel::IsVisible( void )
|
||||
{
|
||||
if ( m_hDispenser )
|
||||
{
|
||||
#ifdef STAGING_ONLY
|
||||
if ( m_hDispenser->IsMiniBuilding() )
|
||||
return false;
|
||||
#endif // STAGING_ONLY
|
||||
|
||||
if ( m_hDispenser->GetInvisibilityLevel() == 1.f )
|
||||
return false;
|
||||
}
|
||||
|
||||
return BaseClass::IsVisible();
|
||||
}
|
||||
|
||||
IMPLEMENT_CLIENTCLASS_DT(C_ObjectCartDispenser, DT_ObjectCartDispenser, CObjectCartDispenser)
|
||||
END_RECV_TABLE()
|
||||
@@ -0,0 +1,95 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================//
|
||||
|
||||
#ifndef C_OBJ_DISPENSER_H
|
||||
#define C_OBJ_DISPENSER_H
|
||||
#ifdef _WIN32
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include "c_baseobject.h"
|
||||
#include "ObjectControlPanel.h"
|
||||
#include "vgui_controls/RotatingProgressBar.h"
|
||||
|
||||
class C_ObjectDispenser : public C_BaseObject
|
||||
{
|
||||
DECLARE_CLASS( C_ObjectDispenser, C_BaseObject );
|
||||
public:
|
||||
DECLARE_CLIENTCLASS();
|
||||
|
||||
C_ObjectDispenser();
|
||||
~C_ObjectDispenser();
|
||||
|
||||
int GetMetalAmmoCount() { return m_iAmmoMetal; }
|
||||
|
||||
CUtlVector< CHandle<C_TFPlayer> > m_hHealingTargets;
|
||||
|
||||
virtual void OnDataChanged( DataUpdateType_t updateType );
|
||||
virtual void ClientThink() OVERRIDE;
|
||||
|
||||
virtual void SetInvisibilityLevel( float flValue );
|
||||
void UpdateEffects( void );
|
||||
void StopEffects( bool bRemoveAll = false );
|
||||
|
||||
virtual void UpdateDamageEffects( BuildingDamageLevel_t damageLevel );
|
||||
|
||||
virtual int GetMaxMetal( void );
|
||||
|
||||
bool m_bUpdateHealingTargets;
|
||||
|
||||
private:
|
||||
|
||||
|
||||
int m_iState;
|
||||
int m_iAmmoMetal;
|
||||
int m_iMiniBombCounter;
|
||||
|
||||
bool m_bPlayingSound;
|
||||
|
||||
struct healingtargeteffects_t
|
||||
{
|
||||
C_BaseEntity *pTarget;
|
||||
CNewParticleEffect *pEffect;
|
||||
};
|
||||
CUtlVector<healingtargeteffects_t> m_hHealingTargetEffects;
|
||||
|
||||
C_ObjectDispenser( const C_ObjectDispenser & ); // not defined, not accessible
|
||||
};
|
||||
|
||||
|
||||
class CDispenserControlPanel : public CObjectControlPanel
|
||||
{
|
||||
DECLARE_CLASS( CDispenserControlPanel, CObjectControlPanel );
|
||||
|
||||
public:
|
||||
CDispenserControlPanel( vgui::Panel *parent, const char *panelName );
|
||||
|
||||
protected:
|
||||
virtual void OnTickActive( C_BaseObject *pObj, C_TFPlayer *pLocalPlayer );
|
||||
virtual bool IsVisible() OVERRIDE;
|
||||
|
||||
private:
|
||||
vgui::RotatingProgressBar *m_pAmmoProgress;
|
||||
CHandle< C_ObjectDispenser > m_hDispenser;
|
||||
};
|
||||
|
||||
class CDispenserControlPanel_Red : public CDispenserControlPanel
|
||||
{
|
||||
DECLARE_CLASS( CDispenserControlPanel_Red, CDispenserControlPanel );
|
||||
|
||||
public:
|
||||
CDispenserControlPanel_Red( vgui::Panel *parent, const char *panelName ) : CDispenserControlPanel( parent, panelName ) {}
|
||||
};
|
||||
|
||||
|
||||
class C_ObjectCartDispenser : public C_ObjectDispenser
|
||||
{
|
||||
DECLARE_CLASS( C_ObjectCartDispenser, C_ObjectDispenser );
|
||||
public:
|
||||
DECLARE_CLIENTCLASS();
|
||||
};
|
||||
#endif //C_OBJ_DISPENSER_H
|
||||
@@ -0,0 +1,54 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
//=============================================================================//
|
||||
|
||||
#include "cbase.h"
|
||||
#include "hud.h"
|
||||
#include "c_obj_sapper.h"
|
||||
#include "c_tf_player.h"
|
||||
#include <igameevents.h>
|
||||
|
||||
// memdbgon must be the last include file in a .cpp file!!!
|
||||
#include "tier0/memdbgon.h"
|
||||
|
||||
using namespace vgui;
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Start thinking
|
||||
//-----------------------------------------------------------------------------
|
||||
void C_ObjectSapper::OnDataChanged( DataUpdateType_t type )
|
||||
{
|
||||
BaseClass::OnDataChanged( type );
|
||||
|
||||
if ( type == DATA_UPDATE_CREATED )
|
||||
{
|
||||
SetNextClientThink( CLIENT_THINK_ALWAYS );
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Create the sparking effect if we're built and ready
|
||||
//-----------------------------------------------------------------------------
|
||||
void C_ObjectSapper::ClientThink( void )
|
||||
{
|
||||
IGameEvent *event = gameeventmanager->CreateEvent( "building_info_changed" );
|
||||
if ( event )
|
||||
{
|
||||
event->SetInt( "building_type", OBJ_ATTACHMENT_SAPPER );
|
||||
event->SetInt( "object_mode", GetObjectMode() );
|
||||
gameeventmanager->FireEventClientSide( event );
|
||||
}
|
||||
}
|
||||
|
||||
float C_ObjectSapper::GetReversesBuildingConstructionSpeed( void )
|
||||
{
|
||||
float flReverseSpeed = 0.0f;
|
||||
CALL_ATTRIB_HOOK_FLOAT_ON_OTHER( GetBuilder(), flReverseSpeed, sapper_degenerates_buildings );
|
||||
|
||||
return flReverseSpeed;
|
||||
}
|
||||
|
||||
IMPLEMENT_CLIENTCLASS_DT(C_ObjectSapper, DT_ObjectSapper, CObjectSapper)
|
||||
END_RECV_TABLE()
|
||||
@@ -0,0 +1,39 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================//
|
||||
|
||||
#ifndef C_OBJ_SAPPER_H
|
||||
#define C_OBJ_SAPPER_H
|
||||
#ifdef _WIN32
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include "tf_obj_baseupgrade_shared.h"
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
class C_ObjectSapper : public C_BaseObjectUpgrade
|
||||
{
|
||||
DECLARE_CLASS( C_ObjectSapper, C_BaseObjectUpgrade );
|
||||
public:
|
||||
DECLARE_CLIENTCLASS();
|
||||
|
||||
C_ObjectSapper() {}
|
||||
|
||||
virtual void ClientThink( void );
|
||||
virtual void OnDataChanged( DataUpdateType_t type );
|
||||
|
||||
virtual bool IsHostileUpgrade( void ) { return true; }
|
||||
|
||||
float GetReversesBuildingConstructionSpeed( void );
|
||||
|
||||
private:
|
||||
C_ObjectSapper( const C_ObjectSapper & ); // not defined, not accessible
|
||||
};
|
||||
|
||||
|
||||
#endif // C_OBJ_SAPPER_H
|
||||
@@ -0,0 +1,761 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose: Client's CObjectSentrygun
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================//
|
||||
#include "cbase.h"
|
||||
#include "c_tf_player.h"
|
||||
#include "vgui_bitmapbutton.h"
|
||||
#include "vgui/ILocalize.h"
|
||||
#include "tf_fx_muzzleflash.h"
|
||||
#include "eventlist.h"
|
||||
#include "hintsystem.h"
|
||||
#include <vgui_controls/ProgressBar.h>
|
||||
#include "igameevents.h"
|
||||
|
||||
#include "c_obj_sentrygun.h"
|
||||
|
||||
// memdbgon must be the last include file in a .cpp file!!!
|
||||
#include "tier0/memdbgon.h"
|
||||
|
||||
using namespace vgui;
|
||||
|
||||
static void RecvProxy_BooleanToShieldLevel( const CRecvProxyData *pData, void *pStruct, void *pOut )
|
||||
{
|
||||
// convert old boolean "m_bShielded" to uint32 "m_nShieldLevel"
|
||||
*(uint32*)pOut = ( pData->m_Value.m_Int != 0 ) ? 1 : 0;
|
||||
}
|
||||
|
||||
IMPLEMENT_NETWORKCLASS_ALIASED( TFProjectile_SentryRocket, DT_TFProjectile_SentryRocket )
|
||||
|
||||
BEGIN_NETWORK_TABLE( C_TFProjectile_SentryRocket, DT_TFProjectile_SentryRocket )
|
||||
END_NETWORK_TABLE()
|
||||
|
||||
BEGIN_NETWORK_TABLE_NOBASE( C_ObjectSentrygun, DT_SentrygunLocalData )
|
||||
RecvPropInt( RECVINFO(m_iKills) ),
|
||||
RecvPropInt( RECVINFO(m_iAssists) ),
|
||||
END_NETWORK_TABLE()
|
||||
|
||||
IMPLEMENT_CLIENTCLASS_DT(C_ObjectSentrygun, DT_ObjectSentrygun, CObjectSentrygun)
|
||||
RecvPropInt( RECVINFO(m_iAmmoShells) ),
|
||||
RecvPropInt( RECVINFO(m_iAmmoRockets) ),
|
||||
RecvPropInt( RECVINFO(m_iState) ),
|
||||
RecvPropBool( RECVINFO(m_bPlayerControlled) ),
|
||||
RecvPropInt( RECVINFO(m_nShieldLevel) ),
|
||||
RecvPropInt( RECVINFO_NAME(m_nShieldLevel, m_bShielded), 0, RecvProxy_BooleanToShieldLevel ), // for demo compatibility only
|
||||
RecvPropEHandle( RECVINFO( m_hEnemy ) ),
|
||||
RecvPropEHandle( RECVINFO( m_hAutoAimTarget ) ),
|
||||
RecvPropDataTable( "SentrygunLocalData", 0, 0, &REFERENCE_RECV_TABLE( DT_SentrygunLocalData ) ),
|
||||
END_RECV_TABLE()
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
C_ObjectSentrygun::C_ObjectSentrygun()
|
||||
{
|
||||
m_iMaxAmmoShells = SENTRYGUN_MAX_SHELLS_1;
|
||||
m_bPlayerControlled = false;
|
||||
m_bOldPlayerControlled = false;
|
||||
m_nShieldLevel = SHIELD_NONE;
|
||||
m_nOldShieldLevel = SHIELD_NONE;
|
||||
m_hLaserBeamEffect = NULL;
|
||||
m_pTempShield = NULL;
|
||||
m_bNearMiss = false;
|
||||
m_flNextNearMissCheck = 0.f;
|
||||
|
||||
m_iOldModelIndex = 0;
|
||||
m_bOldCarried = false;
|
||||
m_bRecreateShield = false;
|
||||
m_bRecreateLaserBeam = false;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void C_ObjectSentrygun::UpdateOnRemove( void )
|
||||
{
|
||||
DestroyLaserBeam();
|
||||
DestroyShield();
|
||||
DestroySiren();
|
||||
|
||||
BaseClass::UpdateOnRemove();
|
||||
}
|
||||
|
||||
|
||||
void C_ObjectSentrygun::GetAmmoCount( int &iShells, int &iMaxShells, int &iRockets, int & iMaxRockets )
|
||||
{
|
||||
iShells = m_iAmmoShells;
|
||||
iMaxShells = m_iMaxAmmoShells;
|
||||
iRockets = m_iAmmoRockets;
|
||||
iMaxRockets = SENTRYGUN_MAX_ROCKETS;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void C_ObjectSentrygun::UpgradeLevelChanged()
|
||||
{
|
||||
switch( m_iUpgradeLevel )
|
||||
{
|
||||
case 1:
|
||||
{
|
||||
VectorCopy( SENTRYGUN_EYE_OFFSET_LEVEL_1, m_vecViewOffset );
|
||||
m_iMaxAmmoShells = SENTRYGUN_MAX_SHELLS_1;
|
||||
break;
|
||||
}
|
||||
case 2:
|
||||
{
|
||||
VectorCopy( SENTRYGUN_EYE_OFFSET_LEVEL_2, m_vecViewOffset );
|
||||
m_iMaxAmmoShells = SENTRYGUN_MAX_SHELLS_2;
|
||||
break;
|
||||
}
|
||||
case 3:
|
||||
{
|
||||
VectorCopy( SENTRYGUN_EYE_OFFSET_LEVEL_3, m_vecViewOffset );
|
||||
m_iMaxAmmoShells = SENTRYGUN_MAX_SHELLS_3;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
Assert( 0 );
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
CreateLaserBeam();
|
||||
|
||||
// Because the bounding box size changes when upgrading, force the shadow to be reprojected using the new bounds
|
||||
g_pClientShadowMgr->AddToDirtyShadowList( this, true );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void C_ObjectSentrygun::OnPreDataChanged( DataUpdateType_t updateType )
|
||||
{
|
||||
BaseClass::OnPreDataChanged( updateType );
|
||||
|
||||
m_iOldBodygroups = GetBody();
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void C_ObjectSentrygun::OnDataChanged( DataUpdateType_t updateType )
|
||||
{
|
||||
BaseClass::OnDataChanged( updateType );
|
||||
|
||||
// intercept bodygroup sets from the server
|
||||
// we aren't clientsideanimating, but we don't want the server setting our
|
||||
// bodygroup while we are placing
|
||||
if ( m_iOldBodygroups != GetBody() )
|
||||
{
|
||||
if ( IsPlacing() )
|
||||
{
|
||||
m_nBody = m_iOldBodygroups;
|
||||
}
|
||||
}
|
||||
|
||||
if ( GetModelIndex() != m_iOldModelIndex )
|
||||
{
|
||||
m_iOldModelIndex = GetModelIndex();
|
||||
|
||||
if ( IsMiniBuilding() )
|
||||
{
|
||||
CStudioHdr *pStudiohdr = GetModelPtr();
|
||||
int bodyGroup = FindBodygroupByName( "mini_sentry_light" );
|
||||
if ( bodyGroup < pStudiohdr->numbodyparts() )
|
||||
{
|
||||
mstudiobodyparts_t *pbodypart = pStudiohdr->pBodypart( bodyGroup );
|
||||
if ( pbodypart->base > 0 )
|
||||
{
|
||||
SetBodygroup( bodyGroup, 1 );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ( m_bPlayerControlled != m_bOldPlayerControlled || m_bRecreateLaserBeam )
|
||||
{
|
||||
if ( m_bPlayerControlled )
|
||||
{
|
||||
CreateLaserBeam();
|
||||
}
|
||||
else
|
||||
{
|
||||
DestroyLaserBeam();
|
||||
}
|
||||
m_bOldPlayerControlled = m_bPlayerControlled;
|
||||
m_bRecreateLaserBeam = false;
|
||||
}
|
||||
|
||||
if ( m_nShieldLevel != m_nOldShieldLevel || m_bRecreateShield )
|
||||
{
|
||||
if ( m_nShieldLevel > 0 )
|
||||
{
|
||||
CreateShield();
|
||||
}
|
||||
else
|
||||
{
|
||||
DestroyShield();
|
||||
}
|
||||
m_nOldShieldLevel = m_nShieldLevel;
|
||||
m_bRecreateShield = false;
|
||||
}
|
||||
|
||||
if ( IsCarried() != m_bOldCarried )
|
||||
{
|
||||
m_bOldCarried = IsCarried();
|
||||
if ( IsCarried() )
|
||||
{
|
||||
DestroySiren();
|
||||
}
|
||||
}
|
||||
|
||||
if ( ShouldBeActive() && !IsDisabled() && IsMiniBuilding() && !m_hSirenEffect )
|
||||
{
|
||||
CreateSiren();
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void C_ObjectSentrygun::OnGoActive( void )
|
||||
{
|
||||
CreateSiren();
|
||||
|
||||
BaseClass::OnGoActive();
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void C_ObjectSentrygun::OnGoInactive( void )
|
||||
{
|
||||
DestroySiren();
|
||||
|
||||
BaseClass::OnGoInactive();
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void C_ObjectSentrygun::OnStartDisabled( void )
|
||||
{
|
||||
DestroySiren();
|
||||
|
||||
BaseClass::OnStartDisabled();
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void C_ObjectSentrygun::OnEndDisabled( void )
|
||||
{
|
||||
CreateSiren();
|
||||
|
||||
BaseClass::OnEndDisabled();
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void C_ObjectSentrygun::CreateLaserBeam( void )
|
||||
{
|
||||
if ( !m_bPlayerControlled )
|
||||
return;
|
||||
|
||||
DestroyLaserBeam();
|
||||
|
||||
int iAttachment = LookupAttachment( "laser_origin" );
|
||||
m_hLaserBeamEffect = ParticleProp()->Create( "laser_sight_beam", PATTACH_POINT_FOLLOW, iAttachment );
|
||||
if ( m_hLaserBeamEffect )
|
||||
{
|
||||
m_hLaserBeamEffect->SetSortOrigin( m_hLaserBeamEffect->GetRenderOrigin() );
|
||||
}
|
||||
|
||||
SetNextClientThink( CLIENT_THINK_ALWAYS );
|
||||
|
||||
if ( m_hLaserBeamEffect )
|
||||
{
|
||||
if ( GetTeamNumber() == TF_TEAM_BLUE )
|
||||
{
|
||||
m_hLaserBeamEffect->SetControlPoint( 2, Vector( 0, 0, 255 ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
m_hLaserBeamEffect->SetControlPoint( 2, Vector( 255, 0, 0 ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void C_ObjectSentrygun::DestroyLaserBeam( void )
|
||||
{
|
||||
if ( m_hLaserBeamEffect )
|
||||
{
|
||||
SetNextClientThink( CLIENT_THINK_NEVER );
|
||||
ParticleProp()->StopEmissionAndDestroyImmediately( m_hLaserBeamEffect );
|
||||
m_hLaserBeamEffect = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void C_ObjectSentrygun::SetDormant( bool bDormant )
|
||||
{
|
||||
if ( IsDormant() && !bDormant )
|
||||
{
|
||||
// Make sure our shield is where we are. We may have moved since last seen.
|
||||
if ( m_pTempShield )
|
||||
{
|
||||
m_bRecreateShield = true;
|
||||
m_bRecreateLaserBeam = true;
|
||||
}
|
||||
}
|
||||
|
||||
BaseClass::SetDormant( bDormant );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void C_ObjectSentrygun::CreateShield( void )
|
||||
{
|
||||
DestroyShield();
|
||||
|
||||
model_t *pModel = (model_t *) engine->LoadModel( "models/buildables/sentry_shield.mdl" );
|
||||
m_pTempShield = tempents->SpawnTempModel( pModel, GetAbsOrigin(), GetAbsAngles(), Vector(0, 0, 0), 1, FTENT_NEVERDIE );
|
||||
if ( m_pTempShield )
|
||||
{
|
||||
m_pTempShield->ChangeTeam( GetTeamNumber() );
|
||||
m_pTempShield->m_nSkin = ( GetTeamNumber() == TF_TEAM_RED ) ? 0 : 1;
|
||||
//m_pTempShield->m_nRenderFX = kRenderFxDistort;
|
||||
}
|
||||
|
||||
m_hShieldEffect = ParticleProp()->Create( "turret_shield", PATTACH_ABSORIGIN_FOLLOW, 0, Vector( 0,0,30) );
|
||||
if ( !m_hShieldEffect )
|
||||
return;
|
||||
if ( GetTeamNumber() == TF_TEAM_BLUE )
|
||||
{
|
||||
m_hShieldEffect->SetControlPoint( 1, Vector(50,150,255) );
|
||||
}
|
||||
else
|
||||
{
|
||||
m_hShieldEffect->SetControlPoint( 1, Vector(255,50,50) );
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void C_ObjectSentrygun::DestroyShield( void )
|
||||
{
|
||||
if ( m_pTempShield )
|
||||
{
|
||||
m_pTempShield->flags = FTENT_FADEOUT;
|
||||
m_pTempShield->die = gpGlobals->curtime;
|
||||
m_pTempShield->fadeSpeed = 1.0f;
|
||||
m_pTempShield = NULL;
|
||||
}
|
||||
|
||||
if ( m_hShieldEffect )
|
||||
{
|
||||
ParticleProp()->StopEmission( m_hShieldEffect );
|
||||
m_hShieldEffect = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void C_ObjectSentrygun::CreateSiren( void )
|
||||
{
|
||||
if ( !IsMiniBuilding() )
|
||||
return;
|
||||
|
||||
if ( IsCarried() )
|
||||
return;
|
||||
|
||||
if ( m_hSirenEffect )
|
||||
return;
|
||||
|
||||
const char* flashlightName = "cart_flashinglight";
|
||||
if ( GetTeamNumber() == TF_TEAM_RED )
|
||||
{
|
||||
flashlightName = "cart_flashinglight_red";
|
||||
}
|
||||
m_hSirenEffect = ParticleProp()->Create( flashlightName, PATTACH_POINT_FOLLOW, "siren" );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void C_ObjectSentrygun::DestroySiren( void )
|
||||
{
|
||||
if ( m_hSirenEffect )
|
||||
{
|
||||
ParticleProp()->StopEmission( m_hSirenEffect );
|
||||
m_hSirenEffect = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void C_ObjectSentrygun::ClientThink( void )
|
||||
{
|
||||
if ( m_hLaserBeamEffect && m_hEnemy && GetBuilder() )
|
||||
{
|
||||
QAngle vecAngles;
|
||||
Vector vecMuzzleOrigin;
|
||||
int iAttachment = 0;
|
||||
switch ( GetUpgradeLevel() )
|
||||
{
|
||||
case 1:
|
||||
iAttachment = LookupAttachment( "muzzle" );
|
||||
break;
|
||||
case 2:
|
||||
iAttachment = LookupAttachment( "muzzle_l" );
|
||||
break;
|
||||
case 3:
|
||||
iAttachment = LookupAttachment( "rocket_l" );
|
||||
break;
|
||||
}
|
||||
GetAttachment( iAttachment, vecMuzzleOrigin, vecAngles );
|
||||
|
||||
Vector vForward;
|
||||
AngleVectors( vecAngles, &vForward );
|
||||
|
||||
Vector vEnd = m_hEnemy->WorldSpaceCenter();
|
||||
if ( m_hAutoAimTarget )
|
||||
{
|
||||
vEnd = m_hAutoAimTarget->GetAbsOrigin() + m_hAutoAimTarget->GetClassEyeHeight()*0.75f;
|
||||
}
|
||||
|
||||
trace_t trace;
|
||||
CTraceFilterIgnoreTeammatesAndTeamObjects filter( GetBuilder(), COLLISION_GROUP_NONE, GetBuilder()->GetTeamNumber() );
|
||||
UTIL_TraceLine( vecMuzzleOrigin, vEnd, MASK_SOLID, &filter, &trace );
|
||||
|
||||
Vector vecInterpBeamPos;
|
||||
InterpolateVector( gpGlobals->frametime * 25.f, m_vecLaserBeamPos, trace.endpos, vecInterpBeamPos );
|
||||
|
||||
m_hLaserBeamEffect->SetControlPoint( 1, vecInterpBeamPos );
|
||||
m_vecLaserBeamPos = vecInterpBeamPos;
|
||||
|
||||
// Perform a near-miss check.
|
||||
// This works pretty well as a threat indicator for the arrow, let's try it for our laser.
|
||||
if ( gpGlobals->curtime > m_flNextNearMissCheck )
|
||||
{
|
||||
// CheckNearMiss( vecMuzzleOrigin, m_hEnemy->GetAbsOrigin() );
|
||||
m_flNextNearMissCheck = gpGlobals->curtime + 0.2f;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void C_ObjectSentrygun::CheckNearMiss( Vector vecStart, Vector vecEnd )
|
||||
{
|
||||
// Check against the local player. If the laser sweeps near him, play the near miss sound...
|
||||
C_TFPlayer *pLocalPlayer = C_TFPlayer::GetLocalTFPlayer();
|
||||
if ( !pLocalPlayer || !pLocalPlayer->IsAlive() )
|
||||
return;
|
||||
|
||||
// Can't hear near miss sounds from friendly guns.
|
||||
// if ( pLocalPlayer->GetTeamNumber() == GetTeamNumber() )
|
||||
// return;
|
||||
|
||||
Vector vecPlayerPos = pLocalPlayer->GetAbsOrigin();
|
||||
Vector vecClosestPoint;
|
||||
float dist;
|
||||
CalcClosestPointOnLineSegment( vecPlayerPos, vecStart, vecEnd, vecClosestPoint, &dist );
|
||||
dist = vecPlayerPos.DistTo( vecClosestPoint );
|
||||
if ( dist > 120 )
|
||||
{
|
||||
StopSound( "Building_Sentrygun.ShaftLaserPass" );
|
||||
return;
|
||||
}
|
||||
|
||||
if ( !m_bNearMiss )
|
||||
{
|
||||
// We're good for a near miss!
|
||||
float soundlen = 0;
|
||||
EmitSound_t params;
|
||||
params.m_flSoundTime = 0;
|
||||
params.m_pSoundName = "Building_Sentrygun.ShaftLaserPass";
|
||||
params.m_pflSoundDuration = &soundlen;
|
||||
params.m_flVolume = 1.f - (dist / 120.f);
|
||||
CSingleUserRecipientFilter localFilter( pLocalPlayer );
|
||||
EmitSound( localFilter, pLocalPlayer->entindex(), params );
|
||||
|
||||
m_bNearMiss = true;
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void C_ObjectSentrygun::DisplayHintTo( C_BasePlayer *pPlayer )
|
||||
{
|
||||
bool bHintPlayed = false;
|
||||
|
||||
C_TFPlayer *pTFPlayer = ToTFPlayer(pPlayer);
|
||||
if ( InSameTeam( pPlayer ) )
|
||||
{
|
||||
// We're looking at a friendly object.
|
||||
if ( pTFPlayer->IsPlayerClass( TF_CLASS_ENGINEER ) )
|
||||
{
|
||||
// If the sentrygun can be upgraded, and I can afford it, let me know
|
||||
if ( GetHealth() == GetMaxHealth() && GetUpgradeLevel() < 3 )
|
||||
{
|
||||
if ( pTFPlayer->GetBuildResources() >= SENTRYGUN_UPGRADE_COST )
|
||||
{
|
||||
bHintPlayed = pTFPlayer->HintMessage( HINT_ENGINEER_UPGRADE_SENTRYGUN, false, true );
|
||||
}
|
||||
else
|
||||
{
|
||||
bHintPlayed = pTFPlayer->HintMessage( HINT_ENGINEER_METAL_TO_UPGRADE, false, true );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ( !bHintPlayed )
|
||||
{
|
||||
BaseClass::DisplayHintTo( pPlayer );
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
const char *C_ObjectSentrygun::GetHudStatusIcon( void )
|
||||
{
|
||||
const char *pszResult;
|
||||
|
||||
switch( m_iUpgradeLevel )
|
||||
{
|
||||
case 1:
|
||||
default:
|
||||
pszResult = "obj_status_sentrygun_1";
|
||||
break;
|
||||
case 2:
|
||||
pszResult = "obj_status_sentrygun_2";
|
||||
break;
|
||||
case 3:
|
||||
pszResult = "obj_status_sentrygun_3";
|
||||
break;
|
||||
}
|
||||
|
||||
return pszResult;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
BuildingHudAlert_t C_ObjectSentrygun::GetBuildingAlertLevel( void )
|
||||
{
|
||||
BuildingHudAlert_t baseAlertLevel = BaseClass::GetBuildingAlertLevel();
|
||||
|
||||
// Just warn on low shells.
|
||||
|
||||
float flShellPercent = (float)m_iAmmoShells / (float)m_iMaxAmmoShells;
|
||||
|
||||
BuildingHudAlert_t alertLevel = BUILDING_HUD_ALERT_NONE;
|
||||
|
||||
if ( !IsCarried() )
|
||||
{
|
||||
if ( !IsBuilding() && flShellPercent < 0.25 )
|
||||
{
|
||||
alertLevel = BUILDING_HUD_ALERT_VERY_LOW_AMMO;
|
||||
}
|
||||
else if ( !IsBuilding() && flShellPercent < 0.50 )
|
||||
{
|
||||
alertLevel = BUILDING_HUD_ALERT_LOW_AMMO;
|
||||
}
|
||||
}
|
||||
|
||||
return MAX( baseAlertLevel, alertLevel );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: During placement, only use the smaller bbox for shadow calc, don't include the range bodygroup
|
||||
//-----------------------------------------------------------------------------
|
||||
void C_ObjectSentrygun::GetShadowRenderBounds( Vector &mins, Vector &maxs, ShadowType_t shadowType )
|
||||
{
|
||||
if ( IsPlacing() )
|
||||
{
|
||||
mins = CollisionProp()->OBBMins();
|
||||
maxs = CollisionProp()->OBBMaxs();
|
||||
|
||||
// HACK: The collision prop bounding box doesn't quite cover the blueprint model, so we bloat it a little
|
||||
Vector bbBloat( 10.0f, 10.0f, 0.0f );
|
||||
mins -= bbBloat;
|
||||
maxs += bbBloat;
|
||||
}
|
||||
else
|
||||
{
|
||||
BaseClass::GetShadowRenderBounds( mins, maxs, shadowType );
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Re-calc our damage particles when we get a new model
|
||||
//-----------------------------------------------------------------------------
|
||||
CStudioHdr *C_ObjectSentrygun::OnNewModel( void )
|
||||
{
|
||||
CStudioHdr *hdr = BaseClass::OnNewModel();
|
||||
|
||||
UpdateDamageEffects( m_damageLevel );
|
||||
|
||||
// Reset Bodygroups
|
||||
for ( int i = GetNumBodyGroups()-1; i >= 0; i-- )
|
||||
{
|
||||
SetBodygroup( i, 0 );
|
||||
}
|
||||
|
||||
m_iPlacementBodygroup = FindBodygroupByName( "sentry1_range" );
|
||||
m_iPlacementBodygroup_Mini = FindBodygroupByName( "sentry1_range_mini" );
|
||||
|
||||
return hdr;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Damage level has changed, update our effects
|
||||
//-----------------------------------------------------------------------------
|
||||
void C_ObjectSentrygun::UpdateDamageEffects( BuildingDamageLevel_t damageLevel )
|
||||
{
|
||||
if ( m_hDamageEffects )
|
||||
{
|
||||
m_hDamageEffects->StopEmission( false, false );
|
||||
m_hDamageEffects = NULL;
|
||||
}
|
||||
|
||||
const char *pszEffect = "";
|
||||
|
||||
switch( damageLevel )
|
||||
{
|
||||
case BUILDING_DAMAGE_LEVEL_LIGHT:
|
||||
pszEffect = "sentrydamage_1";
|
||||
break;
|
||||
case BUILDING_DAMAGE_LEVEL_MEDIUM:
|
||||
pszEffect = "sentrydamage_2";
|
||||
break;
|
||||
case BUILDING_DAMAGE_LEVEL_HEAVY:
|
||||
pszEffect = "sentrydamage_3";
|
||||
break;
|
||||
case BUILDING_DAMAGE_LEVEL_CRITICAL:
|
||||
pszEffect = "sentrydamage_4";
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if ( Q_strlen(pszEffect) > 0 )
|
||||
{
|
||||
switch( m_iUpgradeLevel )
|
||||
{
|
||||
case 1:
|
||||
case 2:
|
||||
m_hDamageEffects = ParticleProp()->Create( pszEffect, PATTACH_POINT_FOLLOW, "build_point_0" );
|
||||
break;
|
||||
|
||||
case 3:
|
||||
m_hDamageEffects = ParticleProp()->Create( pszEffect, PATTACH_POINT_FOLLOW, "sentrydamage" );
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: placement state has changed, update the model
|
||||
//-----------------------------------------------------------------------------
|
||||
void C_ObjectSentrygun::OnPlacementStateChanged( bool bValidPlacement )
|
||||
{
|
||||
if ( bValidPlacement && ( m_iPlacementBodygroup >= 0 ) && ( m_iPlacementBodygroup_Mini >= 0 ) )
|
||||
{
|
||||
if ( IsMiniBuilding() )
|
||||
{
|
||||
SetBodygroup( m_iPlacementBodygroup, 0 );
|
||||
SetBodygroup( m_iPlacementBodygroup_Mini, 1 );
|
||||
}
|
||||
else
|
||||
{
|
||||
SetBodygroup( m_iPlacementBodygroup, 1 );
|
||||
SetBodygroup( m_iPlacementBodygroup_Mini, 0 );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
SetBodygroup( m_iPlacementBodygroup, 0 );
|
||||
SetBodygroup( m_iPlacementBodygroup_Mini, 0 );
|
||||
}
|
||||
|
||||
BaseClass::OnPlacementStateChanged( bValidPlacement );
|
||||
}
|
||||
|
||||
void C_ObjectSentrygun::DebugDamageParticles( void )
|
||||
{
|
||||
Msg( "Health %d\n", GetHealth() );
|
||||
|
||||
BuildingDamageLevel_t damageLevel = CalculateDamageLevel();
|
||||
Msg( "Damage Level %d\n", (int)damageLevel );
|
||||
|
||||
if ( m_hDamageEffects )
|
||||
{
|
||||
Msg( "m_hDamageEffects is valid\n" );
|
||||
}
|
||||
else
|
||||
{
|
||||
Msg( "m_hDamageEffects is NULL\n" );
|
||||
}
|
||||
|
||||
// print all particles owned by particleprop
|
||||
ParticleProp()->DebugPrintEffects();
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void C_ObjectSentrygun::BuildTransformations( CStudioHdr *hdr, Vector *pos, Quaternion q[], const matrix3x4_t& cameraTransform, int boneMask, CBoneBitList &boneComputed )
|
||||
{
|
||||
BaseClass::BuildTransformations( hdr, pos, q, cameraTransform, boneMask, boneComputed );
|
||||
|
||||
if ( !IsMiniBuilding() )
|
||||
return;
|
||||
|
||||
if ( IsBuilding() || IsPlacing() )
|
||||
return;
|
||||
|
||||
|
||||
//Vector position;
|
||||
//for ( int i=0; i<8; ++i )
|
||||
//{
|
||||
// matrix3x4_t &transform = GetBoneForWrite( i );
|
||||
// MatrixGetColumn( transform, 3, position );
|
||||
// MatrixSetColumn( Vector(0,0,-4) + position, 3, transform );
|
||||
//}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
const char* C_ObjectSentrygun::GetStatusName() const
|
||||
{
|
||||
if ( IsDisposableBuilding() )
|
||||
{
|
||||
return "#TF_Object_Sentry_Disp";
|
||||
}
|
||||
|
||||
return "#TF_Object_Sentry";
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,150 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================//
|
||||
|
||||
#ifndef C_OBJ_SENTRYGUN_H
|
||||
#define C_OBJ_SENTRYGUN_H
|
||||
#ifdef _WIN32
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include "c_baseobject.h"
|
||||
#include "ObjectControlPanel.h"
|
||||
#include "c_tf_projectile_rocket.h"
|
||||
#include "tempent.h"
|
||||
#include "c_te_legacytempents.h"
|
||||
#include "c_tf_player.h"
|
||||
|
||||
class C_MuzzleFlashModel;
|
||||
|
||||
enum
|
||||
{
|
||||
SHIELD_NONE = 0,
|
||||
SHIELD_NORMAL, // 33% damage taken
|
||||
SHIELD_MAX, // 10% damage taken, no inactive period
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Sentry object
|
||||
//-----------------------------------------------------------------------------
|
||||
class C_ObjectSentrygun : public C_BaseObject
|
||||
{
|
||||
DECLARE_CLASS( C_ObjectSentrygun, C_BaseObject );
|
||||
public:
|
||||
DECLARE_CLIENTCLASS();
|
||||
|
||||
C_ObjectSentrygun();
|
||||
|
||||
virtual void UpdateOnRemove( void );
|
||||
|
||||
void GetAmmoCount( int &iShells, int &iMaxShells, int &iRockets, int & iMaxRockets );
|
||||
|
||||
virtual BuildingHudAlert_t GetBuildingAlertLevel( void );
|
||||
|
||||
virtual const char *GetHudStatusIcon( void );
|
||||
|
||||
int GetKills( void ) { return m_iKills; }
|
||||
int GetAssists( void ) { return m_iAssists; }
|
||||
|
||||
virtual void GetShadowRenderBounds( Vector &mins, Vector &maxs, ShadowType_t shadowType );
|
||||
|
||||
virtual CStudioHdr *OnNewModel( void );
|
||||
virtual void UpdateDamageEffects( BuildingDamageLevel_t damageLevel );
|
||||
|
||||
virtual void OnPlacementStateChanged( bool bValidPlacement );
|
||||
|
||||
void DebugDamageParticles();
|
||||
|
||||
virtual const char* GetStatusName() const;
|
||||
|
||||
virtual void OnPreDataChanged( DataUpdateType_t updateType );
|
||||
virtual void OnDataChanged( DataUpdateType_t updateType );
|
||||
|
||||
virtual bool IsUpgrading( void ) const { return ( m_iState == SENTRY_STATE_UPGRADING ); }
|
||||
|
||||
void CreateLaserBeam( void );
|
||||
void DestroyLaserBeam( void );
|
||||
|
||||
virtual void SetDormant( bool bDormant );
|
||||
void CreateShield( void );
|
||||
void DestroyShield( void );
|
||||
|
||||
void CreateSiren( void );
|
||||
void DestroySiren( void );
|
||||
|
||||
virtual void OnGoActive( void );
|
||||
virtual void OnGoInactive( void );
|
||||
virtual void OnStartDisabled( void );
|
||||
virtual void OnEndDisabled( void );
|
||||
|
||||
virtual void ClientThink( void );
|
||||
|
||||
void CheckNearMiss( Vector vecStart, Vector vecEnd );
|
||||
|
||||
// ITargetIDProvidesHint
|
||||
public:
|
||||
virtual void DisplayHintTo( C_BasePlayer *pPlayer );
|
||||
|
||||
virtual void BuildTransformations( CStudioHdr *hdr, Vector *pos, Quaternion q[], const matrix3x4_t& cameraTransform, int boneMask, CBoneBitList &boneComputed );
|
||||
|
||||
private:
|
||||
|
||||
virtual void UpgradeLevelChanged();
|
||||
|
||||
private:
|
||||
int m_iState;
|
||||
|
||||
int m_iAmmoShells;
|
||||
int m_iMaxAmmoShells;
|
||||
int m_iAmmoRockets;
|
||||
|
||||
int m_iKills;
|
||||
int m_iAssists;
|
||||
|
||||
int m_iPlacementBodygroup;
|
||||
int m_iPlacementBodygroup_Mini;
|
||||
|
||||
int m_iOldBodygroups;
|
||||
|
||||
bool m_bPlayerControlled;
|
||||
bool m_bOldPlayerControlled;
|
||||
uint32 m_nShieldLevel;
|
||||
uint32 m_nOldShieldLevel;
|
||||
bool m_bOldCarried;
|
||||
|
||||
bool m_bPDQSentry;
|
||||
|
||||
int m_iOldModelIndex;
|
||||
|
||||
bool m_bNearMiss;
|
||||
bool m_bRecreateShield;
|
||||
bool m_bRecreateLaserBeam;
|
||||
float m_flNextNearMissCheck;
|
||||
|
||||
C_LocalTempEntity *m_pTempShield;
|
||||
|
||||
HPARTICLEFFECT m_hSirenEffect;
|
||||
HPARTICLEFFECT m_hShieldEffect;
|
||||
HPARTICLEFFECT m_hLaserBeamEffect;
|
||||
CNetworkHandle( CBaseEntity, m_hEnemy );
|
||||
CNetworkHandle( C_TFPlayer, m_hAutoAimTarget );
|
||||
|
||||
Vector m_vecLaserBeamPos;
|
||||
|
||||
private:
|
||||
C_ObjectSentrygun( const C_ObjectSentrygun & ); // not defined, not accessible
|
||||
};
|
||||
|
||||
class C_TFProjectile_SentryRocket : public C_TFProjectile_Rocket
|
||||
{
|
||||
DECLARE_CLASS( C_TFProjectile_SentryRocket, C_TFProjectile_Rocket );
|
||||
public:
|
||||
DECLARE_CLIENTCLASS();
|
||||
|
||||
virtual void CreateRocketTrails( void ) {}
|
||||
};
|
||||
|
||||
#endif //C_OBJ_SENTRYGUN_H
|
||||
@@ -0,0 +1,465 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose: Client's CObjectTeleporter
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================//
|
||||
#include "cbase.h"
|
||||
#include "c_baseobject.h"
|
||||
#include "c_tf_player.h"
|
||||
#include "vgui/ILocalize.h"
|
||||
#include "c_obj_teleporter.h"
|
||||
#include "soundenvelope.h"
|
||||
#include "vgui/ILocalize.h"
|
||||
#include "tf_gamerules.h"
|
||||
|
||||
// memdbgon must be the last include file in a .cpp file!!!
|
||||
#include "tier0/memdbgon.h"
|
||||
|
||||
using namespace vgui;
|
||||
|
||||
#define TELEPORTER_MINS Vector( -24, -24, 0)
|
||||
#define TELEPORTER_MAXS Vector( 24, 24, 12)
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Teleporter object
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
IMPLEMENT_CLIENTCLASS_DT(C_ObjectTeleporter, DT_ObjectTeleporter, CObjectTeleporter)
|
||||
RecvPropInt( RECVINFO(m_iState) ),
|
||||
RecvPropTime( RECVINFO(m_flRechargeTime) ),
|
||||
RecvPropTime( RECVINFO(m_flCurrentRechargeDuration) ),
|
||||
RecvPropInt( RECVINFO(m_iTimesUsed) ),
|
||||
RecvPropFloat( RECVINFO(m_flYawToExit) ),
|
||||
RecvPropBool( RECVINFO(m_bMatchBuilding) ),
|
||||
END_RECV_TABLE()
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
C_ObjectTeleporter::C_ObjectTeleporter()
|
||||
{
|
||||
m_hChargedEffect = NULL;
|
||||
m_hDirectionEffect = NULL;
|
||||
m_hChargedLeftArmEffect = NULL;
|
||||
m_hChargedRightArmEffect = NULL;
|
||||
|
||||
m_iDirectionArrowPoseParam = 0;
|
||||
|
||||
m_pSpinSound = NULL;
|
||||
|
||||
m_bMatchBuilding = false;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void C_ObjectTeleporter::UpdateOnRemove( void )
|
||||
{
|
||||
StopActiveEffects();
|
||||
StopChargedEffects();
|
||||
|
||||
if ( m_pSpinSound )
|
||||
{
|
||||
CSoundEnvelopeController::GetController().SoundDestroy( m_pSpinSound );
|
||||
}
|
||||
|
||||
BaseClass::UpdateOnRemove();
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void C_ObjectTeleporter::OnPreDataChanged( DataUpdateType_t updateType )
|
||||
{
|
||||
BaseClass::OnPreDataChanged( updateType );
|
||||
|
||||
m_iOldState = m_iState;
|
||||
m_bOldMatchBuilding = m_bMatchBuilding;
|
||||
}
|
||||
|
||||
void C_ObjectTeleporter::StartBuildingEffects()
|
||||
{
|
||||
StopBuildingEffects();
|
||||
char szEffect[128];
|
||||
|
||||
// arm glow effects
|
||||
Q_snprintf( szEffect, sizeof(szEffect), "teleporter_arms_circle_%s_blink", ( GetTeamNumber() == TF_TEAM_RED ) ? "red" : "blue" );
|
||||
|
||||
Assert( m_hBuildingLeftArmEffect.m_pObject == NULL );
|
||||
m_hBuildingLeftArmEffect = ParticleProp()->Create( szEffect, PATTACH_POINT_FOLLOW, 1 );
|
||||
|
||||
Assert( m_hBuildingRightArmEffect.m_pObject == NULL );
|
||||
m_hBuildingRightArmEffect = ParticleProp()->Create( szEffect, PATTACH_POINT_FOLLOW, 3 );
|
||||
}
|
||||
|
||||
void C_ObjectTeleporter::StartChargedEffects()
|
||||
{
|
||||
StopChargedEffects();
|
||||
char szEffect[128];
|
||||
|
||||
Q_snprintf( szEffect, sizeof(szEffect), "teleporter_%s_charged_level%d",
|
||||
( GetTeamNumber() == TF_TEAM_RED ) ? "red" : "blue", GetUpgradeLevel() );
|
||||
|
||||
Assert( m_hChargedEffect.m_pObject == NULL );
|
||||
m_hChargedEffect = ParticleProp()->Create( szEffect, PATTACH_ABSORIGIN );
|
||||
}
|
||||
|
||||
void C_ObjectTeleporter::StartActiveEffects()
|
||||
{
|
||||
StopActiveEffects();
|
||||
char szEffect[128];
|
||||
|
||||
Q_snprintf( szEffect, sizeof(szEffect), "teleporter_%s_%s_level%d",
|
||||
( GetTeamNumber() == TF_TEAM_RED ) ? "red" : "blue",
|
||||
GetObjectMode() == MODE_TELEPORTER_ENTRANCE ? "entrance" : "exit",
|
||||
GetUpgradeLevel() );
|
||||
|
||||
Assert( m_hDirectionEffect.m_pObject == NULL );
|
||||
m_hDirectionEffect = ParticleProp()->Create( szEffect, PATTACH_ABSORIGIN );
|
||||
|
||||
// arm glow effects
|
||||
Q_snprintf( szEffect, sizeof(szEffect), "teleporter_arms_circle_%s",
|
||||
( GetTeamNumber() == TF_TEAM_RED ) ? "red" : "blue" );
|
||||
|
||||
Assert( m_hChargedLeftArmEffect.m_pObject == NULL );
|
||||
m_hChargedLeftArmEffect = ParticleProp()->Create( szEffect, PATTACH_POINT_FOLLOW, 1 );
|
||||
|
||||
Assert( m_hChargedRightArmEffect.m_pObject == NULL );
|
||||
m_hChargedRightArmEffect = ParticleProp()->Create( szEffect, PATTACH_POINT_FOLLOW, 3 );
|
||||
|
||||
// always reinitializes sound since this only gets called when the sound needs to start or change
|
||||
CSoundEnvelopeController &controller = CSoundEnvelopeController::GetController();
|
||||
if ( m_pSpinSound )
|
||||
{
|
||||
controller.SoundDestroy( m_pSpinSound );
|
||||
m_pSpinSound = NULL;
|
||||
}
|
||||
char szSound[128];
|
||||
Q_snprintf( szSound, sizeof(szSound), "Building_Teleporter.SpinLevel%d", GetUpgradeLevel());
|
||||
|
||||
CLocalPlayerFilter filter;
|
||||
m_pSpinSound = controller.SoundCreate( filter, entindex(), szSound );
|
||||
controller.Play( m_pSpinSound, 1.0, 100 );
|
||||
}
|
||||
|
||||
void C_ObjectTeleporter::StopBuildingEffects()
|
||||
{
|
||||
if ( m_hBuildingLeftArmEffect )
|
||||
{
|
||||
ParticleProp()->StopEmission( m_hBuildingLeftArmEffect );
|
||||
m_hBuildingLeftArmEffect = NULL;
|
||||
}
|
||||
|
||||
if ( m_hBuildingRightArmEffect )
|
||||
{
|
||||
ParticleProp()->StopEmission( m_hBuildingRightArmEffect );
|
||||
m_hBuildingRightArmEffect = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
void C_ObjectTeleporter::StopChargedEffects()
|
||||
{
|
||||
if ( m_hChargedEffect )
|
||||
{
|
||||
ParticleProp()->StopEmission( m_hChargedEffect );
|
||||
m_hChargedEffect = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
void C_ObjectTeleporter::StopActiveEffects()
|
||||
{
|
||||
if ( m_hDirectionEffect )
|
||||
{
|
||||
ParticleProp()->StopEmission( m_hDirectionEffect );
|
||||
m_hDirectionEffect = NULL;
|
||||
}
|
||||
|
||||
if ( m_hChargedLeftArmEffect )
|
||||
{
|
||||
ParticleProp()->StopEmission( m_hChargedLeftArmEffect );
|
||||
m_hChargedLeftArmEffect = NULL;
|
||||
}
|
||||
|
||||
if ( m_hChargedRightArmEffect )
|
||||
{
|
||||
ParticleProp()->StopEmission( m_hChargedRightArmEffect );
|
||||
m_hChargedRightArmEffect = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void C_ObjectTeleporter::SetInvisibilityLevel( float flValue )
|
||||
{
|
||||
if ( IsEnteringOrExitingFullyInvisible( flValue ) )
|
||||
{
|
||||
UpdateTeleporterEffects();
|
||||
}
|
||||
|
||||
BaseClass::SetInvisibilityLevel( flValue );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void C_ObjectTeleporter::UpdateTeleporterEffects( void )
|
||||
{
|
||||
#ifdef STAGING_ONLY
|
||||
C_TFPlayer *pTFOwner = GetOwner();
|
||||
if ( ( pTFOwner && pTFOwner->m_Shared.IsEnteringOrExitingFullyInvisible() ) || GetInvisibilityLevel() == 1.f )
|
||||
{
|
||||
StopActiveEffects();
|
||||
StopBuildingEffects();
|
||||
StopChargedEffects();
|
||||
return;
|
||||
}
|
||||
#endif // STAGING_ONLY
|
||||
|
||||
if ( m_bMatchBuilding )
|
||||
{
|
||||
StartBuildingEffects();
|
||||
}
|
||||
else
|
||||
{
|
||||
StopBuildingEffects();
|
||||
}
|
||||
|
||||
// In MVM, teleporter from invaders act as spawn point. Always play active effect
|
||||
if ( TFGameRules() && TFGameRules()->IsMannVsMachineMode() )
|
||||
{
|
||||
if ( m_iState != TELEPORTER_STATE_BUILDING && GetTeamNumber() == TF_TEAM_PVE_INVADERS )
|
||||
{
|
||||
StartChargedEffects();
|
||||
StartActiveEffects();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if ( m_iState == TELEPORTER_STATE_READY )
|
||||
{
|
||||
StartChargedEffects();
|
||||
}
|
||||
else
|
||||
{
|
||||
StopChargedEffects();
|
||||
}
|
||||
|
||||
if ( m_iState > TELEPORTER_STATE_IDLE && m_iOldState <= TELEPORTER_STATE_IDLE )
|
||||
{
|
||||
StartActiveEffects();
|
||||
}
|
||||
else if ( ( m_iState <= TELEPORTER_STATE_IDLE || m_iState == TELEPORTER_STATE_UPGRADING ) && m_iOldState > TELEPORTER_STATE_IDLE )
|
||||
{
|
||||
StopActiveEffects();
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void C_ObjectTeleporter::OnDataChanged( DataUpdateType_t updateType )
|
||||
{
|
||||
BaseClass::OnDataChanged( updateType );
|
||||
|
||||
if ( m_bOldMatchBuilding != m_bMatchBuilding )
|
||||
{
|
||||
m_bOldMatchBuilding = m_bMatchBuilding;
|
||||
UpdateTeleporterEffects();
|
||||
}
|
||||
|
||||
if ( m_iOldState != m_iState )
|
||||
{
|
||||
UpdateTeleporterEffects();
|
||||
m_iOldState = m_iState;
|
||||
}
|
||||
|
||||
// update the pitch based on our playback rate
|
||||
if ( m_pSpinSound )
|
||||
{
|
||||
CSoundEnvelopeController &controller = CSoundEnvelopeController::GetController();
|
||||
|
||||
controller.SoundChangePitch( m_pSpinSound, GetPlaybackRate() * 100.0f, 0.1 );
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
float C_ObjectTeleporter::GetChargeTime( void )
|
||||
{
|
||||
float flTime = m_flRechargeTime - gpGlobals->curtime;
|
||||
|
||||
if ( flTime < 0 )
|
||||
return 0;
|
||||
|
||||
return flTime;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
int C_ObjectTeleporter::GetTimesUsed( void )
|
||||
{
|
||||
return m_iTimesUsed;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
CStudioHdr *C_ObjectTeleporter::OnNewModel( void )
|
||||
{
|
||||
CStudioHdr *hdr = BaseClass::OnNewModel();
|
||||
|
||||
m_iDirectionArrowPoseParam = LookupPoseParameter( "direction" );
|
||||
|
||||
SetNextClientThink( CLIENT_THINK_ALWAYS );
|
||||
|
||||
return hdr;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Update the direction arrow
|
||||
//-----------------------------------------------------------------------------
|
||||
void C_ObjectTeleporter::ClientThink( void )
|
||||
{
|
||||
if ( m_iState >= TELEPORTER_STATE_READY )
|
||||
{
|
||||
SetPoseParameter( m_iDirectionArrowPoseParam, m_flYawToExit);
|
||||
}
|
||||
|
||||
#ifdef STAGING_ONLY
|
||||
C_TFPlayer *pTFOwner = GetOwner();
|
||||
if ( pTFOwner && pTFOwner->m_Shared.IsEnteringOrExitingFullyInvisible() )
|
||||
{
|
||||
UpdateTeleporterEffects();
|
||||
}
|
||||
#endif // STAGING_ONLY
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void C_ObjectTeleporter::GetTargetIDDataString( OUT_Z_BYTECAP(iMaxLenInBytes) wchar_t *sDataString, int iMaxLenInBytes )
|
||||
{
|
||||
Assert( iMaxLenInBytes >= sizeof(sDataString[0]) );
|
||||
wchar_t wzBaseString[MAX_ID_STRING];
|
||||
BaseClass::GetTargetIDDataString( wzBaseString, sizeof( wzBaseString ) );
|
||||
|
||||
sDataString[0] = '\0';
|
||||
if ( m_iState == TELEPORTER_STATE_RECHARGING && gpGlobals->curtime < m_flRechargeTime )
|
||||
{
|
||||
float flPercent = clamp( ( m_flRechargeTime - gpGlobals->curtime ) / m_flCurrentRechargeDuration, 0.0f, 1.0f );
|
||||
|
||||
wchar_t wszRecharging[ 32 ];
|
||||
_snwprintf( wszRecharging, ARRAYSIZE(wszRecharging) - 1, L"%.0f", 100 - (flPercent * 100) );
|
||||
wszRecharging[ ARRAYSIZE(wszRecharging)-1 ] = '\0';
|
||||
|
||||
const char *printFormatString = "#TF_playerid_object_recharging";
|
||||
|
||||
g_pVGuiLocalize->ConstructString( sDataString, iMaxLenInBytes, g_pVGuiLocalize->Find(printFormatString),
|
||||
1,
|
||||
wszRecharging );
|
||||
}
|
||||
else if ( m_iState == TELEPORTER_STATE_IDLE )
|
||||
{
|
||||
g_pVGuiLocalize->ConstructString( sDataString, iMaxLenInBytes, g_pVGuiLocalize->Find("#TF_playerid_teleporter_nomatch" ), 0 );
|
||||
}
|
||||
|
||||
// Concatenate the base level string
|
||||
V_wcsncat( sDataString, L" ", iMaxLenInBytes / sizeof( wchar_t ) );
|
||||
V_wcsncat( sDataString, wzBaseString, iMaxLenInBytes / sizeof( wchar_t ) );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Damage level has changed, update our effects
|
||||
//-----------------------------------------------------------------------------
|
||||
void C_ObjectTeleporter::UpdateDamageEffects( BuildingDamageLevel_t damageLevel )
|
||||
{
|
||||
if ( m_hDamageEffects )
|
||||
{
|
||||
m_hDamageEffects->StopEmission( false, false );
|
||||
m_hDamageEffects = NULL;
|
||||
}
|
||||
|
||||
const char *pszEffect = "";
|
||||
|
||||
switch( damageLevel )
|
||||
{
|
||||
case BUILDING_DAMAGE_LEVEL_LIGHT:
|
||||
pszEffect = "tpdamage_1";
|
||||
break;
|
||||
case BUILDING_DAMAGE_LEVEL_MEDIUM:
|
||||
pszEffect = "tpdamage_2";
|
||||
break;
|
||||
case BUILDING_DAMAGE_LEVEL_HEAVY:
|
||||
pszEffect = "tpdamage_3";
|
||||
break;
|
||||
case BUILDING_DAMAGE_LEVEL_CRITICAL:
|
||||
pszEffect = "tpdamage_4";
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if ( Q_strlen(pszEffect) > 0 )
|
||||
{
|
||||
m_hDamageEffects = ParticleProp()->Create( pszEffect, PATTACH_ABSORIGIN );
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
bool C_ObjectTeleporter::IsPlacementPosValid( void )
|
||||
{
|
||||
bool bResult = BaseClass::IsPlacementPosValid();
|
||||
|
||||
if ( !bResult )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// m_vecBuildOrigin is the proposed build origin
|
||||
|
||||
// start above the teleporter position
|
||||
Vector vecTestPos = m_vecBuildOrigin;
|
||||
vecTestPos.z += TELEPORTER_MAXS.z;
|
||||
|
||||
// make sure we can fit a player on top in this pos
|
||||
trace_t tr;
|
||||
UTIL_TraceHull( vecTestPos, vecTestPos, VEC_HULL_MIN, VEC_HULL_MAX, MASK_SOLID | CONTENTS_PLAYERCLIP, this, COLLISION_GROUP_PLAYER_MOVEMENT, &tr );
|
||||
|
||||
return ( tr.fraction >= 1.0 );
|
||||
}
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
void C_ObjectTeleporter::UpgradeLevelChanged( void )
|
||||
{
|
||||
StopActiveEffects();
|
||||
StopChargedEffects();
|
||||
|
||||
if ( m_iState >= TELEPORTER_STATE_READY && m_iState != TELEPORTER_STATE_UPGRADING )
|
||||
{
|
||||
StartActiveEffects();
|
||||
if ( m_iState != TELEPORTER_STATE_RECHARGING )
|
||||
{
|
||||
StartChargedEffects();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void C_ObjectTeleporter::OnGoInactive( void )
|
||||
{
|
||||
StopActiveEffects();
|
||||
StopBuildingEffects();
|
||||
StopChargedEffects();
|
||||
|
||||
BaseClass::OnGoInactive();
|
||||
}
|
||||
@@ -0,0 +1,94 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================//
|
||||
|
||||
#ifndef C_OBJ_TELEPORTER_H
|
||||
#define C_OBJ_TELEPORTER_H
|
||||
#ifdef _WIN32
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include "c_baseobject.h"
|
||||
#include "ObjectControlPanel.h"
|
||||
|
||||
class C_ObjectTeleporter : public C_BaseObject
|
||||
{
|
||||
DECLARE_CLASS( C_ObjectTeleporter, C_BaseObject );
|
||||
public:
|
||||
DECLARE_CLIENTCLASS();
|
||||
|
||||
C_ObjectTeleporter();
|
||||
|
||||
virtual void OnPreDataChanged( DataUpdateType_t updateType );
|
||||
virtual void OnDataChanged( DataUpdateType_t updateType );
|
||||
|
||||
virtual void GetTargetIDDataString( OUT_Z_BYTECAP(iMaxLenInBytes) wchar_t *sDataString, int iMaxLenInBytes );
|
||||
|
||||
virtual void ClientThink( void );
|
||||
|
||||
virtual void UpdateOnRemove();
|
||||
|
||||
virtual CStudioHdr *OnNewModel( void );
|
||||
|
||||
virtual bool IsPlacementPosValid( void );
|
||||
|
||||
float GetChargeTime( void );
|
||||
|
||||
float GetCurrentRechargeDuration( void ) { return m_flCurrentRechargeDuration; }
|
||||
|
||||
int GetState( void ) { return m_iState; }
|
||||
|
||||
int GetTimesUsed( void );
|
||||
|
||||
void StartChargedEffects( void );
|
||||
void StopChargedEffects( void );
|
||||
|
||||
void StartActiveEffects( void );
|
||||
void StopActiveEffects( void );
|
||||
|
||||
void StartBuildingEffects( void );
|
||||
void StopBuildingEffects( void );
|
||||
|
||||
virtual void SetInvisibilityLevel( float flValue );
|
||||
void UpdateTeleporterEffects( void );
|
||||
|
||||
virtual void UpdateDamageEffects( BuildingDamageLevel_t damageLevel );
|
||||
|
||||
virtual int GetUpgradeLevel( void ) { return m_iUpgradeLevel; }
|
||||
int GetUpgradeMetal( void ) { return m_iUpgradeMetal; }
|
||||
//virtual int GetUpgradeMetalRequired( void ) { return GetObjectInfo( GetType() )->m_UpgradeCost; }
|
||||
virtual void UpgradeLevelChanged( void );
|
||||
|
||||
virtual void OnGoInactive( void ) OVERRIDE;
|
||||
|
||||
private:
|
||||
int m_iState;
|
||||
int m_iOldState;
|
||||
float m_flRechargeTime;
|
||||
float m_flCurrentRechargeDuration;
|
||||
int m_iTimesUsed;
|
||||
float m_flYawToExit;
|
||||
bool m_bMatchBuilding;
|
||||
bool m_bOldMatchBuilding;
|
||||
|
||||
int m_iDirectionArrowPoseParam;
|
||||
|
||||
HPARTICLEFFECT m_hChargedEffect;
|
||||
HPARTICLEFFECT m_hDirectionEffect;
|
||||
|
||||
HPARTICLEFFECT m_hChargedLeftArmEffect;
|
||||
HPARTICLEFFECT m_hChargedRightArmEffect;
|
||||
|
||||
HPARTICLEFFECT m_hBuildingLeftArmEffect;
|
||||
HPARTICLEFFECT m_hBuildingRightArmEffect;
|
||||
|
||||
CSoundPatch *m_pSpinSound;
|
||||
|
||||
private:
|
||||
C_ObjectTeleporter( const C_ObjectTeleporter & ); // not defined, not accessible
|
||||
};
|
||||
|
||||
#endif //C_OBJ_TELEPORTER_H
|
||||
@@ -0,0 +1,137 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose: A clientside, visual only model that's attached to players
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
#include "cbase.h"
|
||||
#include "c_playerattachedmodel.h"
|
||||
|
||||
// Todo: Turn these all into parameters
|
||||
#define PAM_ANIMATE_TIME 0.075
|
||||
#define PAM_ROTATE_TIME 0.075
|
||||
|
||||
#define PAM_SCALE_SPEED 7
|
||||
#define PAM_MAX_SCALE 3
|
||||
#define PAM_SPIN_SPEED 360
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
C_PlayerAttachedModel *C_PlayerAttachedModel::Create( const char *pszModelName, C_BaseEntity *pParent, int iAttachment, Vector vecOffset, float flLifetime, int iFlags )
|
||||
{
|
||||
C_PlayerAttachedModel *pFlash = new C_PlayerAttachedModel;
|
||||
if ( !pFlash )
|
||||
return NULL;
|
||||
|
||||
if ( !pFlash->Initialize( pszModelName, pParent, iAttachment, vecOffset, flLifetime, iFlags ) )
|
||||
return NULL;
|
||||
|
||||
return pFlash;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
bool C_PlayerAttachedModel::Initialize( const char *pszModelName, C_BaseEntity *pParent, int iAttachment, Vector vecOffset, float flLifetime, int iFlags )
|
||||
{
|
||||
AddEffects( EF_NORECEIVESHADOW | EF_NOSHADOW );
|
||||
if ( InitializeAsClientEntity( pszModelName, RENDER_GROUP_OPAQUE_ENTITY ) == false )
|
||||
{
|
||||
Release();
|
||||
return false;
|
||||
}
|
||||
|
||||
SetParent( pParent, iAttachment );
|
||||
SetLocalOrigin( vecOffset );
|
||||
SetLocalAngles( vec3_angle );
|
||||
|
||||
AddSolidFlags( FSOLID_NOT_SOLID );
|
||||
|
||||
SetLifetime( flLifetime );
|
||||
SetNextClientThink( CLIENT_THINK_ALWAYS );
|
||||
|
||||
SetCycle( 0 );
|
||||
|
||||
m_iFlags = iFlags;
|
||||
m_flScale = 0;
|
||||
|
||||
if ( m_iFlags & PAM_ROTATE_RANDOMLY )
|
||||
{
|
||||
m_flRotateAt = gpGlobals->curtime + PAM_ANIMATE_TIME;
|
||||
}
|
||||
if ( m_iFlags & PAM_ANIMATE_RANDOMLY )
|
||||
{
|
||||
m_flAnimateAt = gpGlobals->curtime + PAM_ROTATE_TIME;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void C_PlayerAttachedModel::SetLifetime( float flLifetime )
|
||||
{
|
||||
if ( flLifetime == PAM_PERMANENT )
|
||||
{
|
||||
m_flExpiresAt = PAM_PERMANENT;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Expire when the lifetime is up
|
||||
m_flExpiresAt = gpGlobals->curtime + flLifetime;
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void C_PlayerAttachedModel::ClientThink( void )
|
||||
{
|
||||
if ( !GetMoveParent() || (m_flExpiresAt != PAM_PERMANENT && gpGlobals->curtime > m_flExpiresAt) )
|
||||
{
|
||||
Release();
|
||||
return;
|
||||
}
|
||||
|
||||
if ( m_iFlags & PAM_ANIMATE_RANDOMLY && gpGlobals->curtime > m_flAnimateAt )
|
||||
{
|
||||
float flDelta = RandomFloat(0.2,0.4) * (RandomInt(0,1) == 1 ? 1 : -1);
|
||||
float flCycle = clamp( GetCycle() + flDelta, 0.f, 1.f );
|
||||
SetCycle( flCycle );
|
||||
m_flAnimateAt = gpGlobals->curtime + PAM_ANIMATE_TIME;
|
||||
}
|
||||
|
||||
if ( m_iFlags & PAM_ROTATE_RANDOMLY && gpGlobals->curtime > m_flRotateAt )
|
||||
{
|
||||
SetLocalAngles( QAngle(0,0,RandomFloat(0,360)) );
|
||||
m_flRotateAt = gpGlobals->curtime + PAM_ROTATE_TIME;
|
||||
}
|
||||
|
||||
if ( m_iFlags & PAM_SPIN_Z )
|
||||
{
|
||||
float flAng = GetAbsAngles().y + (gpGlobals->frametime * PAM_SPIN_SPEED);
|
||||
SetLocalAngles( QAngle(0,flAng,0) );
|
||||
}
|
||||
|
||||
if ( m_iFlags & PAM_SCALEUP )
|
||||
{
|
||||
m_flScale = MIN( m_flScale + (gpGlobals->frametime * PAM_SCALE_SPEED), PAM_MAX_SCALE );
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void C_PlayerAttachedModel::ApplyBoneMatrixTransform( matrix3x4_t& transform )
|
||||
{
|
||||
BaseClass::ApplyBoneMatrixTransform( transform );
|
||||
|
||||
if ( !(m_iFlags & PAM_SCALEUP) )
|
||||
return;
|
||||
|
||||
VectorScale( transform[0], m_flScale, transform[0] );
|
||||
VectorScale( transform[1], m_flScale, transform[1] );
|
||||
VectorScale( transform[2], m_flScale, transform[2] );
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
#ifndef C_PLAYERATTACHEDMODEL_H
|
||||
#define C_PLAYERATTACHEDMODEL_H
|
||||
#ifdef _WIN32
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#define PAM_PERMANENT -1
|
||||
|
||||
// Flags
|
||||
#define PAM_SPIN_Z (1<<0)
|
||||
#define PAM_ROTATE_RANDOMLY (1<<1)
|
||||
#define PAM_SCALEUP (1<<2)
|
||||
#define PAM_ANIMATE_RANDOMLY (1<<3)
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: A clientside, visual only model that's attached to players
|
||||
//-----------------------------------------------------------------------------
|
||||
class C_PlayerAttachedModel : public C_BaseAnimating
|
||||
{
|
||||
DECLARE_CLASS( C_PlayerAttachedModel, C_BaseAnimating );
|
||||
public:
|
||||
static C_PlayerAttachedModel *Create( const char *pszModelName, C_BaseEntity *pParent, int iAttachment, Vector vecOffset, float flLifetime = 0.2, int iFlags = 0 );
|
||||
|
||||
bool Initialize( const char *pszModelName, C_BaseEntity *pParent, int iAttachment, Vector vecOffset, float flLifetime, int iFlags );
|
||||
void SetLifetime( float flLifetime );
|
||||
void ClientThink( void );
|
||||
void ApplyBoneMatrixTransform( matrix3x4_t& transform );
|
||||
|
||||
private:
|
||||
float m_flExpiresAt;
|
||||
int m_iFlags;
|
||||
float m_flRotateAt;
|
||||
float m_flAnimateAt;
|
||||
float m_flScale;
|
||||
};
|
||||
|
||||
#endif // C_PLAYERATTACHEDMODEL_H
|
||||
@@ -0,0 +1,164 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose: A clientside, visual only model that's positioned relative to players
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
#include "cbase.h"
|
||||
#include "c_playerrelativemodel.h"
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
C_PlayerRelativeModel *C_PlayerRelativeModel::Create( const char *pszModelName, C_BaseEntity *pParent, Vector vecOffset, QAngle angleOffset, float flAnimSpeed, float flLifetime, int iFlags )
|
||||
{
|
||||
C_PlayerRelativeModel *pFlash = new C_PlayerRelativeModel;
|
||||
if ( !pFlash )
|
||||
return NULL;
|
||||
|
||||
if ( !pFlash->Initialize( pszModelName, pParent, vecOffset, angleOffset, flAnimSpeed, flLifetime, iFlags ) )
|
||||
return NULL;
|
||||
|
||||
return pFlash;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
bool C_PlayerRelativeModel::Initialize( const char *pszModelName, C_BaseEntity *pParent, Vector vecOffset, QAngle angleOffset, float flAnimSpeed, float flLifetime, int iFlags )
|
||||
{
|
||||
AddEffects( EF_NORECEIVESHADOW | EF_NOSHADOW );
|
||||
if ( InitializeAsClientEntity( pszModelName, RENDER_GROUP_OPAQUE_ENTITY ) == false )
|
||||
{
|
||||
Release();
|
||||
return false;
|
||||
}
|
||||
|
||||
m_vecOffsetPos = vecOffset;
|
||||
m_angleOffset = angleOffset;
|
||||
|
||||
SetParent( pParent, 0 );
|
||||
SetLocalOrigin( vec3_origin );
|
||||
SetLocalAngles( vec3_angle );
|
||||
|
||||
AddSolidFlags( FSOLID_NOT_SOLID );
|
||||
|
||||
SetLifetime( flLifetime );
|
||||
SetNextClientThink( CLIENT_THINK_ALWAYS );
|
||||
|
||||
SetCycle( 0 );
|
||||
|
||||
m_qOffsetRotation = vec3_angle;
|
||||
m_flAnimSpeed = flAnimSpeed;
|
||||
|
||||
m_iFlags = iFlags;
|
||||
return true;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void C_PlayerRelativeModel::SetLifetime( float flLifetime )
|
||||
{
|
||||
if ( flLifetime == PRM_PERMANENT )
|
||||
{
|
||||
m_flExpiresAt = PRM_PERMANENT;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Expire when the lifetime is up
|
||||
m_flExpiresAt = gpGlobals->curtime + flLifetime;
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void C_PlayerRelativeModel::ClientThink( void )
|
||||
{
|
||||
if ( !GetMoveParent() || (m_flExpiresAt != PRM_PERMANENT && gpGlobals->curtime > m_flExpiresAt) )
|
||||
{
|
||||
Release();
|
||||
return;
|
||||
}
|
||||
|
||||
// Animate
|
||||
C_BaseEntity *pParent = GetMoveParent();
|
||||
|
||||
Vector out(0, 0, 0);
|
||||
if ( m_iFlags & PRM_SPIN_Z )
|
||||
{
|
||||
m_qOffsetRotation += QAngle(0, gpGlobals->frametime * m_flAnimSpeed, 0);
|
||||
VectorRotate( m_vecOffsetPos, m_qOffsetRotation, out );
|
||||
}
|
||||
|
||||
SetAbsOrigin( pParent->GetAbsOrigin() + out );
|
||||
SetAbsAngles( m_qOffsetRotation + m_angleOffset );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// C_MerasmusBombEffect
|
||||
//-----------------------------------------------------------------------------
|
||||
C_MerasmusBombEffect *C_MerasmusBombEffect::Create( const char *pszModelName, C_TFPlayer *pParent, Vector vecOffset, QAngle angleOffset, float flAnimSpeed, float flLifetime, int iFlags )
|
||||
{
|
||||
C_MerasmusBombEffect *pFlash = new C_MerasmusBombEffect;
|
||||
if ( !pFlash )
|
||||
return NULL;
|
||||
|
||||
if ( !pFlash->Initialize( pszModelName, pParent, vecOffset, angleOffset, flAnimSpeed, flLifetime, iFlags ) )
|
||||
return NULL;
|
||||
|
||||
return pFlash;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
bool C_MerasmusBombEffect::Initialize( const char *pszModelName, C_TFPlayer *pParent, Vector vecOffset, QAngle angleOffset, float flAnimSpeed, float flLifetime, int iFlags )
|
||||
{
|
||||
if ( !BaseClass::Initialize(pszModelName, pParent, vecOffset, angleOffset, flAnimSpeed, flLifetime, iFlags ) )
|
||||
return false;
|
||||
|
||||
// Create a particle effect
|
||||
const char *pszEffectName = "bombonomicon_spell_trail";
|
||||
|
||||
if ( m_pBombonomiconBeam )
|
||||
{
|
||||
m_pBombonomiconBeam->StopEmission();
|
||||
m_pBombonomiconBeam = NULL;
|
||||
}
|
||||
|
||||
if ( m_pBombonomiconEffect )
|
||||
{
|
||||
m_pBombonomiconEffect->StopEmission();
|
||||
m_pBombonomiconEffect = NULL;
|
||||
}
|
||||
|
||||
m_pBombonomiconBeam = ParticleProp()->Create( pszEffectName, PATTACH_ABSORIGIN_FOLLOW, INVALID_PARTICLE_ATTACHMENT, Vector(0,0,-10) );
|
||||
if ( m_pBombonomiconBeam )
|
||||
{
|
||||
ParticleProp()->AddControlPoint( m_pBombonomiconBeam, 1, pParent, PATTACH_POINT_FOLLOW, "head", Vector(0,0,0) );
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
void C_MerasmusBombEffect::ClientThink( void )
|
||||
{
|
||||
if ( !GetMoveParent() || (m_flExpiresAt != PRM_PERMANENT && gpGlobals->curtime > m_flExpiresAt) )
|
||||
{
|
||||
if ( m_pBombonomiconBeam )
|
||||
{
|
||||
m_pBombonomiconBeam->StopEmission();
|
||||
m_pBombonomiconBeam = NULL;
|
||||
}
|
||||
|
||||
if ( m_pBombonomiconEffect )
|
||||
{
|
||||
m_pBombonomiconEffect->StopEmission();
|
||||
m_pBombonomiconEffect = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
BaseClass::ClientThink();
|
||||
}
|
||||
@@ -0,0 +1,64 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
#ifndef C_PLAYERRELATIVEMODEL_H
|
||||
#define C_PLAYERRELATIVEMODEL_H
|
||||
#ifdef _WIN32
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include "c_tf_player.h"
|
||||
|
||||
#define PRM_PERMANENT -1
|
||||
|
||||
//
|
||||
// Flags
|
||||
#define PRM_SPIN_Z (1<<0)
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: A clientside, visual only model that's positioned relative to players
|
||||
//-----------------------------------------------------------------------------
|
||||
class C_PlayerRelativeModel : public C_BaseAnimating
|
||||
{
|
||||
DECLARE_CLASS( C_PlayerRelativeModel, C_BaseAnimating );
|
||||
public:
|
||||
static C_PlayerRelativeModel *Create( const char *pszModelName, C_BaseEntity *pParent, Vector vecOffset, QAngle angleOffset, float flAnimSpeed, float flLifetime = 0.2, int iFlags = 0 );
|
||||
|
||||
bool Initialize( const char *pszModelName, C_BaseEntity *pParent, Vector vecOffset, QAngle angleOffset, float flAnimSpeed, float flLifetime, int iFlags );
|
||||
void SetLifetime( float flLifetime );
|
||||
void ClientThink( void );
|
||||
|
||||
protected:
|
||||
float m_flExpiresAt;
|
||||
int m_iFlags;
|
||||
private:
|
||||
float m_flRotateAt;
|
||||
float m_flAnimateAt;
|
||||
float m_flScale;
|
||||
|
||||
Vector m_vecOffsetPos;
|
||||
QAngle m_angleOffset;
|
||||
|
||||
QAngle m_qOffsetRotation;
|
||||
float m_flAnimSpeed;
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: A clientside, visual only model that's positioned relative to players
|
||||
//-----------------------------------------------------------------------------
|
||||
class C_MerasmusBombEffect : public C_PlayerRelativeModel
|
||||
{
|
||||
DECLARE_CLASS( C_MerasmusBombEffect, C_PlayerRelativeModel );
|
||||
public:
|
||||
static C_MerasmusBombEffect *Create( const char *pszModelName, C_TFPlayer *pParent, Vector vecOffset, QAngle angleOffset, float flAnimSpeed, float flLifetime = 0.2, int iFlags = 0 );
|
||||
|
||||
bool Initialize( const char *pszModelName, C_TFPlayer *pParent, Vector vecOffset, QAngle angleOffset, float flAnimSpeed, float flLifetime, int iFlags );
|
||||
void ClientThink( void );
|
||||
private:
|
||||
CNewParticleEffect *m_pBombonomiconBeam;
|
||||
CNewParticleEffect *m_pBombonomiconEffect;
|
||||
};
|
||||
#endif // C_PLAYERRELATIVEMODEL_H
|
||||
@@ -0,0 +1,145 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
//=============================================================================//
|
||||
#include "cbase.h"
|
||||
#include "c_tf_ammo_pack.h"
|
||||
|
||||
// memdbgon must be the last include file in a .cpp file!!!
|
||||
#include "tier0/memdbgon.h"
|
||||
|
||||
#ifdef _DEBUG
|
||||
static ConVar tf_debug_weapontrail( "tf_debug_weapontrail", "0", FCVAR_CHEAT | FCVAR_DEVELOPMENTONLY );
|
||||
#endif // _DEBUG
|
||||
|
||||
// Network table.
|
||||
IMPLEMENT_CLIENTCLASS_DT( C_TFAmmoPack, DT_AmmoPack, CTFAmmoPack )
|
||||
RecvPropVector( RECVINFO( m_vecInitialVelocity ) ),
|
||||
RecvPropFloat( RECVINFO_NAME( m_angNetworkAngles[0], m_angRotation[0] ) ),
|
||||
RecvPropFloat( RECVINFO_NAME( m_angNetworkAngles[1], m_angRotation[1] ) ),
|
||||
RecvPropFloat( RECVINFO_NAME( m_angNetworkAngles[2], m_angRotation[2] ) ),
|
||||
END_RECV_TABLE()
|
||||
|
||||
|
||||
C_TFAmmoPack::C_TFAmmoPack( void )
|
||||
{
|
||||
m_nWorldModelIndex = 0;
|
||||
}
|
||||
|
||||
C_TFAmmoPack::~C_TFAmmoPack( void )
|
||||
{
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
// Input : flags -
|
||||
// Output : int
|
||||
//-----------------------------------------------------------------------------
|
||||
int C_TFAmmoPack::DrawModel( int flags )
|
||||
{
|
||||
#ifdef _DEBUG
|
||||
// Debug!
|
||||
if ( tf_debug_weapontrail.GetBool() )
|
||||
{
|
||||
Msg( "Ammo Pack:: Position: (%f %f %f), Velocity (%f %f %f)\n", GetAbsOrigin().x, GetAbsOrigin().y, GetAbsOrigin().z, GetAbsVelocity().x, GetAbsVelocity().y, GetAbsVelocity().z );
|
||||
if ( debugoverlay )
|
||||
{
|
||||
debugoverlay->AddBoxOverlay( GetAbsOrigin(), Vector( -2, -2, -2 ), Vector( 2, 2, 2 ), QAngle( 0, 0, 0 ), 255, 255, 0, 32, 5.0 );
|
||||
}
|
||||
}
|
||||
#endif // _DEBUG
|
||||
|
||||
return BaseClass::DrawModel( flags );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
// Input : updateType -
|
||||
//-----------------------------------------------------------------------------
|
||||
void C_TFAmmoPack::OnDataChanged( DataUpdateType_t updateType )
|
||||
{
|
||||
BaseClass::OnDataChanged( updateType );
|
||||
|
||||
#ifdef _DEBUG
|
||||
// Debug!
|
||||
if ( tf_debug_weapontrail.GetBool() )
|
||||
{
|
||||
Msg( "AbsOrigin (%f %f %f), LocalOrigin(%f %f %f)\n", GetAbsOrigin().x, GetAbsOrigin().y, GetAbsOrigin().z, GetLocalOrigin().x, GetLocalOrigin().y, GetLocalOrigin().z );
|
||||
}
|
||||
#endif // _DEBUG
|
||||
|
||||
if ( updateType == DATA_UPDATE_CREATED )
|
||||
{
|
||||
#ifdef _DEBUG
|
||||
// Debug!
|
||||
if ( tf_debug_weapontrail.GetBool() )
|
||||
{
|
||||
Msg( "Origin (%f %f %f)\n", GetAbsOrigin().x, GetAbsOrigin().y, GetAbsOrigin().z );
|
||||
}
|
||||
#endif // _DEBUG
|
||||
|
||||
float flChangeTime = GetLastChangeTime( LATCH_SIMULATION_VAR );
|
||||
Vector vecCurOrigin = GetLocalOrigin();
|
||||
|
||||
// Now stick our initial velocity into the interpolation history
|
||||
CInterpolatedVar< Vector > &interpolator = GetOriginInterpolator();
|
||||
interpolator.ClearHistory();
|
||||
interpolator.AddToHead( flChangeTime - 0.15f, &vecCurOrigin, false );
|
||||
|
||||
m_nWorldModelIndex = m_nModelIndex;
|
||||
}
|
||||
}
|
||||
|
||||
int C_TFAmmoPack::GetWorldModelIndex( void )
|
||||
{
|
||||
if ( m_nWorldModelIndex == 0 )
|
||||
return m_nModelIndex;
|
||||
|
||||
if ( GameRules() )
|
||||
{
|
||||
const char *pBaseName = modelinfo->GetModelName( modelinfo->GetModel( m_nWorldModelIndex ) );
|
||||
const char *pTranslatedName = GameRules()->TranslateEffectForVisionFilter( "weapons", pBaseName );
|
||||
|
||||
if ( pTranslatedName != pBaseName )
|
||||
{
|
||||
return modelinfo->GetModelIndex( pTranslatedName );
|
||||
}
|
||||
}
|
||||
|
||||
return m_nWorldModelIndex;
|
||||
}
|
||||
|
||||
void C_TFAmmoPack::ValidateModelIndex( void )
|
||||
{
|
||||
m_nModelIndex = GetWorldModelIndex();
|
||||
|
||||
BaseClass::ValidateModelIndex();
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
// Input : currentTime -
|
||||
// Output : Returns true on success, false on failure.
|
||||
//-----------------------------------------------------------------------------
|
||||
bool C_TFAmmoPack::Interpolate( float currentTime )
|
||||
{
|
||||
return BaseClass::Interpolate( currentTime );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
// Input : *pPlayer -
|
||||
//-----------------------------------------------------------------------------
|
||||
void C_TFAmmoPack::DisplayHintTo( C_BasePlayer *pPlayer )
|
||||
{
|
||||
C_TFPlayer *pTFPlayer = ToTFPlayer(pPlayer);
|
||||
if ( pTFPlayer->IsPlayerClass( TF_CLASS_ENGINEER ) )
|
||||
{
|
||||
pTFPlayer->HintMessage( HINT_ENGINEER_PICKUP_METAL );
|
||||
}
|
||||
else
|
||||
{
|
||||
pTFPlayer->HintMessage( HINT_PICKUP_AMMO );
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
//=============================================================================//
|
||||
|
||||
#ifndef C_TF_AMMO_PACK_H
|
||||
#define C_TF_AMMO_PACK_H
|
||||
#ifdef _WIN32
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include "c_baseanimating.h"
|
||||
#include "engine/ivdebugoverlay.h"
|
||||
#include "c_tf_player.h"
|
||||
#include "engine/IEngineSound.h"
|
||||
#include "soundenvelope.h"
|
||||
|
||||
// memdbgon must be the last include file in a .cpp file!!!
|
||||
#include "tier0/memdbgon.h"
|
||||
|
||||
class C_TFAmmoPack : public C_BaseAnimating, public ITargetIDProvidesHint
|
||||
{
|
||||
DECLARE_CLASS( C_TFAmmoPack, C_BaseAnimating );
|
||||
|
||||
public:
|
||||
|
||||
DECLARE_CLIENTCLASS();
|
||||
|
||||
C_TFAmmoPack( void );
|
||||
~C_TFAmmoPack( void );
|
||||
|
||||
virtual int DrawModel( int flags );
|
||||
virtual void OnDataChanged( DataUpdateType_t updateType );
|
||||
virtual int GetWorldModelIndex( void );
|
||||
virtual void ValidateModelIndex( void );
|
||||
virtual bool Interpolate( float currentTime );
|
||||
|
||||
// ITargetIDProvidesHint
|
||||
public:
|
||||
virtual void DisplayHintTo( C_BasePlayer *pPlayer );
|
||||
|
||||
private:
|
||||
|
||||
Vector m_vecInitialVelocity;
|
||||
short m_nWorldModelIndex;
|
||||
};
|
||||
|
||||
#endif // C_TF_AMMO_PACK_H
|
||||
@@ -0,0 +1,98 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
#include "cbase.h"
|
||||
#include "c_tf_buff_banner.h"
|
||||
#include "c_tf_player.h"
|
||||
|
||||
// memdbgon must be the last include file in a .cpp file!!!
|
||||
#include "tier0/memdbgon.h"
|
||||
|
||||
IMPLEMENT_NETWORKCLASS_ALIASED( TFBuffBanner, DT_TFBuffBanner )
|
||||
|
||||
BEGIN_NETWORK_TABLE( C_TFBuffBanner, DT_TFBuffBanner )
|
||||
END_NETWORK_TABLE()
|
||||
|
||||
|
||||
C_TFBuffBanner::C_TFBuffBanner()
|
||||
{
|
||||
m_flDetachTime = 0.f;
|
||||
m_iBuffType = 0;
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
// -----------------------------------------------------------------------------
|
||||
void CTFBuffBanner::NotifyBoneAttached( C_BaseAnimating* attachTarget )
|
||||
{
|
||||
if ( m_hBuffItem )
|
||||
{
|
||||
if ( attachTarget != m_hBuffItem->GetOwner() )
|
||||
{
|
||||
// We are being moved to a corpse. Let our associated buff item know.
|
||||
m_hBuffItem->SetBanner( NULL );
|
||||
}
|
||||
else
|
||||
{
|
||||
float flDuration = 10.f; // 10 is default
|
||||
CALL_ATTRIB_HOOK_FLOAT_ON_OTHER( attachTarget, flDuration, mod_buff_duration );
|
||||
m_flDetachTime = gpGlobals->curtime + flDuration;
|
||||
|
||||
SetNextClientThink( CLIENT_THINK_ALWAYS );
|
||||
}
|
||||
}
|
||||
|
||||
BaseClass::NotifyBoneAttached( attachTarget );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void CTFBuffBanner::ClientThink( void )
|
||||
{
|
||||
BaseClass::ClientThink();
|
||||
|
||||
// DO THIS AFTER BASECLASS::CLIENTTHINK
|
||||
if ( !m_pAttachedTo || !m_hBuffItem )
|
||||
{
|
||||
if ( m_hBuffItem )
|
||||
{
|
||||
m_hBuffItem->SetBanner( NULL );
|
||||
}
|
||||
Release();
|
||||
return;
|
||||
}
|
||||
|
||||
// Parachute's never expire
|
||||
if ( m_iBuffType == EParachute )
|
||||
{
|
||||
m_flDetachTime = gpGlobals->curtime + 10.0f;
|
||||
}
|
||||
|
||||
// Normal Banners
|
||||
if ( m_pAttachedTo )
|
||||
{
|
||||
if ( gpGlobals->curtime > m_flDetachTime || !m_hBuffItem )
|
||||
{
|
||||
// Destroy us automatically after a period of time.
|
||||
if ( m_hBuffItem )
|
||||
{
|
||||
m_hBuffItem->SetBanner( NULL );
|
||||
}
|
||||
Release();
|
||||
}
|
||||
else if ( m_pAttachedTo->IsEffectActive( EF_NODRAW ) && !IsEffectActive( EF_NODRAW ) )
|
||||
{
|
||||
AddEffects( EF_NODRAW );
|
||||
UpdateVisibility();
|
||||
}
|
||||
else if ( !m_pAttachedTo->IsEffectActive( EF_NODRAW ) && IsEffectActive( EF_NODRAW ) && (m_pAttachedTo != C_BasePlayer::GetLocalPlayer()) )
|
||||
{
|
||||
RemoveEffects( EF_NODRAW );
|
||||
UpdateVisibility();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
#ifndef C_TF_BUFF_BANNER_H
|
||||
#define C_TF_BUFF_BANNER_H
|
||||
#ifdef _WIN32
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include "tf_weapon_buff_item.h"
|
||||
|
||||
#define CTFBuffBanner C_TFBuffBanner
|
||||
|
||||
class C_TFBuffItem;
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: These need some base class derived from base animating that handles stuff like clientthink.
|
||||
//-----------------------------------------------------------------------------
|
||||
class C_TFBuffBanner : public CBaseAnimating
|
||||
{
|
||||
DECLARE_CLASS( C_TFBuffBanner, CBaseAnimating );
|
||||
|
||||
public:
|
||||
|
||||
DECLARE_NETWORKCLASS();
|
||||
|
||||
C_TFBuffBanner();
|
||||
~C_TFBuffBanner() {}
|
||||
|
||||
void SetBuffItem( C_TFBuffItem* newBuffItem ) { m_hBuffItem = newBuffItem; }
|
||||
|
||||
virtual void NotifyBoneAttached( C_BaseAnimating* attachTarget );
|
||||
|
||||
virtual void ClientThink( void );
|
||||
|
||||
void SetBuffType( int iBuffType ) { m_iBuffType = iBuffType; }
|
||||
private:
|
||||
|
||||
float m_flDetachTime;
|
||||
int m_iBuffType;
|
||||
CHandle<C_TFBuffItem> m_hBuffItem;
|
||||
};
|
||||
|
||||
#endif // C_TF_BUFF_BANNER_H
|
||||
@@ -0,0 +1,109 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose: TF Death Calling card version based off the stickybolt code.
|
||||
//=============================================================================//
|
||||
#include "cbase.h"
|
||||
#include "c_basetempentity.h"
|
||||
#include "fx.h"
|
||||
#include "decals.h"
|
||||
#include "iefx.h"
|
||||
#include "engine/IEngineSound.h"
|
||||
#include "materialsystem/imaterialvar.h"
|
||||
#include "IEffects.h"
|
||||
#include "engine/IEngineTrace.h"
|
||||
#include "vphysics/constraints.h"
|
||||
#include "engine/ivmodelinfo.h"
|
||||
#include "tempent.h"
|
||||
#include "c_te_legacytempents.h"
|
||||
#include "engine/ivdebugoverlay.h"
|
||||
#include "c_te_effect_dispatch.h"
|
||||
#include "c_tf_player.h"
|
||||
#include "GameEventListener.h"
|
||||
#include "tf_shareddefs.h"
|
||||
|
||||
// memdbgon must be the last include file in a .cpp file!!!
|
||||
#include "tier0/memdbgon.h"
|
||||
|
||||
extern IPhysicsSurfaceProps *physprops;
|
||||
IPhysicsObject *GetWorldPhysObject( void );
|
||||
|
||||
extern CBaseEntity *BreakModelCreateSingle( CBaseEntity *pOwner, breakmodel_t *pModel, const Vector &position,
|
||||
const QAngle &angles, const Vector &velocity, const AngularImpulse &angVelocity, int nSkin, const breakablepropparams_t ¶ms );
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Creates a "Calling Card" prop at the victim's location
|
||||
//-----------------------------------------------------------------------------
|
||||
void CreateDeathCallingCard(
|
||||
const Vector &vecOrigin,
|
||||
const QAngle &vAngle,
|
||||
const int iVictimIndex,
|
||||
const int iShooterIndex,
|
||||
const int iCallingCardIndex
|
||||
) {
|
||||
if ( iCallingCardIndex < 1 || iCallingCardIndex > TF_CALLING_CARD_MODEL_COUNT )
|
||||
{
|
||||
Warning( "Attempted to Call CreateDeathCallingCard With invalid index %d", iCallingCardIndex );
|
||||
return;
|
||||
}
|
||||
|
||||
const char* pszModelName = g_pszDeathCallingCardModels[iCallingCardIndex];
|
||||
|
||||
CTFPlayer *pVictim = ToTFPlayer( UTIL_PlayerByIndex( iVictimIndex ) );
|
||||
if ( !pVictim )
|
||||
return;
|
||||
|
||||
breakablepropparams_t breakParams( vecOrigin, vAngle, vec3_origin, vec3_origin );
|
||||
breakParams.impactEnergyScale = 1.0f;
|
||||
|
||||
breakmodel_t breakModel;
|
||||
Q_strncpy( breakModel.modelName, pszModelName, sizeof(breakModel.modelName) );
|
||||
|
||||
breakModel.health = 1;
|
||||
breakModel.fadeTime = RandomFloat(7,10);
|
||||
breakModel.fadeMinDist = 0.0f;
|
||||
breakModel.fadeMaxDist = 0.0f;
|
||||
breakModel.burstScale = 1.0f;
|
||||
breakModel.collisionGroup = COLLISION_GROUP_DEBRIS;
|
||||
breakModel.isRagdoll = false;
|
||||
breakModel.isMotionDisabled = false;
|
||||
breakModel.placementName[0] = 0;
|
||||
breakModel.placementIsBone = false;
|
||||
breakModel.offset = Vector( 0, 0, 50 );
|
||||
|
||||
CBaseEntity * pBreakModel = BreakModelCreateSingle(
|
||||
pVictim,
|
||||
&breakModel,
|
||||
pVictim->GetAbsOrigin() + Vector( 0, 0, 50 ),
|
||||
QAngle(0, vAngle.y, 0 ),
|
||||
vec3_origin,
|
||||
vec3_origin,
|
||||
0,
|
||||
breakParams
|
||||
);
|
||||
|
||||
// Scale down the tombstones a bit
|
||||
if ( pBreakModel )
|
||||
{
|
||||
CBaseAnimating *pAnim = dynamic_cast < CBaseAnimating * > ( pBreakModel );
|
||||
if ( pAnim )
|
||||
{
|
||||
pAnim->SetModelScale( 0.9f );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void DeathCallingCard( const CEffectData &data )
|
||||
{
|
||||
CreateDeathCallingCard(
|
||||
data.m_vOrigin,
|
||||
data.m_vAngles,
|
||||
data.m_nAttachmentIndex, // Victim
|
||||
data.m_nHitBox, // iShooter
|
||||
data.m_fFlags // Calling card Index
|
||||
);
|
||||
}
|
||||
|
||||
DECLARE_CLIENT_EFFECT( "TFDeathCallingCard", DeathCallingCard );
|
||||
@@ -0,0 +1,388 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================//
|
||||
|
||||
#include "cbase.h"
|
||||
|
||||
#include "c_tf_freeaccount.h"
|
||||
|
||||
#include "gcsdk/sharedobjectcache.h"
|
||||
#include "tf_gcmessages.h"
|
||||
#include "econ_game_account_client.h"
|
||||
#include "tf_item_inventory.h"
|
||||
#include "tf_player_info.h"
|
||||
|
||||
#include <vgui/ILocalize.h>
|
||||
#include "confirm_dialog.h"
|
||||
#include "econ/econ_notifications.h"
|
||||
#include "select_player_dialog.h"
|
||||
|
||||
#include "gc_clientsystem.h"
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
class CSelectMostHelpfulFriendDialog : public CSelectPlayerDialog
|
||||
{
|
||||
public:
|
||||
CSelectMostHelpfulFriendDialog( vgui::Panel *parent )
|
||||
: CSelectPlayerDialog( parent )
|
||||
, m_iNumFriends( 0 )
|
||||
, m_bRefreshing( false )
|
||||
{
|
||||
}
|
||||
|
||||
virtual void UpdatePlayerList()
|
||||
{
|
||||
CSelectPlayerDialog::UpdatePlayerList();
|
||||
|
||||
vgui::Label *pLabelEmpty = dynamic_cast<vgui::Label*>( m_pStatePanels[m_iCurrentState]->FindChildByName("EmptyPlayerListLabel") );
|
||||
vgui::Label *pLabelQuery = dynamic_cast<vgui::Label*>( m_pStatePanels[m_iCurrentState]->FindChildByName("QueryLabel") );
|
||||
vgui::Label *pLabelRetrieving = dynamic_cast<vgui::Label*>( m_pStatePanels[m_iCurrentState]->FindChildByName("RetrievingPlayerListLabel") );
|
||||
|
||||
if ( pLabelEmpty )
|
||||
{
|
||||
pLabelEmpty->SetVisible( m_bRefreshing == false && pLabelEmpty->IsVisible() );
|
||||
}
|
||||
if ( pLabelQuery )
|
||||
{
|
||||
pLabelQuery->SetVisible( m_bRefreshing == false && pLabelQuery->IsVisible() );
|
||||
}
|
||||
if ( pLabelRetrieving )
|
||||
{
|
||||
pLabelRetrieving->SetVisible( m_bRefreshing );
|
||||
}
|
||||
}
|
||||
|
||||
virtual void Reset()
|
||||
{
|
||||
CSelectPlayerDialog::Reset();
|
||||
m_iNumFriends = 0;
|
||||
if ( m_bRefreshing == false )
|
||||
{
|
||||
RequestFriendsFromGC();
|
||||
}
|
||||
}
|
||||
|
||||
virtual void SetupSelectFriends()
|
||||
{
|
||||
m_PlayerInfoList.Purge();
|
||||
|
||||
if ( steamapicontext && steamapicontext->SteamFriends() )
|
||||
{
|
||||
// Get our game info so we can use that to test if our friends are connected to the same game as us
|
||||
FriendGameInfo_t myGameInfo;
|
||||
CSteamID mySteamID = steamapicontext->SteamUser()->GetSteamID();
|
||||
steamapicontext->SteamFriends()->GetFriendGamePlayed( mySteamID, &myGameInfo );
|
||||
|
||||
int iFriends = steamapicontext->SteamFriends()->GetFriendCount( k_EFriendFlagImmediate );
|
||||
if ( m_iNumFriends != iFriends )
|
||||
{
|
||||
RequestFriendsFromGC();
|
||||
}
|
||||
else
|
||||
{
|
||||
m_PlayerInfoList = m_FriendsWhoOwnTF2;
|
||||
}
|
||||
}
|
||||
|
||||
UpdatePlayerList();
|
||||
}
|
||||
|
||||
virtual void OnSelectPlayer( const CSteamID &steamID )
|
||||
{
|
||||
GCSDK::CProtoBufMsg<CMsgTFFreeTrialChooseMostHelpfulFriend> msg( k_EMsgGCFreeTrial_ChooseMostHelpfulFriend );
|
||||
msg.Body().set_account_id_friend( steamID.GetAccountID() );
|
||||
GCClientSystem()->BSendMessage( msg );
|
||||
}
|
||||
|
||||
void OnTF2FriendsReceived( GCSDK::CProtoBufMsg<CMsgTFRequestTF2FriendsResponse> &msg )
|
||||
{
|
||||
// populate the list of friends who own TF2
|
||||
m_bRefreshing = false;
|
||||
m_FriendsWhoOwnTF2.Purge();
|
||||
for ( int i = 0; i < msg.Body().account_ids_size(); ++i )
|
||||
{
|
||||
uint32 unAccountID = msg.Body().account_ids( i );
|
||||
FOR_EACH_VEC( m_EntireFriendsList, j )
|
||||
{
|
||||
partner_info_t &info = m_EntireFriendsList[j];
|
||||
if ( info.m_steamID.GetAccountID() == unAccountID )
|
||||
{
|
||||
int idx = m_FriendsWhoOwnTF2.AddToTail();
|
||||
partner_info_t &infoCopy = m_FriendsWhoOwnTF2[idx];
|
||||
infoCopy = info;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// update UI
|
||||
if ( m_iCurrentState == SPDS_SELECTING_FROM_FRIENDS )
|
||||
{
|
||||
m_PlayerInfoList = m_FriendsWhoOwnTF2;
|
||||
UpdatePlayerList();
|
||||
}
|
||||
}
|
||||
|
||||
protected:
|
||||
virtual const char *GetResFile() { return "resource/ui/SelectMostHelpfulFriendDialog.res"; }
|
||||
|
||||
void RequestFriendsFromGC()
|
||||
{
|
||||
// send a message to the GC requesting that it validate which friends own TF2
|
||||
m_bRefreshing = true;
|
||||
m_EntireFriendsList.Purge();
|
||||
m_FriendsWhoOwnTF2.Purge();
|
||||
|
||||
if ( steamapicontext && steamapicontext->SteamFriends() )
|
||||
{
|
||||
// Get our game info so we can use that to test if our friends are connected to the same game as us
|
||||
FriendGameInfo_t myGameInfo;
|
||||
CSteamID mySteamID = steamapicontext->SteamUser()->GetSteamID();
|
||||
steamapicontext->SteamFriends()->GetFriendGamePlayed( mySteamID, &myGameInfo );
|
||||
|
||||
m_iNumFriends = steamapicontext->SteamFriends()->GetFriendCount( k_EFriendFlagImmediate );
|
||||
if ( m_iNumFriends > 0 )
|
||||
{
|
||||
GCSDK::CProtoBufMsg<CMsgTFRequestTF2Friends> msg( k_EMsgGCRequestTF2Friends );
|
||||
for ( int i = 0; i < m_iNumFriends; i++ )
|
||||
{
|
||||
CSteamID friendSteamID = steamapicontext->SteamFriends()->GetFriendByIndex( i, k_EFriendFlagImmediate );
|
||||
|
||||
const char *pszName = steamapicontext->SteamFriends()->GetFriendPersonaName( friendSteamID );
|
||||
int idx = m_EntireFriendsList.AddToTail();
|
||||
partner_info_t &info = m_EntireFriendsList[idx];
|
||||
info.m_steamID = friendSteamID;
|
||||
info.m_name = pszName;
|
||||
|
||||
msg.Body().add_account_ids( friendSteamID.GetAccountID() );
|
||||
}
|
||||
GCClientSystem()->BSendMessage( msg );
|
||||
}
|
||||
else
|
||||
{
|
||||
m_bRefreshing = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// data
|
||||
bool m_bRefreshing;
|
||||
int m_iNumFriends;
|
||||
CUtlVector<partner_info_t> m_EntireFriendsList;
|
||||
CUtlVector<partner_info_t> m_FriendsWhoOwnTF2;
|
||||
};
|
||||
|
||||
static vgui::DHANDLE<CSelectMostHelpfulFriendDialog> g_hSelectMostHelpfulFriendDialog;
|
||||
|
||||
/**
|
||||
* Notification that the player should choose their most helpful friend.
|
||||
*/
|
||||
class CSelectHelpfulFriendNotification : public CEconNotification
|
||||
{
|
||||
public:
|
||||
CSelectHelpfulFriendNotification() {}
|
||||
|
||||
virtual void Accept()
|
||||
{
|
||||
OpenSelectMostHelpfulFriendDialog( NULL );
|
||||
MarkForDeletion();
|
||||
}
|
||||
|
||||
virtual void Decline()
|
||||
{
|
||||
MarkForDeletion();
|
||||
}
|
||||
|
||||
virtual EType NotificationType() { return eType_AcceptDecline; }
|
||||
|
||||
void Trigger()
|
||||
{
|
||||
OpenSelectMostHelpfulFriendDialog( NULL );
|
||||
MarkForDeletion();
|
||||
}
|
||||
|
||||
static bool RemoveOtherNotifications( CEconNotification *pNotification )
|
||||
{
|
||||
return dynamic_cast< CSelectHelpfulFriendNotification* >( pNotification ) != NULL;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
class CWasThankedBySomeoneNotification : public CEconNotification
|
||||
{
|
||||
public:
|
||||
CWasThankedBySomeoneNotification( const CSteamID& steamID )
|
||||
{
|
||||
SetText( "#TF_Trial_Alert_ThankedBySomeone" );
|
||||
SetLifetime( 30.0f );
|
||||
|
||||
{
|
||||
extern void GetPlayerNameBySteamID( const CSteamID &steamID, OUT_Z_CAP(maxLenInChars) char *pDestBuffer, int maxLenInChars );
|
||||
|
||||
wchar_t wszPlayerName[ MAX_PLAYER_NAME_LENGTH ];
|
||||
char szPlayerName[ MAX_PLAYER_NAME_LENGTH ];
|
||||
GetPlayerNameBySteamID( steamID, szPlayerName, sizeof( szPlayerName ) );
|
||||
g_pVGuiLocalize->ConvertANSIToUnicode( szPlayerName, wszPlayerName, sizeof( wszPlayerName ) );
|
||||
AddStringToken( "thanker", wszPlayerName );
|
||||
}
|
||||
}
|
||||
|
||||
static bool RemoveOtherNotifications( CEconNotification *pNotification )
|
||||
{
|
||||
return dynamic_cast< CWasThankedBySomeoneNotification* >( pNotification ) != NULL;
|
||||
}
|
||||
};
|
||||
|
||||
#ifdef _DEBUG
|
||||
CON_COMMAND( cl_free_trial_select_friend, "Bring up dialog to select most helpful friend" )
|
||||
{
|
||||
OpenSelectMostHelpfulFriendDialog( NULL );
|
||||
}
|
||||
|
||||
CON_COMMAND( cl_thanks_test, "Tests the thanked ui notification." )
|
||||
{
|
||||
if ( steamapicontext == NULL || steamapicontext->SteamUser() == NULL )
|
||||
return;
|
||||
|
||||
CSteamID steamID = steamapicontext->SteamUser()->GetSteamID();
|
||||
NotificationQueue_Add( new CWasThankedBySomeoneNotification( steamID ) );
|
||||
}
|
||||
#endif
|
||||
|
||||
class CGCRequestTF2FriendsResponse : public GCSDK::CGCClientJob
|
||||
{
|
||||
public:
|
||||
CGCRequestTF2FriendsResponse( GCSDK::CGCClient *pClient ) : GCSDK::CGCClientJob( pClient ) {}
|
||||
|
||||
virtual bool BYieldingRunGCJob( GCSDK::IMsgNetPacket *pNetPacket )
|
||||
{
|
||||
GCSDK::CProtoBufMsg<CMsgTFRequestTF2FriendsResponse> msg( pNetPacket );
|
||||
if ( g_hSelectMostHelpfulFriendDialog.Get() )
|
||||
{
|
||||
g_hSelectMostHelpfulFriendDialog->OnTF2FriendsReceived( msg );
|
||||
}
|
||||
return true;
|
||||
}
|
||||
};
|
||||
GC_REG_JOB( GCSDK::CGCClient, CGCRequestTF2FriendsResponse, "CGCRequestTF2FriendsResponse", k_EMsgGCRequestTF2FriendsResponse, GCSDK::k_EServerTypeGCClient );
|
||||
|
||||
class CGCThankedBySomeone : public GCSDK::CGCClientJob
|
||||
{
|
||||
public:
|
||||
CGCThankedBySomeone( GCSDK::CGCClient *pClient ) : GCSDK::CGCClientJob( pClient ) {}
|
||||
|
||||
virtual bool BYieldingRunGCJob( GCSDK::IMsgNetPacket *pNetPacket )
|
||||
{
|
||||
GCSDK::CProtoBufMsg<CMsgTFThankedBySomeone> msg( pNetPacket );
|
||||
NotificationQueue_Add( new CWasThankedBySomeoneNotification( CSteamID( msg.Body().thanker_steam_id() ) ) );
|
||||
return true;
|
||||
}
|
||||
};
|
||||
GC_REG_JOB( GCSDK::CGCClient, CGCThankedBySomeone, "CGCThankedBySomeone", k_EMsgGCFreeTrial_ThankedBySomeone, GCSDK::k_EServerTypeGCClient );
|
||||
|
||||
class CGCThankedSomeone : public GCSDK::CGCClientJob
|
||||
{
|
||||
public:
|
||||
CGCThankedSomeone( GCSDK::CGCClient *pClient ) : GCSDK::CGCClientJob( pClient ) {}
|
||||
|
||||
virtual bool BYieldingRunGCJob( GCSDK::IMsgNetPacket *pNetPacket )
|
||||
{
|
||||
ShowMessageBox( "#TF_Trial_ThankSuccess_Title", "#TF_Trial_ThankSuccess_Text", "#GameUI_OK" );
|
||||
return true;
|
||||
}
|
||||
};
|
||||
GC_REG_JOB( GCSDK::CGCClient, CGCThankedSomeone, "CGCThankedSomeone", k_EMsgGCFreeTrial_ThankedSomeone, GCSDK::k_EServerTypeGCClient );
|
||||
|
||||
class CGCFreeTrialConvertedToPremium : public GCSDK::CGCClientJob
|
||||
{
|
||||
public:
|
||||
CGCFreeTrialConvertedToPremium( GCSDK::CGCClient *pClient ) : GCSDK::CGCClientJob( pClient ) {}
|
||||
|
||||
virtual bool BYieldingRunGCJob( GCSDK::IMsgNetPacket *pNetPacket )
|
||||
{
|
||||
ShowMessageBox( "#TF_Trial_Converted_Title", "#TF_Trial_Converted_Text", "#GameUI_OK" );
|
||||
return true;
|
||||
}
|
||||
};
|
||||
GC_REG_JOB( GCSDK::CGCClient, CGCFreeTrialConvertedToPremium, "CGCFreeTrialConvertedToPremium", k_EMsgGCFreeTrial_ConvertedToPremium, GCSDK::k_EServerTypeGCClient );
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// External API
|
||||
|
||||
#if _DEBUG
|
||||
ConVar tf_forcetrialaccount( "tf_forcetrialaccount", "0", FCVAR_CLIENTDLL | FCVAR_ARCHIVE );
|
||||
#endif
|
||||
|
||||
#ifdef STAGING_ONLY
|
||||
ConVar tf_thank_a_friend_enabled( "tf_thank_a_friend_enabled", "1", FCVAR_CLIENTDLL | FCVAR_ARCHIVE );
|
||||
#endif // STAGING_ONLY
|
||||
|
||||
bool IsFreeTrialAccount()
|
||||
{
|
||||
#if _DEBUG
|
||||
if ( tf_forcetrialaccount.GetBool() )
|
||||
return true;
|
||||
#endif
|
||||
|
||||
if ( InventoryManager() && TFInventoryManager()->GetLocalTFInventory() && TFInventoryManager()->GetLocalTFInventory()->GetSOC() )
|
||||
{
|
||||
CEconGameAccountClient *pGameAccountClient = TFInventoryManager()->GetLocalTFInventory()->GetSOC()->GetSingleton<CEconGameAccountClient>();
|
||||
if ( pGameAccountClient )
|
||||
return pGameAccountClient->Obj().trial_account();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool NeedsToChooseMostHelpfulFriend()
|
||||
{
|
||||
#ifdef STAGING_ONLY
|
||||
if ( tf_thank_a_friend_enabled.GetBool() )
|
||||
#endif // STAGING_ONLY
|
||||
{
|
||||
if ( InventoryManager() && TFInventoryManager()->GetLocalTFInventory() && TFInventoryManager()->GetLocalTFInventory()->GetSOC() )
|
||||
{
|
||||
CEconGameAccountClient *pGameAccountClient = TFInventoryManager()->GetLocalTFInventory()->GetSOC()->GetSingleton<CEconGameAccountClient>();
|
||||
if ( pGameAccountClient )
|
||||
{
|
||||
return !pGameAccountClient->Obj().trial_account()
|
||||
&& pGameAccountClient->Obj().need_to_choose_most_helpful_friend();
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void NotifyNeedsToChooseMostHelpfulFriend()
|
||||
{
|
||||
// remove duplicates
|
||||
NotificationQueue_Remove( &CSelectHelpfulFriendNotification::RemoveOtherNotifications );
|
||||
// add new notification
|
||||
CSelectHelpfulFriendNotification *pNotification = new CSelectHelpfulFriendNotification();
|
||||
pNotification->SetText( "#TF_Trial_Alert_SelectFriend" );
|
||||
pNotification->SetLifetime( 120.0f );
|
||||
NotificationQueue_Add( pNotification );
|
||||
}
|
||||
|
||||
CSelectPlayerDialog *OpenSelectMostHelpfulFriendDialog( vgui::Panel *pParent )
|
||||
{
|
||||
if (!g_hSelectMostHelpfulFriendDialog.Get())
|
||||
{
|
||||
g_hSelectMostHelpfulFriendDialog = vgui::SETUP_PANEL( new CSelectMostHelpfulFriendDialog( pParent ) );
|
||||
}
|
||||
g_hSelectMostHelpfulFriendDialog->InvalidateLayout( false, true );
|
||||
g_hSelectMostHelpfulFriendDialog->Reset();
|
||||
g_hSelectMostHelpfulFriendDialog->SetVisible( true );
|
||||
g_hSelectMostHelpfulFriendDialog->MakePopup();
|
||||
g_hSelectMostHelpfulFriendDialog->MoveToFront();
|
||||
g_hSelectMostHelpfulFriendDialog->SetKeyBoardInputEnabled(true);
|
||||
g_hSelectMostHelpfulFriendDialog->SetMouseInputEnabled(true);
|
||||
TFModalStack()->PushModal( g_hSelectMostHelpfulFriendDialog );
|
||||
|
||||
return g_hSelectMostHelpfulFriendDialog;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,42 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose: Interface for the client to general GC API
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================
|
||||
|
||||
#ifndef C_TF_FREEACCOUNT_H
|
||||
#define C_TF_FREEACCOUNT_H
|
||||
#ifdef _WIN32
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
namespace vgui
|
||||
{
|
||||
class Panel;
|
||||
};
|
||||
class CSelectPlayerDialog;
|
||||
|
||||
/**
|
||||
* @return true if the local player is using a free trial account, false otherwise
|
||||
*/
|
||||
bool IsFreeTrialAccount();
|
||||
|
||||
/**
|
||||
* @return true if the local player needs to choose their most helpful friend, false otherwse
|
||||
*/
|
||||
bool NeedsToChooseMostHelpfulFriend();
|
||||
|
||||
/**
|
||||
* Adds an alert that the player needs to choose their most helpful friend
|
||||
*/
|
||||
void NotifyNeedsToChooseMostHelpfulFriend();
|
||||
|
||||
/**
|
||||
* Opens the dialog where the user can specify the friend that helped them the most
|
||||
* @param pParent
|
||||
* @return CSelectPlayerDialog
|
||||
*/
|
||||
CSelectPlayerDialog *OpenSelectMostHelpfulFriendDialog( vgui::Panel *pParent );
|
||||
|
||||
#endif // C_TF_FREEACCOUNT_H
|
||||
@@ -0,0 +1,55 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
#include "cbase.h"
|
||||
#include "tf_fx_shared.h"
|
||||
#include "c_basetempentity.h"
|
||||
#include "tier0/vprof.h"
|
||||
#include <cliententitylist.h>
|
||||
|
||||
class C_TEFireBullets : public C_BaseTempEntity
|
||||
{
|
||||
public:
|
||||
|
||||
DECLARE_CLASS( C_TEFireBullets, C_BaseTempEntity );
|
||||
DECLARE_CLIENTCLASS();
|
||||
|
||||
virtual void PostDataUpdate( DataUpdateType_t updateType );
|
||||
|
||||
public:
|
||||
|
||||
int m_iPlayer;
|
||||
Vector m_vecOrigin;
|
||||
QAngle m_vecAngles;
|
||||
int m_iWeaponID;
|
||||
int m_iMode;
|
||||
int m_iSeed;
|
||||
float m_flSpread;
|
||||
bool m_bCritical;
|
||||
};
|
||||
|
||||
IMPLEMENT_CLIENTCLASS_EVENT( C_TEFireBullets, DT_TEFireBullets, CTEFireBullets );
|
||||
|
||||
BEGIN_RECV_TABLE_NOBASE( C_TEFireBullets, DT_TEFireBullets )
|
||||
RecvPropVector( RECVINFO( m_vecOrigin ) ),
|
||||
RecvPropFloat( RECVINFO( m_vecAngles[0] ) ),
|
||||
RecvPropFloat( RECVINFO( m_vecAngles[1] ) ),
|
||||
RecvPropInt( RECVINFO( m_iWeaponID ) ),
|
||||
RecvPropInt( RECVINFO( m_iMode ) ),
|
||||
RecvPropInt( RECVINFO( m_iSeed ) ),
|
||||
RecvPropInt( RECVINFO( m_iPlayer ) ),
|
||||
RecvPropFloat( RECVINFO( m_flSpread ) ),
|
||||
RecvPropInt( RECVINFO( m_bCritical ) ),
|
||||
END_RECV_TABLE()
|
||||
|
||||
void C_TEFireBullets::PostDataUpdate( DataUpdateType_t updateType )
|
||||
{
|
||||
VPROF( "C_TEFireBullets::PostDataUpdate" );
|
||||
|
||||
// Create the effect.
|
||||
m_vecAngles.z = 0;
|
||||
FX_FireBullets( NULL, m_iPlayer+1, m_vecOrigin, m_vecAngles, m_iWeaponID, m_iMode, m_iSeed, m_flSpread, -1, m_bCritical );
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
#ifndef C_TF_FX_H
|
||||
#define C_TF_FX_H
|
||||
|
||||
#ifdef _WIN32
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
// See comments in tf_fx.h
|
||||
const int kInvalidEHandleExplosion = MAX_EDICTS - 1;
|
||||
const int kInvalidEHandleParticleEffect = MAX_EDICTS - 1;
|
||||
|
||||
#endif
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,344 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
//=============================================================================//
|
||||
#ifndef C_TF_GAMESTATS_H
|
||||
#define C_TF_GAMESTATS_H
|
||||
#ifdef _WIN32
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include "gamestats.h"
|
||||
#include "tf_gamestats_shared.h"
|
||||
#include "GameEventListener.h"
|
||||
#include "c_tf_player.h"
|
||||
#include "econ_store.h"
|
||||
#include "store/store_panel.h"
|
||||
|
||||
class CTFPlayer;
|
||||
|
||||
struct TF_Gamestats_ClientSession_t
|
||||
{
|
||||
public:
|
||||
|
||||
TF_Gamestats_ClientSession_t();
|
||||
|
||||
private:
|
||||
TF_Gamestats_ClientSession_t( const TF_Gamestats_ClientSession_t &stats ) {}
|
||||
|
||||
public:
|
||||
void Reset();
|
||||
|
||||
struct SessionSummary_t
|
||||
{
|
||||
int iClassesPlayed;
|
||||
int iMapsPlayed;
|
||||
int iRoundsPlayed;
|
||||
int iFavoriteClass;
|
||||
int iFavoriteWeapon;
|
||||
char szFavoriteMap[64];
|
||||
int iKills;
|
||||
int iDeaths;
|
||||
int iSuicides;
|
||||
int iAssists;
|
||||
int iBuildingsBuilt;
|
||||
int iBuildingsUpgraded;
|
||||
int iBuildingsDestroyed;
|
||||
int iHeadshots;
|
||||
int iDominations;
|
||||
int iRevenges;
|
||||
int iInvulns;
|
||||
int iTeleports;
|
||||
int iDamageDone;
|
||||
int iHealingDone;
|
||||
int iCrits;
|
||||
int iBackstabs;
|
||||
int iAchievementsEarned;
|
||||
};
|
||||
|
||||
SessionSummary_t m_Summary;
|
||||
|
||||
RTime32 m_SessionStart;
|
||||
RTime32 m_FirstConnect;
|
||||
int m_iMapsPlayed;
|
||||
int m_iRoundsPlayed;
|
||||
CBitVecT< CFixedBitVecBase<32> > m_ClassesPlayed;
|
||||
};
|
||||
|
||||
struct TF_Gamestats_WeaponInfo_t
|
||||
{
|
||||
TF_Gamestats_WeaponInfo_t();
|
||||
|
||||
int weaponID;
|
||||
int critsFired;
|
||||
int shotsFired;
|
||||
int shotsHit;
|
||||
int shotsMissed;
|
||||
int avgDamage;
|
||||
int totalDamage;
|
||||
int critHits;
|
||||
float lastUpdateTime;
|
||||
};
|
||||
|
||||
struct TF_Gamestats_AchievementEvent_t
|
||||
{
|
||||
TF_Gamestats_AchievementEvent_t( int in_achievementNum, const char* in_achievementID );
|
||||
|
||||
int eventTime;
|
||||
int achievementNum;
|
||||
const char* achievementID;
|
||||
};
|
||||
|
||||
// Item event baseclass.
|
||||
class TF_Gamestats_ItemEvent
|
||||
{
|
||||
public:
|
||||
TF_Gamestats_ItemEvent( int in_eventNum, CEconItemView* in_item );
|
||||
|
||||
int eventNum;
|
||||
int eventTime;
|
||||
const char* eventID;
|
||||
|
||||
item_definition_index_t itemDefIndex;
|
||||
itemid_t itemID;
|
||||
const char* itemName;
|
||||
char itemNameBuf[512];
|
||||
bool bUseNameBuf;
|
||||
|
||||
const char* GetItemName()
|
||||
{
|
||||
if ( bUseNameBuf )
|
||||
return itemNameBuf;
|
||||
else
|
||||
return itemName;
|
||||
}
|
||||
};
|
||||
|
||||
// Mann Co Catalog Usage Tracking
|
||||
class TF_Gamestats_CatalogEvent : public TF_Gamestats_ItemEvent
|
||||
{
|
||||
public:
|
||||
TF_Gamestats_CatalogEvent( int in_eventNum, CEconItemView* in_item, const char* in_filter );
|
||||
|
||||
const char* catalogFilter;
|
||||
};
|
||||
|
||||
// Crafting System Usage Tracking
|
||||
class TF_Gamestats_CraftingEvent : public TF_Gamestats_ItemEvent
|
||||
{
|
||||
public:
|
||||
TF_Gamestats_CraftingEvent( int in_eventNum, CEconItemView* in_item, int in_numAttempts, int in_recipe );
|
||||
|
||||
int numAttempts;
|
||||
int recipeFound;
|
||||
};
|
||||
|
||||
// Store Usage Tracking
|
||||
class TF_Gamestats_StoreEvent : public TF_Gamestats_ItemEvent
|
||||
{
|
||||
public:
|
||||
TF_Gamestats_StoreEvent( int in_eventNum, CEconItemView* in_item,
|
||||
const char* in_panelName, int in_classId, const cart_item_t* in_cartItem,
|
||||
int in_checkoutAttempts, const char* in_storeError, int in_totalPrice, int in_currencyCode );
|
||||
|
||||
int classId;
|
||||
int cartQuantity;
|
||||
int cartItemCost;
|
||||
int currencyCode;
|
||||
int checkoutAttempt;
|
||||
const char* storeError;
|
||||
const char* panelName;
|
||||
};
|
||||
|
||||
// General client-subjective item transaction tracking.
|
||||
class TF_Gamestats_ItemTransactionEvent : public TF_Gamestats_ItemEvent
|
||||
{
|
||||
public:
|
||||
TF_Gamestats_ItemTransactionEvent( int in_eventNum, CEconItemView* in_item, const char* in_reason, int in_quality );
|
||||
|
||||
const char* reason;
|
||||
int itemQuality;
|
||||
};
|
||||
|
||||
// Trade Usage Tracking
|
||||
class TF_Gamestats_TradeEvent : public TF_Gamestats_ItemEvent
|
||||
{
|
||||
public:
|
||||
TF_Gamestats_TradeEvent( int eventID, CEconItemView* item, bool localPlayerIsPartyA,
|
||||
uint64 steamIDPartyA, uint64 steamIDPartyB, int iTradeRequests, int iTradeAttempts );
|
||||
TF_Gamestats_TradeEvent( int eventID, uint64 steamIDRequested, int iTradeRequests, int iTradeAttempts );
|
||||
TF_Gamestats_TradeEvent( int eventID, int iTradeRequests, const char* reason, int iTradeAttempts );
|
||||
|
||||
bool localPlayerPartyMatters;
|
||||
bool localPlayerIsPartyA;
|
||||
uint64 steamIDPartyA;
|
||||
uint64 steamIDPartyB;
|
||||
|
||||
uint64 steamIDRequested;
|
||||
int tradeRequests;
|
||||
int tradeAttempts;
|
||||
|
||||
const char* reason;
|
||||
};
|
||||
|
||||
// Matchmaking stats
|
||||
struct TF_Gamestats_QuickPlay_t
|
||||
{
|
||||
// Status code for the search as a whole
|
||||
enum eResult
|
||||
{
|
||||
k_Result_InternalError = -1,
|
||||
k_Result_UserCancel = 10,
|
||||
k_Result_NoServersFound = 20,
|
||||
k_Result_NoServersMetCrtieria = 30,
|
||||
//k_Result_NeverHeardBackFromGC = 40,
|
||||
//k_Result_ReceivedZeroGCScores = 50,
|
||||
k_Result_FinalPingFailed = 60,
|
||||
k_Result_TriedToConnect = 100,
|
||||
};
|
||||
|
||||
// Status codes for the servers
|
||||
enum eServerStatus
|
||||
{
|
||||
k_Server_Invalid = -1, // we have a bug if this gets reported
|
||||
k_Server_Ineligible = 10,
|
||||
k_Server_Eligible = 20,
|
||||
k_Server_RequestedScore = 30,
|
||||
k_Server_Scored = 40,
|
||||
k_Server_Pinged = 50,
|
||||
k_Server_PingTimedOut = 60,
|
||||
k_Server_PingIneligible = 70,
|
||||
k_Server_Connected = 100,
|
||||
};
|
||||
|
||||
TF_Gamestats_QuickPlay_t()
|
||||
{
|
||||
m_fUserHoursPlayed = -1.0f;
|
||||
m_sUserGameMode;
|
||||
m_fSearchTime = -1.0;
|
||||
m_eResultCode = k_Result_UserCancel;
|
||||
m_iExperimentGroup = 0;
|
||||
}
|
||||
|
||||
float m_fUserHoursPlayed;
|
||||
CUtlString m_sUserGameMode;
|
||||
float m_fSearchTime;
|
||||
eResult m_eResultCode;
|
||||
int m_iExperimentGroup; // TF2ScoringNumbers_t::ExperimentGroup_t
|
||||
|
||||
struct Server_t
|
||||
{
|
||||
uint32 m_ip;
|
||||
uint16 m_port;
|
||||
bool m_bRegistered;
|
||||
bool m_bValve;
|
||||
bool m_bSecure;
|
||||
bool m_bMapIsNewUserFriendly;
|
||||
bool m_bMapIsQuickPlayOK;
|
||||
int m_nPlayers;
|
||||
int m_nMaxPlayers;
|
||||
CUtlString m_sMapName;
|
||||
CUtlString m_sTags;
|
||||
int m_iPing;
|
||||
float m_fScoreClient;
|
||||
float m_fScoreServer;
|
||||
float m_fScoreGC;
|
||||
eServerStatus m_eStatus;
|
||||
};
|
||||
CUtlVector<Server_t> m_vecServers;
|
||||
};
|
||||
|
||||
//=============================================================================
|
||||
//
|
||||
// TF Game Stats Class
|
||||
//
|
||||
|
||||
class C_CTFGameStats : public CBaseGameStats, public CGameEventListener, public CAutoGameSystem
|
||||
{
|
||||
public:
|
||||
|
||||
// Constructor/Destructor.
|
||||
C_CTFGameStats( void );
|
||||
~C_CTFGameStats( void );
|
||||
|
||||
virtual void Clear( void );
|
||||
|
||||
virtual bool UseOldFormat() { return false; }
|
||||
virtual bool AddDataForSend( KeyValues *pKV, StatSendType_t sendType );
|
||||
|
||||
virtual bool Init();
|
||||
virtual void Shutdown();
|
||||
|
||||
void ResetRoundStats();
|
||||
|
||||
void ClientDisconnect( int iReason );
|
||||
|
||||
// Events.
|
||||
virtual void Event_LevelInit( void );
|
||||
virtual void Event_LevelShutdown( float flElapsed );
|
||||
virtual void Event_RoundActive();
|
||||
virtual void Event_RoundEnd( int winningTeam, float roundTime, int fullRound );
|
||||
virtual void Event_PlayerChangeClass( int userid, int classid );
|
||||
virtual void Event_AchievementProgress( int achievementID, const char* achievementName );
|
||||
virtual void Event_PlayerHurt( IGameEvent* event /*player_hurt*/ );
|
||||
virtual void Event_PlayerFiredWeapon( C_TFPlayer *pPlayer, bool bCritical );
|
||||
virtual void Event_Catalog( int eventID, const char* filter=NULL, CEconItemView* item=NULL );
|
||||
virtual void Event_Crafting( int eventID, CEconItemView* item=NULL, int numAttempts=0, int recipeFound=0 );
|
||||
virtual void Event_Store( int eventID, CEconItemView* item=NULL, const char* panelName=NULL,
|
||||
int classId=0, const cart_item_t* in_cartItem=NULL, int in_checkoutAttempts=0, const char* storeError=NULL, int in_totalPrice=0, int in_currencyCode=0 );
|
||||
virtual void Event_ItemTransaction( int eventID, CEconItemView* item, const char* pszReason=NULL, int iQuality=0 );
|
||||
virtual void Event_Trading( int eventID, CEconItemView* item=NULL, bool localPlayerIsPartyA=false,
|
||||
uint64 steamIDPartyA=0, uint64 steamIDPartyB=0, int iTradeRequests=0, int iTradeAttempts=0 );
|
||||
virtual void Event_Trading( int eventID, uint64 steamIDRequested=0, int iTradeRequests=0, int iTradeAttempts=0 );
|
||||
virtual void Event_Trading( int eventID, int iTradeRequests=0, const char* reason=NULL, int iTradeAttempts=0 );
|
||||
virtual void Event_Trading( TF_Gamestats_TradeEvent& event );
|
||||
|
||||
virtual void FireGameEvent( IGameEvent * event );
|
||||
|
||||
void SW_GameStats_WriteClientSessionSummary();
|
||||
void SW_GameStats_WriteClientWeapons();
|
||||
void SW_GameStats_WriteClientRound( int winningTeam, int fullRound, int endReason );
|
||||
void SW_GameStats_WriteClientMap();
|
||||
|
||||
void SetExperimentValue( uint64 experimentValue ) { m_ulExperimentValue = experimentValue; }
|
||||
|
||||
static void ImmediateWriteInterfaceEvent( const char *pszEventType, const char *pszEventDesc );
|
||||
|
||||
/*
|
||||
void SW_GameStats_WriteClientAchievements();
|
||||
void SW_GameStats_WriteClientCatalogEvents();
|
||||
void SW_GameStats_WriteClientCraftingEvents();
|
||||
void SW_GameStats_WriteClientStoreEvents();
|
||||
void SW_GameStats_WriteClientItemTransactionEvents();
|
||||
void SW_GameStats_WriteClientTradeEvents();
|
||||
*/
|
||||
|
||||
void QuickplayResults( const TF_Gamestats_QuickPlay_t &info );
|
||||
|
||||
private:
|
||||
char m_szCountryCode[64];
|
||||
char m_szAudioLanguage[64];
|
||||
char m_szTextLanguage[64];
|
||||
|
||||
TF_Gamestats_ClientSession_t m_currentSession;
|
||||
TF_Gamestats_RoundStats_t m_currentRound;
|
||||
TF_Gamestats_LevelStats_t m_currentMap;
|
||||
CUtlVector<TF_Gamestats_AchievementEvent_t> m_vecAchievementEvents;
|
||||
CUtlMap<int, TF_Gamestats_WeaponInfo_t> m_mapWeaponInfo;
|
||||
|
||||
CUtlVector<TF_Gamestats_CatalogEvent> m_vecCatalogEvents;
|
||||
CUtlVector<TF_Gamestats_CraftingEvent> m_vecCraftingEvents;
|
||||
CUtlVector<TF_Gamestats_StoreEvent> m_vecStoreEvents;
|
||||
CUtlVector<TF_Gamestats_ItemTransactionEvent> m_vecItemTransactionEvents;
|
||||
CUtlVector<TF_Gamestats_TradeEvent> m_vecTradeEvents;
|
||||
|
||||
uint64 m_ulExperimentValue;
|
||||
|
||||
bool m_bRoundActive;
|
||||
bool m_bIsDisconnecting;
|
||||
};
|
||||
|
||||
extern C_CTFGameStats C_CTF_GameStats;
|
||||
|
||||
#endif // C_TF_GAMESTATS_H
|
||||
@@ -0,0 +1,89 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
//=============================================================================//
|
||||
|
||||
#include "cbase.h"
|
||||
|
||||
// memdbgon must be the last include file in a .cpp file!!!
|
||||
#include "tier0/memdbgon.h"
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
class C_TFGlow : public C_BaseEntity
|
||||
{
|
||||
public:
|
||||
DECLARE_CLASS( C_TFGlow, C_BaseEntity );
|
||||
DECLARE_CLIENTCLASS();
|
||||
|
||||
C_TFGlow();
|
||||
virtual ~C_TFGlow();
|
||||
virtual void PostDataUpdate( DataUpdateType_t updateType ) OVERRIDE;
|
||||
|
||||
private:
|
||||
void CreateGlow();
|
||||
|
||||
CGlowObject *pGlow;
|
||||
CNetworkVar( int, m_iMode );
|
||||
CNetworkVar( color32, m_glowColor );
|
||||
CNetworkVar( bool, m_bDisabled );
|
||||
CNetworkHandle( CBaseEntity, m_hTarget );
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
IMPLEMENT_CLIENTCLASS_DT( C_TFGlow, DT_TFGlow, CTFGlow )
|
||||
RecvPropInt(RECVINFO( m_iMode ) ),
|
||||
RecvPropInt( RECVINFO( m_glowColor ), 0, RecvProxy_IntToColor32 ),
|
||||
RecvPropBool( RECVINFO( m_bDisabled ) ),
|
||||
RecvPropEHandle( RECVINFO( m_hTarget ) ),
|
||||
END_RECV_TABLE()
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
C_TFGlow::C_TFGlow()
|
||||
{
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
C_TFGlow::~C_TFGlow()
|
||||
{
|
||||
delete pGlow;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
void C_TFGlow::CreateGlow()
|
||||
{
|
||||
if ( pGlow )
|
||||
{
|
||||
delete pGlow;
|
||||
pGlow = nullptr;
|
||||
}
|
||||
|
||||
if ( m_bDisabled || !m_hTarget )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
Vector cvec;
|
||||
color32 c = m_glowColor.Get();
|
||||
cvec[0] = c.r * (1.0f/255.0f);
|
||||
cvec[1] = c.g * (1.0f/255.0f);
|
||||
cvec[2] = c.b * (1.0f/255.0f);
|
||||
float a = c.a * (1.0f/255.0f);
|
||||
|
||||
int iMode = m_iMode.Get();
|
||||
bool bDrawWhenOccluded = ( iMode == 0 ) || ( iMode == 1 );
|
||||
bool bDrawWhenVisible = ( iMode == 0 ) || ( iMode == 2 );
|
||||
Assert( bDrawWhenOccluded || bDrawWhenVisible );
|
||||
|
||||
pGlow = new CGlowObject( m_hTarget, cvec, a, bDrawWhenOccluded, bDrawWhenVisible );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
void C_TFGlow::PostDataUpdate( DataUpdateType_t updateType )
|
||||
{
|
||||
BaseClass::PostDataUpdate( updateType );
|
||||
|
||||
// this could avoid recreating the glow object on every update, but it
|
||||
// wouldn't be noticeably more efficient and it would add a ton of code here.
|
||||
CreateGlow();
|
||||
}
|
||||
@@ -0,0 +1,416 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================
|
||||
#include "cbase.h"
|
||||
|
||||
#include "c_tf_player.h"
|
||||
#include "collisionutils.h"
|
||||
#include "econ_item_inventory.h"
|
||||
#include "iclientmode.h"
|
||||
#include "tf_gcmessages.h"
|
||||
#include "tf_gamerules.h"
|
||||
#include "econ_notifications.h"
|
||||
#include "rtime.h"
|
||||
#include "achievementmgr.h"
|
||||
#include "baseachievement.h"
|
||||
#include "achievements_tf.h"
|
||||
#include "gc_clientsystem.h"
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
EHalloweenMap GetHalloweenMap()
|
||||
{
|
||||
if ( FStrEq( engine->GetLevelName(), "maps/cp_manor_event.bsp" ) )
|
||||
return kHalloweenMap_MannManor;
|
||||
|
||||
if ( FStrEq( engine->GetLevelName(), "maps/koth_viaduct_event.bsp" ) )
|
||||
return kHalloweenMap_Viaduct;
|
||||
|
||||
if ( FStrEq( engine->GetLevelName(), "maps/koth_lakeside_event.bsp" ) )
|
||||
return kHalloweenMap_Lakeside;
|
||||
|
||||
if ( FStrEq( engine->GetLevelName(), "maps/plr_hightower_event.bsp" ) )
|
||||
return kHalloweenMap_Hightower;
|
||||
|
||||
return kHalloweenMapCount;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Created when the GC decides to give out an item.
|
||||
// A player must intersect the item to claim it.
|
||||
//-----------------------------------------------------------------------------
|
||||
#define HALLOWEEN_ITEM_TIME_TO_READY 10.0f
|
||||
class C_HalloweenItemPickup : public CBaseAnimating
|
||||
{
|
||||
DECLARE_CLASS( C_HalloweenItemPickup, CBaseAnimating );
|
||||
public:
|
||||
C_HalloweenItemPickup()
|
||||
: m_bReadyForPickup( false )
|
||||
, m_bClaimed( false )
|
||||
, m_flTimeToReady( 0.0f )
|
||||
{
|
||||
AddEFlags( EFL_USE_PARTITION_WHEN_NOT_SOLID );
|
||||
}
|
||||
|
||||
virtual ~C_HalloweenItemPickup()
|
||||
{
|
||||
}
|
||||
|
||||
bool Initialize()
|
||||
{
|
||||
const char *pszModelName = "models/props_halloween/halloween_gift.mdl";
|
||||
SetModelName( AllocPooledString( pszModelName ) );
|
||||
|
||||
if ( InitializeAsClientEntity( STRING(GetModelName()), RENDER_GROUP_OPAQUE_ENTITY ) == false )
|
||||
return false;
|
||||
|
||||
const model_t *mod = GetModel();
|
||||
if ( mod )
|
||||
{
|
||||
Vector mins, maxs;
|
||||
modelinfo->GetModelBounds( mod, mins, maxs );
|
||||
SetCollisionBounds( mins, maxs );
|
||||
}
|
||||
|
||||
Spawn();
|
||||
|
||||
// initialize as translucent
|
||||
float alpha = 0.0f;
|
||||
SetRenderMode( kRenderTransTexture );
|
||||
SetRenderColorA( alpha * 256 );
|
||||
m_flTimeToReady = gpGlobals->realtime + HALLOWEEN_ITEM_TIME_TO_READY;
|
||||
|
||||
UpdatePartitionListEntry();
|
||||
|
||||
SetBlocksLOS( false ); // this should be a small object
|
||||
|
||||
// Set up shadows; do it here so that objects can change shadowcasting state
|
||||
CreateShadow();
|
||||
|
||||
UpdateVisibility();
|
||||
|
||||
SetNextClientThink( CLIENT_THINK_ALWAYS );
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
virtual void Spawn()
|
||||
{
|
||||
Precache();
|
||||
BaseClass::Spawn();
|
||||
SetSolid( SOLID_NONE );
|
||||
AddSolidFlags( FSOLID_NOT_SOLID );
|
||||
SetMoveType( MOVETYPE_NONE );
|
||||
}
|
||||
|
||||
virtual void ClientThink()
|
||||
{
|
||||
if ( m_bReadyForPickup )
|
||||
{
|
||||
ClientThink_Active();
|
||||
return;
|
||||
}
|
||||
|
||||
float flTimeDelta = m_flTimeToReady - gpGlobals->realtime;
|
||||
if ( flTimeDelta < 0 )
|
||||
{
|
||||
m_bReadyForPickup = true;
|
||||
ParticleProp()->Create( "halloween_pickup_active", PATTACH_ABSORIGIN_FOLLOW );
|
||||
SetRenderMode( kRenderNormal );
|
||||
}
|
||||
else
|
||||
{
|
||||
float alpha = 0.75f * ( ( HALLOWEEN_ITEM_TIME_TO_READY - flTimeDelta ) / HALLOWEEN_ITEM_TIME_TO_READY );
|
||||
SetRenderColorA( alpha * 256 );
|
||||
}
|
||||
}
|
||||
|
||||
void ClientThink_Active( void )
|
||||
{
|
||||
Vector vWorldMins = WorldAlignMins();
|
||||
Vector vWorldMaxs = WorldAlignMaxs();
|
||||
Vector vBoxMin1 = GetAbsOrigin() + vWorldMins;
|
||||
Vector vBoxMax1 = GetAbsOrigin() + vWorldMaxs;
|
||||
|
||||
float flBestDistance2 = 0.0f;
|
||||
CSteamID bestSteamID;
|
||||
bool bBestHasNoclip = false;
|
||||
|
||||
#define CLIENT_HALLOWEEN_LOGIC_ENABLE_LOCAL_PLAYER_ONLY 1
|
||||
|
||||
#if !CLIENT_HALLOWEEN_LOGIC_ENABLE_LOCAL_PLAYER_ONLY
|
||||
for( int iPlayerIndex = 1 ; iPlayerIndex <= MAX_PLAYERS; iPlayerIndex++ )
|
||||
{
|
||||
C_TFPlayer *pPlayer = ToTFPlayer( UTIL_PlayerByIndex( iPlayerIndex ) );
|
||||
#else
|
||||
do
|
||||
{
|
||||
C_TFPlayer *pPlayer = C_TFPlayer::GetLocalTFPlayer();
|
||||
#endif
|
||||
CSteamID steamID;
|
||||
if ( pPlayer == NULL || pPlayer->IsBot() == true || pPlayer->GetSteamID( &steamID ) == false ||
|
||||
( pPlayer->GetTeamNumber() != TF_TEAM_RED && pPlayer->GetTeamNumber() != TF_TEAM_BLUE ) ||
|
||||
pPlayer->IsAlive() == false ||
|
||||
pPlayer->GetObserverMode() != OBS_MODE_NONE )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
Vector vPlayerMins = pPlayer->GetAbsOrigin() + pPlayer->WorldAlignMins();
|
||||
Vector vPlayerMaxs = pPlayer->GetAbsOrigin() + pPlayer->WorldAlignMaxs();
|
||||
bool bIntersecting = IsBoxIntersectingBox( vBoxMin1, vBoxMax1, vPlayerMins, vPlayerMaxs );
|
||||
float flDistance2 = ( pPlayer->GetAbsOrigin(), GetAbsOrigin() ).LengthSqr();
|
||||
if ( bIntersecting && ( bestSteamID.GetAccountID() == 0 || flDistance2 < flBestDistance2 ) )
|
||||
{
|
||||
bestSteamID = steamID;
|
||||
bBestHasNoclip = pPlayer->GetMoveType() == MOVETYPE_NOCLIP;
|
||||
flBestDistance2 = flDistance2;
|
||||
}
|
||||
}
|
||||
#if CLIENT_HALLOWEEN_LOGIC_ENABLE_LOCAL_PLAYER_ONLY
|
||||
while ( false );
|
||||
#endif
|
||||
|
||||
if ( bestSteamID.GetAccountID() != 0 )
|
||||
{
|
||||
GCSDK::CProtoBufMsg<CMsgGC_Halloween_GrantItem> msg( k_EMsgGC_Halloween_GrantItem );
|
||||
msg.Body().set_recipient_account_id( bestSteamID.GetAccountID() );
|
||||
msg.Body().set_level_id( GetHalloweenMap() );
|
||||
msg.Body().set_flagged( bBestHasNoclip );
|
||||
GCClientSystem()->BSendMessage( msg );
|
||||
OnClaimed( true );
|
||||
return;
|
||||
}
|
||||
|
||||
SetNextClientThink( gpGlobals->curtime + 0.33f );
|
||||
}
|
||||
|
||||
void OnClaimed( bool bPlayAudio )
|
||||
{
|
||||
if ( m_bClaimed )
|
||||
return;
|
||||
|
||||
m_bClaimed = true;
|
||||
// stop thinking and remove sparkle...
|
||||
ParticleProp()->StopParticlesNamed( "halloween_pickup_active", true );
|
||||
SetNextClientThink( CLIENT_THINK_NEVER );
|
||||
// throw up bday confetti
|
||||
DispatchParticleEffect( "halloween_gift_pickup", GetAbsOrigin(), vec3_angle );
|
||||
|
||||
if ( bPlayAudio )
|
||||
{
|
||||
C_BaseEntity::EmitSound( "Game.HappyBirthday" );
|
||||
}
|
||||
SetRenderMode( kRenderNone );
|
||||
UpdateVisibility();
|
||||
}
|
||||
|
||||
bool m_bReadyForPickup;
|
||||
bool m_bClaimed;
|
||||
float m_flTimeToReady;
|
||||
};
|
||||
|
||||
LINK_ENTITY_TO_CLASS( tf_halloween_item_pickup, C_HalloweenItemPickup );
|
||||
PRECACHE_REGISTER( tf_halloween_item_pickup );
|
||||
|
||||
static EHANDLE gHalloweenPickup;
|
||||
|
||||
#ifdef _DEBUG
|
||||
CON_COMMAND( cl_halloween_test_cheating, "Test cheating the halloween pickup" )
|
||||
{
|
||||
GCSDK::CProtoBufMsg< CMsgGC_Halloween_GrantItem > msg( k_EMsgGC_Halloween_GrantItem );
|
||||
msg.Body().set_recipient_account_id( steamapicontext->SteamUser()->GetSteamID().GetAccountID() );
|
||||
GCClientSystem()->BSendMessage( msg );
|
||||
}
|
||||
|
||||
CON_COMMAND( cl_halloween_test_spawn_pickup, "Test spawning the pickup item" )
|
||||
{
|
||||
C_TFPlayer *pLocalPlayer = C_TFPlayer::GetLocalTFPlayer();
|
||||
if ( pLocalPlayer == NULL )
|
||||
return;
|
||||
|
||||
// Now create the pickup item
|
||||
C_HalloweenItemPickup *pEntity = new C_HalloweenItemPickup();
|
||||
if ( !pEntity )
|
||||
return;
|
||||
|
||||
Vector vecTargetPoint;
|
||||
trace_t tr;
|
||||
Vector forward;
|
||||
pLocalPlayer->EyeVectors( &forward );
|
||||
UTIL_TraceLine( pLocalPlayer->EyePosition(),
|
||||
pLocalPlayer->EyePosition() + forward * MAX_TRACE_LENGTH,MASK_NPCSOLID,
|
||||
pLocalPlayer, COLLISION_GROUP_NONE, &tr );
|
||||
|
||||
if ( tr.fraction != 1.0 )
|
||||
{
|
||||
vecTargetPoint = tr.endpos;
|
||||
}
|
||||
|
||||
pEntity->SetAbsOrigin( vecTargetPoint );
|
||||
if ( !pEntity->Initialize() )
|
||||
{
|
||||
pEntity->Release();
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( gHalloweenPickup.Get() )
|
||||
gHalloweenPickup->Release();
|
||||
gHalloweenPickup = pEntity;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// GC has decided to drop a Halloween item
|
||||
//-----------------------------------------------------------------------------
|
||||
//class CGCHalloween_ReservedItem : public GCSDK::CGCClientJob
|
||||
//{
|
||||
//public:
|
||||
// CGCHalloween_ReservedItem( GCSDK::CGCClient *pClient ) : GCSDK::CGCClientJob( pClient ) {}
|
||||
//
|
||||
// virtual bool BYieldingRunGCJob( GCSDK::IMsgNetPacket *pNetPacket )
|
||||
// {
|
||||
// GCSDK::CProtoBufMsg<CMsgGC_Halloween_ReservedItem> msg( pNetPacket );
|
||||
//
|
||||
// // Figure out which level we're on so we know how to handle notifications, etc.
|
||||
// EHalloweenMap eMap = GetHalloweenMap();
|
||||
// if ( eMap == kHalloweenMapCount )
|
||||
// return true;
|
||||
//
|
||||
// // Sanity-check the message contents from the GC.
|
||||
// if ( msg.Body().x_size() != msg.Body().y_size() || msg.Body().y_size() != msg.Body().z_size() )
|
||||
// return true;
|
||||
//
|
||||
// if ( msg.Body().x_size() <= eMap )
|
||||
// return true;
|
||||
//
|
||||
// // Don't spawn gifts during startup.
|
||||
// if ( TFGameRules() == NULL
|
||||
// || TFGameRules()->State_Get() != GR_STATE_RND_RUNNING
|
||||
// || TFGameRules()->InSetup()
|
||||
// || TFGameRules()->IsInWaitingForPlayers()
|
||||
// || TFGameRules()->ArePlayersInHell() ) // Dont spawn gifts if players are in 2013 Hell
|
||||
// return true;
|
||||
//
|
||||
// C_TFPlayer *pLocalPlayer = C_TFPlayer::GetLocalTFPlayer();
|
||||
// if ( pLocalPlayer == NULL )
|
||||
// return true;
|
||||
//
|
||||
// // If we don't already know about this gift pickup, create one.
|
||||
// if ( gHalloweenPickup.Get() == NULL )
|
||||
// {
|
||||
// // Now create the pickup item
|
||||
// C_HalloweenItemPickup *pEntity = new C_HalloweenItemPickup();
|
||||
// if ( !pEntity )
|
||||
// return true;
|
||||
//
|
||||
// Vector position( msg.Body().x( eMap ), msg.Body().y( eMap ), msg.Body().z( eMap ) );
|
||||
// pEntity->SetAbsOrigin( position );
|
||||
// if ( !pEntity->Initialize() )
|
||||
// {
|
||||
// pEntity->Release();
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// gHalloweenPickup = pEntity;
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// // Regardless of whether we created a new gift or whether this was a new notification about an old gift,
|
||||
// // display a UI notification for the user.
|
||||
// CEconNotification *pNotification = new CEconNotification();
|
||||
// pNotification->SetText( "#TF_HalloweenItem_Reserved" );
|
||||
// pNotification->SetLifetime( 15.0f );
|
||||
// pNotification->SetSoundFilename( "ui/halloween_loot_spawn.wav" );
|
||||
// NotificationQueue_Add( pNotification );
|
||||
//
|
||||
// return true;
|
||||
// }
|
||||
//};
|
||||
//GC_REG_JOB( GCSDK::CGCClient, CGCHalloween_ReservedItem, "CGCHalloween_ReservedItem", k_EMsgGC_Halloween_ReservedItem, GCSDK::k_EServerTypeGCClient );
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// GC gave out the Halloween item to a player
|
||||
//-----------------------------------------------------------------------------
|
||||
//class CGCHalloween_GrantedItemResponse : public GCSDK::CGCClientJob
|
||||
//{
|
||||
//public:
|
||||
// CGCHalloween_GrantedItemResponse( GCSDK::CGCClient *pClient ) : GCSDK::CGCClientJob( pClient ) {}
|
||||
//
|
||||
// virtual bool BYieldingRunGCJob( GCSDK::IMsgNetPacket *pNetPacket )
|
||||
// {
|
||||
// GCSDK::CProtoBufMsg<CMsgGC_Halloween_GrantItemResponse> msg( pNetPacket );
|
||||
//
|
||||
// // which Steam universe are we in?
|
||||
// EUniverse eUniverse = steamapicontext && steamapicontext->SteamUtils()
|
||||
// ? steamapicontext->SteamUtils()->GetConnectedUniverse()
|
||||
// : k_EUniverseInvalid;
|
||||
//
|
||||
// CSteamID steamIDRecipient( msg.Body().recipient_account_id(), eUniverse, k_EAccountTypeIndividual );
|
||||
// bool bIsValidRecipient = steamIDRecipient.IsValid();
|
||||
//
|
||||
// if ( gHalloweenPickup.Get() != NULL )
|
||||
// {
|
||||
// assert_cast<C_HalloweenItemPickup *>( gHalloweenPickup.Get() )->OnClaimed( bIsValidRecipient );
|
||||
// gHalloweenPickup->Release();
|
||||
// gHalloweenPickup = NULL;
|
||||
// }
|
||||
//
|
||||
// // don't do any work if we're not on a Halloween map
|
||||
// EHalloweenMap eMap = GetHalloweenMap();
|
||||
// if ( eMap == kHalloweenMapCount )
|
||||
// return true;
|
||||
//
|
||||
// // add alert
|
||||
// const char* pPlayerName = InventoryManager()->PersonaName_Get( steamIDRecipient.GetAccountID() );
|
||||
// wchar_t wszPlayerName[MAX_PLAYER_NAME_LENGTH] = L"";
|
||||
// if ( pPlayerName != NULL && FStrEq( pPlayerName, "" ) == false )
|
||||
// {
|
||||
// g_pVGuiLocalize->ConvertANSIToUnicode( pPlayerName, wszPlayerName, sizeof(wszPlayerName) );
|
||||
// }
|
||||
// CEconNotification *pNotification = new CEconNotification();
|
||||
// pNotification->SetLifetime( 15.0f );
|
||||
//
|
||||
// if ( bIsValidRecipient )
|
||||
// {
|
||||
// pNotification->SetText( "#TF_HalloweenItem_Granted" );
|
||||
// pNotification->AddStringToken( "recipient", wszPlayerName );
|
||||
// pNotification->SetSteamID( steamIDRecipient );
|
||||
// pNotification->SetSoundFilename( "ui/halloween_loot_found.wav" );
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// pNotification->SetText( "#TF_HalloweenItem_GrantPickupFail" );
|
||||
// // pNotification->SetSoundFilename( "coach/coach_student_died.wav" );
|
||||
// }
|
||||
//
|
||||
// NotificationQueue_Add( pNotification );
|
||||
//
|
||||
// // is this the local player? award the achievement...
|
||||
// if ( steamapicontext && steamapicontext->SteamUser() )
|
||||
// {
|
||||
// CSteamID localSteamID = steamapicontext->SteamUser()->GetSteamID();
|
||||
// if ( steamIDRecipient == localSteamID )
|
||||
// {
|
||||
// g_AchievementMgrTF.OnAchievementEvent( ACHIEVEMENT_TF_HALLOWEEN_COLLECT_GOODY_BAG );
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// return true;
|
||||
// }
|
||||
//};
|
||||
//GC_REG_JOB( GCSDK::CGCClient, CGCHalloween_GrantedItemResponse, "CGCHalloween_GrantedItemResponse", k_EMsgGC_Halloween_GrantItemResponse, GCSDK::k_EServerTypeGCClient );
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
void CL_Halloween_LevelShutdown()
|
||||
{
|
||||
gHalloweenPickup = NULL;
|
||||
}
|
||||
@@ -0,0 +1,185 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
// NVNT haptic manager for tf2
|
||||
#include "cbase.h"
|
||||
#include "c_tf_haptics.h"
|
||||
#include "c_tf_player.h"
|
||||
// memdbgon must be the last include file in a .cpp file!!!
|
||||
#include "tier0/memdbgon.h"
|
||||
|
||||
// for full cloak effect
|
||||
extern ConVar tf_teammate_max_invis;
|
||||
|
||||
C_TFHaptics::C_TFHaptics()
|
||||
{
|
||||
memset(this, 0, sizeof(C_TFHaptics));
|
||||
}
|
||||
|
||||
void C_TFHaptics::Revert() {
|
||||
if ( haptics )
|
||||
{
|
||||
if(wasBeingHealed)
|
||||
{
|
||||
haptics->ProcessHapticEvent(2,"Game","being_healed_stop");
|
||||
}
|
||||
if(wasHealing)
|
||||
{
|
||||
haptics->ProcessHapticEvent(2,"Game","healing_stop");
|
||||
}
|
||||
if(wasUber)
|
||||
{
|
||||
haptics->ProcessHapticEvent(2, "Game", "uber_stop");
|
||||
}
|
||||
if(wasFullyCloaked)
|
||||
{
|
||||
haptics->ProcessHapticEvent(2, "Game", "cloak_full_stop");
|
||||
}
|
||||
if(wasCloaked)
|
||||
{
|
||||
haptics->ProcessHapticEvent(2, "Game", "cloak_stop");
|
||||
}
|
||||
if(wasBurning)
|
||||
{
|
||||
haptics->ProcessHapticEvent(2, "Game", "burning_stop");
|
||||
}
|
||||
}
|
||||
memset(this, 0, sizeof(C_TFHaptics));
|
||||
if ( haptics )
|
||||
{
|
||||
haptics->LocalPlayerReset();
|
||||
haptics->SetNavigationClass("on_foot");
|
||||
}
|
||||
}
|
||||
|
||||
void C_TFHaptics::HapticsThink(C_TFPlayer *player)
|
||||
{
|
||||
if ( !haptics )
|
||||
return;
|
||||
Assert(player!=C_TFPlayer::GetLocalPlayer());
|
||||
|
||||
{// being healed check
|
||||
C_TFPlayer *pHealer = NULL;
|
||||
float uberCharge = 0.0f;
|
||||
player->GetHealer(&pHealer,&uberCharge);
|
||||
if(pHealer)
|
||||
{
|
||||
if(!wasBeingHealedMedic && !healingDispenserCount)
|
||||
isBeingHealed = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
if(wasBeingHealedMedic && !healingDispenserCount)
|
||||
isBeingHealed = false;
|
||||
}
|
||||
wasBeingHealedMedic = pHealer!=NULL;
|
||||
if(isBeingHealed&&!wasBeingHealed&&haptics)
|
||||
haptics->ProcessHapticEvent(2,"Game","being_healed_start");
|
||||
else if(!isBeingHealed&&wasBeingHealed&&haptics)
|
||||
haptics->ProcessHapticEvent(2,"Game","being_healed_stop");
|
||||
|
||||
wasBeingHealed = isBeingHealed;
|
||||
}
|
||||
{// healing check
|
||||
C_BaseEntity *pHealTarget = player->MedicGetHealTarget();
|
||||
if(pHealTarget)
|
||||
{
|
||||
if(!wasHealing&&haptics)
|
||||
haptics->ProcessHapticEvent(2,"Game","healing_start");
|
||||
}
|
||||
else
|
||||
{
|
||||
if(wasHealing&&haptics)
|
||||
haptics->ProcessHapticEvent(2,"Game","healing_stop");
|
||||
}
|
||||
wasHealing = pHealTarget!=NULL;
|
||||
}
|
||||
//uber
|
||||
if(player->m_Shared.InCond( TF_COND_INVULNERABLE ) && !player->m_Shared.InCond( TF_COND_INVULNERABLE_WEARINGOFF ) )
|
||||
{
|
||||
if(!wasUber&&haptics)
|
||||
{
|
||||
haptics->ProcessHapticEvent(2, "Game", "uber_start");
|
||||
}
|
||||
}else{
|
||||
if(wasUber&&haptics)
|
||||
{
|
||||
haptics->ProcessHapticEvent(2, "Game", "uber_stop");
|
||||
}
|
||||
}
|
||||
//burning
|
||||
if(player->m_Shared.InCond( TF_COND_BURNING ) )
|
||||
{
|
||||
if(!wasBurning&&haptics)
|
||||
{
|
||||
haptics->ProcessHapticEvent(2, "Game", "burning_start");
|
||||
wasBurning = true;
|
||||
}
|
||||
}else{
|
||||
if(wasBurning)
|
||||
{
|
||||
haptics->ProcessHapticEvent(2, "Game", "burning_stop");
|
||||
wasBurning = false;
|
||||
}
|
||||
}
|
||||
//cloak
|
||||
// note: theres some weird stuff going on here.
|
||||
float cloakLevel = player->GetPercentInvisible();
|
||||
if(readyForCloak)
|
||||
{
|
||||
if(cloakLevel>0.0f)
|
||||
{
|
||||
if(!wasCloaked)
|
||||
{
|
||||
haptics->ProcessHapticEvent(2, "Game", "cloak_start");
|
||||
wasCloaked = true;
|
||||
}
|
||||
if(!wasFullyCloaked)
|
||||
{
|
||||
if(cloakLevel >= tf_teammate_max_invis.GetFloat())
|
||||
{
|
||||
haptics->ProcessHapticEvent(2, "Game", "cloak_full_start");
|
||||
wasFullyCloaked = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if(cloakLevel < tf_teammate_max_invis.GetFloat())
|
||||
{
|
||||
haptics->ProcessHapticEvent(2, "Game", "cloak_full_stop");
|
||||
wasFullyCloaked = false;
|
||||
}
|
||||
}
|
||||
}else{
|
||||
if(wasFullyCloaked)
|
||||
{
|
||||
haptics->ProcessHapticEvent(2, "Game", "cloak_full_stop");
|
||||
wasFullyCloaked = false;
|
||||
}
|
||||
if(wasCloaked)
|
||||
{
|
||||
haptics->ProcessHapticEvent(2, "Game", "cloak_stop");
|
||||
wasCloaked = false;
|
||||
}
|
||||
}
|
||||
}else{
|
||||
if(skippedFirstCloak)
|
||||
{
|
||||
if(cloakLevel==0.0f)
|
||||
readyForCloak = true;
|
||||
}else{
|
||||
if(cloakLevel!=0.0f)
|
||||
{
|
||||
skippedFirstCloak = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class C_TFHapticsInternal : public C_TFHaptics
|
||||
{
|
||||
public:
|
||||
C_TFHapticsInternal() : C_TFHaptics() {};
|
||||
};
|
||||
|
||||
static C_TFHapticsInternal tfInternalHaptics;
|
||||
|
||||
C_TFHaptics &tfHaptics = *((C_TFHaptics*)&tfInternalHaptics);
|
||||
@@ -0,0 +1,34 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
// NVNT haptics for Team Fortress 2
|
||||
#ifndef C_TF_HAPTICS_H
|
||||
#define C_TF_HAPTICS_H
|
||||
|
||||
class C_TFPlayer;
|
||||
|
||||
#include "haptics/haptic_utils.h"
|
||||
|
||||
class C_TFHaptics {
|
||||
protected:
|
||||
C_TFHaptics();
|
||||
public:
|
||||
bool wasCloaked : 1;
|
||||
bool wasFullyCloaked : 1;
|
||||
bool wasUber : 1;
|
||||
bool wasBurning :1;
|
||||
bool wasHealing : 1;
|
||||
bool isBeingHealed : 1;
|
||||
bool wasBeingHealed : 1;
|
||||
bool wasBeingHealedMedic : 1;
|
||||
bool wasBeingTeleported :1;
|
||||
bool skippedFirstCloak:1;
|
||||
bool readyForCloak:1;
|
||||
unsigned int healingDispenserCount:16;//short
|
||||
void Revert();
|
||||
// should only be local player!
|
||||
void HapticsThink(C_TFPlayer *player);
|
||||
};
|
||||
|
||||
extern C_TFHaptics &tfHaptics;
|
||||
|
||||
|
||||
#endif // C_TF_HAPTICS_H
|
||||
@@ -0,0 +1,9 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
//
|
||||
//
|
||||
//=============================================================================
|
||||
#include "cbase.h"
|
||||
#include "c_tf_mvm_boss_progress_user.h"
|
||||
|
||||
IMPLEMENT_AUTO_LIST( ITFMvMBossProgressUserAutoList );
|
||||
@@ -0,0 +1,18 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
//
|
||||
//
|
||||
//=============================================================================
|
||||
#ifndef C_TF_MVM_BOSS_HEALTH_USER_H
|
||||
#define C_TF_MVM_BOSS_HEALTH_USER_H
|
||||
|
||||
DECLARE_AUTO_LIST( ITFMvMBossProgressUserAutoList );
|
||||
|
||||
class C_TFMvMBossProgressUser : public ITFMvMBossProgressUserAutoList
|
||||
{
|
||||
public:
|
||||
virtual const char* GetBossProgressImageName() const { return NULL; }
|
||||
virtual float GetBossStatusProgress() const { return 0.f; }
|
||||
};
|
||||
|
||||
#endif // C_TF_MVM_BOSS_HEALTH_USER_H
|
||||
@@ -0,0 +1,237 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================//
|
||||
|
||||
#include "cbase.h"
|
||||
|
||||
#include "tf_notification.h"
|
||||
#include "c_tf_notification.h"
|
||||
#include "tf_gc_client.h"
|
||||
#include "econ/econ_notifications.h"
|
||||
|
||||
///
|
||||
/// Support message notification dialog
|
||||
///
|
||||
|
||||
class CTFSupportNotificationDialog : public CTFMessageBoxDialog
|
||||
{
|
||||
DECLARE_CLASS_SIMPLE( CTFSupportNotificationDialog, CTFMessageBoxDialog );
|
||||
public:
|
||||
CTFSupportNotificationDialog( int iNotificationID, const char *pszSupportMessage )
|
||||
: CTFMessageBoxDialog( NULL, pszSupportMessage, NULL, NULL, NULL )
|
||||
, m_iNotificationID( iNotificationID )
|
||||
, m_pConfirmDialog( NULL )
|
||||
{
|
||||
SetDialogVariable( "text", GetText() );
|
||||
}
|
||||
|
||||
void CleanupConfirmDialog()
|
||||
{
|
||||
if ( m_pConfirmDialog )
|
||||
{
|
||||
m_pConfirmDialog->SetVisible( false );
|
||||
m_pConfirmDialog->MarkForDeletion();
|
||||
m_pConfirmDialog = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
virtual ~CTFSupportNotificationDialog() {
|
||||
CleanupConfirmDialog();
|
||||
}
|
||||
|
||||
void ConfirmDialogCallback( bool bConfirmed )
|
||||
{
|
||||
CleanupConfirmDialog();
|
||||
|
||||
if ( bConfirmed )
|
||||
{
|
||||
// User acknowledged the message, tell the notification it can go away now
|
||||
CClientNotification *pNotification = dynamic_cast< CClientNotification * >( NotificationQueue_Get( m_iNotificationID ) );
|
||||
if ( pNotification )
|
||||
{
|
||||
pNotification->OnDialogAcknowledged();
|
||||
}
|
||||
|
||||
BaseClass::OnCommand( "confirm" );
|
||||
}
|
||||
}
|
||||
|
||||
static void StaticConfirmDialogCallback( bool bConfirmed, void *pContext )
|
||||
{
|
||||
static_cast< CTFSupportNotificationDialog * >( pContext )->ConfirmDialogCallback( bConfirmed );
|
||||
}
|
||||
|
||||
virtual void OnCommand( const char *command ) OVERRIDE
|
||||
{
|
||||
if ( FStrEq( "acknowledge", command ) )
|
||||
{
|
||||
// Confirm this, it's going away forever!
|
||||
CleanupConfirmDialog();
|
||||
m_pConfirmDialog = ShowConfirmDialog( "#DeleteConfirmDefault",
|
||||
"#TF_Support_Message_Confirm_Acknowledge_Text",
|
||||
"#TF_Support_Message_Acknowledge", "#Cancel",
|
||||
&StaticConfirmDialogCallback );
|
||||
m_pConfirmDialog->SetContext( this );
|
||||
return;
|
||||
}
|
||||
else if ( FStrEq( "show_later", command ) )
|
||||
{
|
||||
// User selected "show this later" -- leave notification as is and close.
|
||||
CleanupConfirmDialog();
|
||||
BaseClass::OnCommand( "confirm" );
|
||||
return;
|
||||
}
|
||||
|
||||
BaseClass::OnCommand( command );
|
||||
}
|
||||
|
||||
virtual const char *GetResFile() OVERRIDE
|
||||
{
|
||||
return "Resource/UI/SupportNotificationDialog.res";
|
||||
}
|
||||
|
||||
private:
|
||||
// Associated notification to clear
|
||||
int m_iNotificationID;
|
||||
CTFGenericConfirmDialog *m_pConfirmDialog;
|
||||
};
|
||||
|
||||
///
|
||||
/// The notification class
|
||||
///
|
||||
|
||||
CClientNotification::CClientNotification()
|
||||
{
|
||||
m_pText = NULL;
|
||||
m_flExpireTime = CRTime::RTime32TimeCur();
|
||||
m_ulNotificationID = 0;
|
||||
m_unAccountID = 0;
|
||||
m_bSupportMessage = false;
|
||||
}
|
||||
|
||||
CClientNotification::~CClientNotification()
|
||||
{}
|
||||
|
||||
void CClientNotification::Update( const CTFNotification* notification )
|
||||
{
|
||||
// Custom type handling. For now only support message does anything special.
|
||||
m_bSupportMessage = false;
|
||||
switch ( notification->Obj().type() )
|
||||
{
|
||||
case CMsgGCNotification_NotificationType_NOTIFICATION_REPORTED_PLAYER_BANNED:
|
||||
case CMsgGCNotification_NotificationType_NOTIFICATION_CUSTOM_STRING:
|
||||
case CMsgGCNotification_NotificationType_NOTIFICATION_MM_BAN_DUE_TO_EXCESSIVE_REPORTS:
|
||||
case CMsgGCNotification_NotificationType_NOTIFICATION_REPORTED_PLAYER_WAS_BANNED:
|
||||
// All identical.
|
||||
//
|
||||
// Really, the other types could be used to avoid having to send a localization string down? Otherwise
|
||||
// they're all just redundant with CUSTOM_STRING for now.
|
||||
break;
|
||||
case CMsgGCNotification_NotificationType_NOTIFICATION_SUPPORT_MESSAGE:
|
||||
m_bSupportMessage = true;
|
||||
break;
|
||||
default:
|
||||
Assert( !"Unhandled enum value" );
|
||||
}
|
||||
|
||||
m_pText = NULL;
|
||||
m_strText = notification->Obj().notification_string().c_str();
|
||||
|
||||
if ( m_bSupportMessage )
|
||||
{
|
||||
// Use generic notification, save actual notification contents for dialog
|
||||
m_pText = "#TF_Support_Message_Notification";
|
||||
}
|
||||
else
|
||||
{
|
||||
// Just use our message
|
||||
m_pText = m_strText.Get();
|
||||
}
|
||||
|
||||
// 0 -> does not expire
|
||||
RTime32 rtExpire = notification->Obj().expiration_time();
|
||||
m_flExpireTime = rtExpire > 0 ? (float)rtExpire : FLT_MAX;
|
||||
m_ulNotificationID = notification->Obj().notification_id();
|
||||
m_unAccountID = notification->Obj().account_id();
|
||||
|
||||
}
|
||||
|
||||
void CClientNotification::GCAcknowledge() {
|
||||
|
||||
GTFGCClientSystem()->AcknowledgeNotification( m_unAccountID, m_ulNotificationID );
|
||||
}
|
||||
|
||||
void CClientNotification::Deleted()
|
||||
{
|
||||
if ( m_bSupportMessage )
|
||||
{
|
||||
AssertMsg( !m_bSupportMessage,
|
||||
"Support messages should only be able to be triggered, not deleted" );
|
||||
return;
|
||||
}
|
||||
|
||||
GCAcknowledge();
|
||||
}
|
||||
|
||||
void CClientNotification::Expired()
|
||||
{
|
||||
// No action, we don't want de-sync'd client clock to acknowledge these incorrectly, GC will expire them on its end.
|
||||
}
|
||||
|
||||
CClientNotification::EType CClientNotification::NotificationType()
|
||||
{
|
||||
// Support messages are "must trigger" type -- no delete action, user must click "view"
|
||||
if ( m_bSupportMessage )
|
||||
{
|
||||
return eType_MustTrigger;
|
||||
}
|
||||
|
||||
return eType_Basic;
|
||||
}
|
||||
|
||||
bool CClientNotification::BHighPriority()
|
||||
{
|
||||
return m_bSupportMessage;
|
||||
}
|
||||
|
||||
void CClientNotification::Trigger()
|
||||
{
|
||||
if ( !m_bSupportMessage )
|
||||
{
|
||||
AssertMsg( m_bSupportMessage,
|
||||
"Don't expect to be trigger-able when not in support message mode" );
|
||||
return;
|
||||
}
|
||||
|
||||
CTFSupportNotificationDialog *pDialog = vgui::SETUP_PANEL( new CTFSupportNotificationDialog( GetID(), m_strText.Get() ) );
|
||||
pDialog->Show();
|
||||
}
|
||||
|
||||
void CClientNotification::OnDialogAcknowledged()
|
||||
{
|
||||
if ( !m_bSupportMessage )
|
||||
{
|
||||
AssertMsg( m_bSupportMessage,
|
||||
"Don't expect to be getting callbacks from the support message dialog when not in support message mode" );
|
||||
return;
|
||||
}
|
||||
|
||||
GCAcknowledge();
|
||||
MarkForDeletion();
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// CAutobalanceVolunteerNotification
|
||||
//-----------------------------------------------------------------------------
|
||||
void CAutobalanceVolunteerNotification::SendResponse( bool bResponse )
|
||||
{
|
||||
KeyValues *kv = new KeyValues( "AutoBalanceVolunteerReply" );
|
||||
kv->SetBool( "response", bResponse );
|
||||
engine->ServerCmdKeyValues( kv );
|
||||
|
||||
MarkForDeletion();
|
||||
}
|
||||
@@ -0,0 +1,72 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose: Interface for the client to acknowledge/view notifications sent from the GC
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================
|
||||
|
||||
#ifndef C_TF_NOTIFICATIONS_H
|
||||
#define C_TF_NOTIFICATIONS_H
|
||||
#ifdef _WIN32
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include "econ/econ_notifications.h"
|
||||
#include "tf_notification.h"
|
||||
|
||||
|
||||
class CClientNotification : public CEconNotification
|
||||
{
|
||||
friend class CTFSupportNotificationDialog;
|
||||
public:
|
||||
CClientNotification();
|
||||
virtual ~CClientNotification() OVERRIDE;
|
||||
|
||||
virtual EType NotificationType() OVERRIDE;
|
||||
virtual void Deleted() OVERRIDE;
|
||||
virtual void Expired() OVERRIDE;
|
||||
virtual void Trigger() OVERRIDE;
|
||||
|
||||
virtual bool BHighPriority() OVERRIDE;
|
||||
|
||||
// Should show up on the main menu only -- these go away on dismissal
|
||||
virtual bool BShowInGameElements() const OVERRIDE { return false; }
|
||||
|
||||
void Update( const CTFNotification* notification );
|
||||
uint64 NotificationID() const { return m_ulNotificationID; }
|
||||
|
||||
private:
|
||||
void OnDialogAcknowledged();
|
||||
void GCAcknowledge();
|
||||
|
||||
uint64 m_ulNotificationID;
|
||||
uint32 m_unAccountID;
|
||||
// m_pText sometimes points to a static string we don't own, so this guy owns any text that we do.
|
||||
CUtlString m_strText;
|
||||
|
||||
// Is this a support message? If so, the user must trigger the notification to view the message in a pop-up before they can dismiss.
|
||||
bool m_bSupportMessage;
|
||||
|
||||
};
|
||||
|
||||
class CAutobalanceVolunteerNotification : public CEconNotification
|
||||
{
|
||||
public:
|
||||
CAutobalanceVolunteerNotification() : CEconNotification() {}
|
||||
|
||||
virtual ~CAutobalanceVolunteerNotification() OVERRIDE {}
|
||||
|
||||
virtual bool BShowInGameElements() const OVERRIDE { return true; }
|
||||
virtual EType NotificationType() OVERRIDE { return eType_AcceptDecline; }
|
||||
|
||||
virtual void Accept() OVERRIDE { SendResponse( true ); }
|
||||
virtual void Decline() OVERRIDE { SendResponse( false ); }
|
||||
virtual void Expired() OVERRIDE { Decline(); }
|
||||
|
||||
static bool IsNotificationType( CEconNotification *pNotification ) { return dynamic_cast<CAutobalanceVolunteerNotification *>( pNotification ) != NULL; }
|
||||
|
||||
private:
|
||||
void SendResponse( bool bResponse );
|
||||
};
|
||||
|
||||
#endif // C_TF_NOTIFICATIONS_H
|
||||
@@ -0,0 +1,237 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose: Entity that propagates objective data
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================//
|
||||
#include "cbase.h"
|
||||
#include "clientmode_tf.h"
|
||||
#include "c_tf_objective_resource.h"
|
||||
|
||||
// memdbgon must be the last include file in a .cpp file!!!
|
||||
#include "tier0/memdbgon.h"
|
||||
|
||||
IMPLEMENT_CLIENTCLASS_DT( C_TFObjectiveResource, DT_TFObjectiveResource, CTFObjectiveResource)
|
||||
RecvPropInt( RECVINFO(m_nMannVsMachineMaxWaveCount) ),
|
||||
RecvPropInt( RECVINFO(m_nMannVsMachineWaveCount) ),
|
||||
RecvPropInt( RECVINFO(m_nMannVsMachineWaveEnemyCount) ),
|
||||
RecvPropInt( RECVINFO(m_nMvMWorldMoney) ),
|
||||
RecvPropFloat( RECVINFO( m_flMannVsMachineNextWaveTime ) ),
|
||||
RecvPropBool( RECVINFO( m_bMannVsMachineBetweenWaves ) ),
|
||||
RecvPropInt( RECVINFO(m_nFlagCarrierUpgradeLevel) ),
|
||||
RecvPropFloat( RECVINFO( m_flMvMBaseBombUpgradeTime ) ),
|
||||
RecvPropFloat( RECVINFO( m_flMvMNextBombUpgradeTime ) ),
|
||||
RecvPropString( RECVINFO( m_iszMvMPopfileName ) ),
|
||||
RecvPropInt( RECVINFO(m_iChallengeIndex) ),
|
||||
RecvPropInt( RECVINFO(m_nMvMEventPopfileType) ),
|
||||
|
||||
RecvPropArray3( RECVINFO_ARRAY( m_nMannVsMachineWaveClassCounts ), RecvPropInt( RECVINFO( m_nMannVsMachineWaveClassCounts[0] ) ) ),
|
||||
RecvPropArray( RecvPropString( RECVINFO( m_iszMannVsMachineWaveClassNames[0]) ), m_iszMannVsMachineWaveClassNames ),
|
||||
RecvPropArray3( RECVINFO_ARRAY( m_nMannVsMachineWaveClassFlags ), RecvPropInt( RECVINFO( m_nMannVsMachineWaveClassFlags[0] ) ) ),
|
||||
|
||||
RecvPropArray3( RECVINFO_ARRAY( m_nMannVsMachineWaveClassCounts2 ), RecvPropInt( RECVINFO( m_nMannVsMachineWaveClassCounts2[0] ) ) ),
|
||||
RecvPropArray( RecvPropString( RECVINFO( m_iszMannVsMachineWaveClassNames2[0]) ), m_iszMannVsMachineWaveClassNames2 ),
|
||||
RecvPropArray3( RECVINFO_ARRAY( m_nMannVsMachineWaveClassFlags2 ), RecvPropInt( RECVINFO( m_nMannVsMachineWaveClassFlags2[0] ) ) ),
|
||||
|
||||
RecvPropArray3( RECVINFO_ARRAY( m_bMannVsMachineWaveClassActive ), RecvPropBool( RECVINFO( m_bMannVsMachineWaveClassActive[0] ) ) ),
|
||||
RecvPropArray3( RECVINFO_ARRAY( m_bMannVsMachineWaveClassActive2 ), RecvPropBool( RECVINFO( m_bMannVsMachineWaveClassActive2[0] ) ) ),
|
||||
END_RECV_TABLE()
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
C_TFObjectiveResource::C_TFObjectiveResource()
|
||||
{
|
||||
PrecacheMaterial( "sprites/obj_icons/icon_obj_cap_blu" );
|
||||
PrecacheMaterial( "sprites/obj_icons/icon_obj_cap_blu_up" );
|
||||
PrecacheMaterial( "sprites/obj_icons/icon_obj_cap_red" );
|
||||
PrecacheMaterial( "sprites/obj_icons/icon_obj_cap_red_up" );
|
||||
PrecacheMaterial( "VGUI/flagtime_empty" );
|
||||
PrecacheMaterial( "VGUI/flagtime_full" );
|
||||
|
||||
m_nMannVsMachineMaxWaveCount = 0;
|
||||
m_nMannVsMachineWaveCount = 0;
|
||||
m_nMannVsMachineWaveEnemyCount = 0;
|
||||
m_nMvMWorldMoney = 0;
|
||||
m_flMannVsMachineNextWaveTime = 0;
|
||||
m_bMannVsMachineBetweenWaves = false;
|
||||
m_nFlagCarrierUpgradeLevel = 0;
|
||||
m_iChallengeIndex = -1;
|
||||
m_nMvMEventPopfileType = MVM_EVENT_POPFILE_NONE;
|
||||
|
||||
memset( m_nMannVsMachineWaveClassCounts, 0, sizeof( m_nMannVsMachineWaveClassCounts ) );
|
||||
memset( m_nMannVsMachineWaveClassCounts2, 0, sizeof( m_nMannVsMachineWaveClassCounts2 ) );
|
||||
memset( m_nMannVsMachineWaveClassFlags, MVM_CLASS_FLAG_NONE, sizeof( m_nMannVsMachineWaveClassFlags ) );
|
||||
memset( m_nMannVsMachineWaveClassFlags2, MVM_CLASS_FLAG_NONE, sizeof( m_nMannVsMachineWaveClassFlags2 ) );
|
||||
memset( m_bMannVsMachineWaveClassActive, 0, sizeof( m_bMannVsMachineWaveClassActive ) );
|
||||
memset( m_bMannVsMachineWaveClassActive2, 0, sizeof( m_bMannVsMachineWaveClassActive2 ) );
|
||||
|
||||
int i = 0;
|
||||
for ( i = 0 ; i < ARRAYSIZE( m_iszMannVsMachineWaveClassNames ) ; ++i )
|
||||
{
|
||||
m_iszMannVsMachineWaveClassNames[ i ][ 0 ] = '\0';
|
||||
}
|
||||
|
||||
for ( i = 0 ; i < ARRAYSIZE( m_iszMannVsMachineWaveClassNames2 ) ; ++i )
|
||||
{
|
||||
m_iszMannVsMachineWaveClassNames2[ i ][ 0 ] = '\0';
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
C_TFObjectiveResource::~C_TFObjectiveResource()
|
||||
{
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
const char *C_TFObjectiveResource::GetGameSpecificCPCappingSwipe( int index_, int iCappingTeam )
|
||||
{
|
||||
Assert( index_ < m_iNumControlPoints );
|
||||
Assert( iCappingTeam != TEAM_UNASSIGNED );
|
||||
|
||||
if ( iCappingTeam == TF_TEAM_RED )
|
||||
return "sprites/obj_icons/icon_obj_cap_red";
|
||||
|
||||
return "sprites/obj_icons/icon_obj_cap_blu";
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
const char *C_TFObjectiveResource::GetGameSpecificCPBarFG( int index_, int iOwningTeam )
|
||||
{
|
||||
Assert( index_ < m_iNumControlPoints );
|
||||
|
||||
if ( iOwningTeam == TF_TEAM_RED )
|
||||
return "progress_bar_red";
|
||||
|
||||
if ( iOwningTeam == TF_TEAM_BLUE )
|
||||
return "progress_bar_blu";
|
||||
|
||||
return "progress_bar";
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
const char *C_TFObjectiveResource::GetGameSpecificCPBarBG( int index_, int iCappingTeam )
|
||||
{
|
||||
Assert( index_ < m_iNumControlPoints );
|
||||
Assert( iCappingTeam != TEAM_UNASSIGNED );
|
||||
|
||||
if ( iCappingTeam == TF_TEAM_RED )
|
||||
return "progress_bar_red";
|
||||
|
||||
return "progress_bar_blu";
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void C_TFObjectiveResource::SetCappingTeam( int index_, int team )
|
||||
{
|
||||
//Display warning that someone is capping our point.
|
||||
//Only do this at the start of a cap and if WE own the point.
|
||||
//Also don't warn on a point that will do a "Last Point cap" warning.
|
||||
if ( GetNumControlPoints() > 0 && GetCapWarningLevel( index_ ) == CP_WARN_NORMAL && GetCPCapPercentage( index_ ) == 0.0f && team != TEAM_UNASSIGNED )
|
||||
{
|
||||
C_BasePlayer *pLocalPlayer = C_BasePlayer::GetLocalPlayer();
|
||||
if ( pLocalPlayer )
|
||||
{
|
||||
if ( pLocalPlayer->GetTeamNumber() != team )
|
||||
{
|
||||
CLocalPlayerFilter filter;
|
||||
if ( GetOwningTeam( index_ ) != TEAM_UNASSIGNED )
|
||||
{
|
||||
C_BaseEntity::EmitSound( filter, -1, "Announcer.ControlPointContested" );
|
||||
}
|
||||
else
|
||||
{
|
||||
C_BaseEntity::EmitSound( filter, -1, "Announcer.ControlPointContested_Neutral" );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
BaseClass::SetCappingTeam( index_, team );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
int C_TFObjectiveResource::GetMannVsMachineWaveClassCount( int nIndex )
|
||||
{
|
||||
if ( nIndex < ARRAYSIZE( m_nMannVsMachineWaveClassCounts ) )
|
||||
{
|
||||
return m_nMannVsMachineWaveClassCounts[ nIndex ];
|
||||
}
|
||||
nIndex -= ARRAYSIZE( m_nMannVsMachineWaveClassCounts );
|
||||
|
||||
if ( nIndex < ARRAYSIZE( m_nMannVsMachineWaveClassCounts2 ) )
|
||||
{
|
||||
return m_nMannVsMachineWaveClassCounts2[ nIndex ];
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
const char *C_TFObjectiveResource::GetMannVsMachineWaveClassName( int nIndex )
|
||||
{
|
||||
if ( nIndex < ARRAYSIZE( m_iszMannVsMachineWaveClassNames ) )
|
||||
{
|
||||
return m_iszMannVsMachineWaveClassNames[ nIndex ];
|
||||
}
|
||||
nIndex -= ARRAYSIZE( m_iszMannVsMachineWaveClassNames );
|
||||
|
||||
if ( nIndex < ARRAYSIZE( m_iszMannVsMachineWaveClassNames2 ) )
|
||||
{
|
||||
return m_iszMannVsMachineWaveClassNames2[ nIndex ];
|
||||
}
|
||||
|
||||
return "";
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
unsigned int C_TFObjectiveResource::GetMannVsMachineWaveClassFlags( int nIndex )
|
||||
{
|
||||
if ( nIndex < ARRAYSIZE( m_nMannVsMachineWaveClassFlags ) )
|
||||
{
|
||||
return m_nMannVsMachineWaveClassFlags[ nIndex ];
|
||||
}
|
||||
nIndex -= ARRAYSIZE( m_nMannVsMachineWaveClassFlags );
|
||||
|
||||
if ( nIndex < ARRAYSIZE( m_nMannVsMachineWaveClassFlags2 ) )
|
||||
{
|
||||
return m_nMannVsMachineWaveClassFlags2[ nIndex ];
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
bool C_TFObjectiveResource::GetMannVsMachineWaveClassActive( int nIndex )
|
||||
{
|
||||
if ( nIndex < ARRAYSIZE( m_bMannVsMachineWaveClassActive ) )
|
||||
{
|
||||
return m_bMannVsMachineWaveClassActive[ nIndex ];
|
||||
}
|
||||
nIndex -= ARRAYSIZE( m_bMannVsMachineWaveClassActive );
|
||||
|
||||
if ( nIndex < ARRAYSIZE( m_bMannVsMachineWaveClassActive2 ) )
|
||||
{
|
||||
return m_bMannVsMachineWaveClassActive2[ nIndex ];
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,87 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose: Entity that propagates general data needed by clients for every player.
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================//
|
||||
|
||||
#ifndef C_TF_OBJECTIVE_RESOURCE_H
|
||||
#define C_TF_OBJECTIVE_RESOURCE_H
|
||||
#ifdef _WIN32
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include "tf_shareddefs.h"
|
||||
#include "const.h"
|
||||
#include "c_baseentity.h"
|
||||
#include <igameresources.h>
|
||||
#include "c_team_objectiveresource.h"
|
||||
|
||||
class C_TFObjectiveResource : public C_BaseTeamObjectiveResource
|
||||
{
|
||||
DECLARE_CLASS( C_TFObjectiveResource, C_BaseTeamObjectiveResource );
|
||||
public:
|
||||
DECLARE_CLIENTCLASS();
|
||||
|
||||
C_TFObjectiveResource();
|
||||
virtual ~C_TFObjectiveResource();
|
||||
|
||||
const char *GetGameSpecificCPCappingSwipe( int index, int iCappingTeam );
|
||||
const char *GetGameSpecificCPBarFG( int index, int iOwningTeam );
|
||||
const char *GetGameSpecificCPBarBG( int index, int iCappingTeam );
|
||||
void SetCappingTeam( int index, int team );
|
||||
|
||||
int GetMannVsMachineMaxWaveCount( void ) { return m_nMannVsMachineMaxWaveCount; }
|
||||
int GetMannVsMachineWaveCount( void ) { return m_nMannVsMachineWaveCount; }
|
||||
int GetMannVsMachineWaveEnemyCount( void ) { return m_nMannVsMachineWaveEnemyCount; }
|
||||
int GetMvMInWorldMoney( void ) { return m_nMvMWorldMoney; }
|
||||
|
||||
float GetMannVsMachineNextWaveTime( void ) { return m_flMannVsMachineNextWaveTime; }
|
||||
bool GetMannVsMachineIsBetweenWaves( void ) { return m_bMannVsMachineBetweenWaves; }
|
||||
|
||||
int GetMannVsMachineWaveClassCount( int nIndex );
|
||||
const char *GetMannVsMachineWaveClassName( int nIndex );
|
||||
unsigned int GetMannVsMachineWaveClassFlags( int nIndex );
|
||||
bool GetMannVsMachineWaveClassActive( int nIndex );
|
||||
|
||||
int GetFlagCarrierUpgradeLevel( void ) { return m_nFlagCarrierUpgradeLevel; }
|
||||
float GetBaseMvMBombUpgradeTime( void ) { return m_flMvMBaseBombUpgradeTime; }
|
||||
float GetNextMvMBombUpgradeTime( void ) { return m_flMvMNextBombUpgradeTime; }
|
||||
|
||||
int GetMvMChallengeIndex ( void ) { return m_iChallengeIndex; }
|
||||
char * GetMvMPopFileName ( void ) { return m_iszMvMPopfileName; }
|
||||
int GetMvMEventPopfileType( void ) { return m_nMvMEventPopfileType; }
|
||||
|
||||
private:
|
||||
int m_nMannVsMachineMaxWaveCount;
|
||||
int m_nMannVsMachineWaveCount;
|
||||
int m_nMannVsMachineWaveEnemyCount;
|
||||
|
||||
int m_nMvMWorldMoney;
|
||||
|
||||
float m_flMannVsMachineNextWaveTime;
|
||||
bool m_bMannVsMachineBetweenWaves;
|
||||
|
||||
int m_nFlagCarrierUpgradeLevel;
|
||||
float m_flMvMBaseBombUpgradeTime;
|
||||
float m_flMvMNextBombUpgradeTime;
|
||||
int m_nMvMEventPopfileType;
|
||||
|
||||
int m_nMannVsMachineWaveClassCounts[ MVM_CLASS_TYPES_PER_WAVE_MAX ];
|
||||
int m_nMannVsMachineWaveClassCounts2[ MVM_CLASS_TYPES_PER_WAVE_MAX ];
|
||||
char m_iszMannVsMachineWaveClassNames[ MVM_CLASS_TYPES_PER_WAVE_MAX ][ 64 ];
|
||||
char m_iszMannVsMachineWaveClassNames2[ MVM_CLASS_TYPES_PER_WAVE_MAX ][ 64 ];
|
||||
int m_iChallengeIndex;
|
||||
char m_iszMvMPopfileName[ MAX_PATH ];
|
||||
unsigned int m_nMannVsMachineWaveClassFlags[ MVM_CLASS_TYPES_PER_WAVE_MAX ];
|
||||
unsigned int m_nMannVsMachineWaveClassFlags2[ MVM_CLASS_TYPES_PER_WAVE_MAX ];
|
||||
bool m_bMannVsMachineWaveClassActive[ MVM_CLASS_TYPES_PER_WAVE_MAX ];
|
||||
bool m_bMannVsMachineWaveClassActive2[ MVM_CLASS_TYPES_PER_WAVE_MAX ];
|
||||
};
|
||||
|
||||
inline C_TFObjectiveResource *TFObjectiveResource()
|
||||
{
|
||||
return static_cast<C_TFObjectiveResource*>(g_pObjectiveResource);
|
||||
}
|
||||
|
||||
#endif // C_TF_OBJECTIVE_RESOURCE_H
|
||||
@@ -0,0 +1,99 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================//
|
||||
|
||||
#include "cbase.h"
|
||||
#include "c_tf_passtime_ball.h"
|
||||
#include "passtime_convars.h"
|
||||
#include "tf_shareddefs.h"
|
||||
#include "c_tf_player.h"
|
||||
#include "c_playerresource.h"
|
||||
#include "c_tf_player.h"
|
||||
#include "tf_gamerules.h"
|
||||
|
||||
// memdbgon must be the last include file in a .cpp file!!!
|
||||
#include "tier0/memdbgon.h"
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
IMPLEMENT_CLIENTCLASS_DT( C_PasstimeBall, DT_PasstimeBall, CPasstimeBall )
|
||||
RecvPropInt(RECVINFO(m_iCollisionCount)),
|
||||
RecvPropEHandle(RECVINFO(m_hHomingTarget)),
|
||||
RecvPropEHandle(RECVINFO(m_hCarrier)),
|
||||
RecvPropEHandle(RECVINFO(m_hPrevCarrier)),
|
||||
END_RECV_TABLE()
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
LINK_ENTITY_TO_CLASS( passtime_ball, C_PasstimeBall );
|
||||
PRECACHE_REGISTER( passtime_ball );
|
||||
|
||||
C_TFPlayer *C_PasstimeBall::GetCarrier() { return m_hCarrier.Get(); }
|
||||
C_TFPlayer *C_PasstimeBall::GetPrevCarrier() { return m_hPrevCarrier.Get(); }
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
C_PasstimeBall::C_PasstimeBall()
|
||||
{
|
||||
UseClientSideAnimation();
|
||||
m_fDrawTime = 0.0f;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
C_PasstimeBall::~C_PasstimeBall()
|
||||
{
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
unsigned int C_PasstimeBall::PhysicsSolidMaskForEntity() const
|
||||
{
|
||||
return MASK_PLAYERSOLID; // must match server
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
bool C_PasstimeBall::ShouldCollide( int collisionGroup, int contentsMask ) const
|
||||
{
|
||||
// note: returning false for COLLISION_GROUP_PLAYER_MOVEMENT means the ball won't
|
||||
// stop player movement. the only real visible effect when this function doesn't
|
||||
// return false for COLLISION_GROUP_PLAYER_MOVEMENT is that the ball is unable
|
||||
// to impart physics forces on the ball when the ball is blocked, since the player
|
||||
// will set velocity to zero due to being "stuck" on the ball, even though the
|
||||
// ball won't actually prevent the player from moving through it.
|
||||
return (collisionGroup != COLLISION_GROUP_PLAYER_MOVEMENT);
|
||||
// && (contentsMask & MASK_SHOT_HULL);
|
||||
//return BaseClass::ShouldCollide( collisionGroup, contentsMask );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
void C_PasstimeBall::OnDataChanged( DataUpdateType_t updateType )
|
||||
{
|
||||
BaseClass::OnDataChanged( updateType );
|
||||
|
||||
if ( updateType == DATA_UPDATE_CREATED )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if ( TFGameRules()->IsPasstimeMode() )
|
||||
{
|
||||
bool bIsVisible = !(GetEffects() & EF_NODRAW);
|
||||
if ( bIsVisible && !m_bWasVisible )
|
||||
{
|
||||
float nextValidTime = gpGlobals->curtime + 0.1f;
|
||||
m_fDrawTime = nextValidTime;
|
||||
}
|
||||
m_bWasVisible = bIsVisible;
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
int C_PasstimeBall::DrawModel( int flags )
|
||||
{
|
||||
if( gpGlobals->curtime < m_fDrawTime )
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
return BaseClass::DrawModel( flags );
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================//
|
||||
|
||||
#ifndef C_TF_PASSTIME_BALL_H
|
||||
#define C_TF_PASSTIME_BALL_H
|
||||
#ifdef _WIN32
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include "predictable_entity.h"
|
||||
#include "util_shared.h"
|
||||
#include "c_baseanimating.h"
|
||||
#include "../shared/SpriteTrail.h"
|
||||
|
||||
class C_TFPlayer;
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
class C_PasstimeBall : public C_BaseAnimating
|
||||
{
|
||||
public:
|
||||
DECLARE_CLASS( C_PasstimeBall, C_BaseAnimating );
|
||||
DECLARE_NETWORKCLASS();
|
||||
C_PasstimeBall();
|
||||
virtual ~C_PasstimeBall();
|
||||
virtual void OnDataChanged( DataUpdateType_t updateType ) OVERRIDE;
|
||||
virtual int DrawModel( int flags ) OVERRIDE;
|
||||
virtual unsigned int PhysicsSolidMaskForEntity() const OVERRIDE;
|
||||
virtual bool ShouldCollide( int collisionGroup, int contentsMask ) const OVERRIDE;
|
||||
|
||||
virtual void AddDecal( const Vector& rayStart, const Vector& rayEnd,
|
||||
const Vector& decalCenter, int hitbox, int decalIndex, bool doTrace,
|
||||
trace_t& tr, int maxLODToDecal ) OVERRIDE { }// no decals ever
|
||||
|
||||
int GetCollisionCount() const { return m_iCollisionCount; }
|
||||
C_TFPlayer *GetHomingTarget() const { return m_hHomingTarget; }
|
||||
C_TFPlayer *GetCarrier();
|
||||
C_TFPlayer *GetPrevCarrier();
|
||||
|
||||
private:
|
||||
bool m_bWasVisible;
|
||||
float m_fDrawTime;
|
||||
CNetworkVar( int, m_iCollisionCount );
|
||||
CNetworkHandle( C_TFPlayer, m_hHomingTarget );
|
||||
CNetworkHandle( C_TFPlayer, m_hCarrier );
|
||||
CNetworkHandle( C_TFPlayer, m_hPrevCarrier );
|
||||
};
|
||||
|
||||
#endif // C_TF_PASSTIME_BALL_H
|
||||
@@ -0,0 +1,263 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================//
|
||||
|
||||
#include "cbase.h"
|
||||
#include "tempent.h"
|
||||
#include "c_tf_passtime_logic.h"
|
||||
#include "tf_hud_passtime_reticle.h"
|
||||
#include "passtime_convars.h"
|
||||
#include "passtime_game_events.h"
|
||||
#include "tf_shareddefs.h"
|
||||
#include "tf_classdata.h"
|
||||
#include "c_tf_player.h"
|
||||
#include "c_func_passtime_goal.h"
|
||||
|
||||
// memdbgon must be the last include file in a .cpp file!!!
|
||||
#include "tier0/memdbgon.h"
|
||||
|
||||
void C_TFPasstimeLogic::PostDataUpdate( DataUpdateType_t updateType )
|
||||
{
|
||||
BaseClass::PostDataUpdate( updateType );
|
||||
|
||||
if ( updateType == DATA_UPDATE_CREATED )
|
||||
{
|
||||
SetNextClientThink( CLIENT_THINK_ALWAYS );
|
||||
m_pBallReticle = new C_PasstimeBallReticle();
|
||||
m_pPassReticle = new C_PasstimePassReticle();
|
||||
for( auto *pGoal : C_FuncPasstimeGoal::GetAutoList() )
|
||||
{
|
||||
m_pGoalReticles.AddToTail( new C_PasstimeGoalReticle(
|
||||
static_cast<C_FuncPasstimeGoal*>( pGoal ) ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
C_TFPasstimeLogic* g_pPasstimeLogic;
|
||||
extern ConVar hud_fastswitch;
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
IMPLEMENT_CLIENTCLASS_DT( C_TFPasstimeLogic, DT_TFPasstimeLogic, CTFPasstimeLogic )
|
||||
RecvPropEHandle( RECVINFO( m_hBall ) ),
|
||||
RecvPropArray( RecvPropVector( RECVINFO( m_trackPoints[0] ) ), m_trackPoints ),
|
||||
RecvPropInt( RECVINFO( m_iNumSections ) ),
|
||||
RecvPropInt( RECVINFO( m_iCurrentSection ) ),
|
||||
RecvPropFloat( RECVINFO( m_flMaxPassRange ) ),
|
||||
RecvPropInt( RECVINFO( m_iBallPower ), 8 ),
|
||||
RecvPropFloat( RECVINFO( m_flPackSpeed ) ),
|
||||
RecvPropArray3( RECVINFO_ARRAY( m_bPlayerIsPackMember ), RecvPropInt( RECVINFO( m_bPlayerIsPackMember[0] ) ) ),
|
||||
END_RECV_TABLE()
|
||||
|
||||
LINK_ENTITY_TO_CLASS( passtime_logic, C_TFPasstimeLogic );
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
C_TFPasstimeLogic::C_TFPasstimeLogic()
|
||||
{
|
||||
m_pBallReticle = nullptr;
|
||||
m_pPassReticle = nullptr;
|
||||
memset( m_apPackBeams, 0, sizeof( m_apPackBeams ) );
|
||||
memset( m_bPlayerIsPackMember, 0, sizeof( m_bPlayerIsPackMember ) );
|
||||
for( int i = 0; i < m_trackPoints.Count(); ++i )
|
||||
{
|
||||
m_trackPoints.GetForModify(i).Zero();
|
||||
}
|
||||
|
||||
g_pPasstimeLogic = this;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
C_TFPasstimeLogic::~C_TFPasstimeLogic()
|
||||
{
|
||||
delete m_pBallReticle;
|
||||
m_pGoalReticles.PurgeAndDeleteElements();
|
||||
delete m_pPassReticle;
|
||||
|
||||
// Don't set g_pPasstimeLogic to null here because sometimes this destructor
|
||||
// happens after the contructor of the new object
|
||||
// FIXME: what's the right way to do this?
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
void C_TFPasstimeLogic::Spawn()
|
||||
{
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
void C_TFPasstimeLogic::ClientThink()
|
||||
{
|
||||
BaseClass::ClientThink();
|
||||
|
||||
SetNextClientThink( CLIENT_THINK_ALWAYS );
|
||||
m_pBallReticle->OnClientThink();
|
||||
for ( auto *pGoal : m_pGoalReticles )
|
||||
{
|
||||
pGoal->OnClientThink();
|
||||
}
|
||||
m_pPassReticle->OnClientThink();
|
||||
UpdateBeams();
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
void C_TFPasstimeLogic::DestroyBeams( C_PasstimeBall *pBall )
|
||||
{
|
||||
for ( CNewParticleEffect *pBeam : m_apPackBeams )
|
||||
{
|
||||
if ( pBeam )
|
||||
{
|
||||
pBall->ParticleProp()->StopEmission( pBeam );
|
||||
}
|
||||
}
|
||||
memset( m_apPackBeams, 0, sizeof( m_apPackBeams ) );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
void C_TFPasstimeLogic::DestroyBeam( int i, C_PasstimeBall *pBall )
|
||||
{
|
||||
CNewParticleEffect *pBeam = m_apPackBeams[i];
|
||||
if ( pBeam )
|
||||
{
|
||||
pBall->ParticleProp()->StopEmissionAndDestroyImmediately( pBeam );
|
||||
m_apPackBeams[i] = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
void C_TFPasstimeLogic::UpdateBeams()
|
||||
{
|
||||
C_PasstimeBall *pBall = GetBall();
|
||||
if ( !pBall )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
C_TFPlayer *pCarrier = pBall->GetCarrier();
|
||||
if ( !pCarrier )
|
||||
{
|
||||
DestroyBeams( pBall );
|
||||
return;
|
||||
}
|
||||
|
||||
const char *pEffectName = "passtime_beam";
|
||||
CParticleProperty *pParticles = pBall->ParticleProp();
|
||||
|
||||
for ( int i = 1; i <= MAX_PLAYERS; ++i )
|
||||
{
|
||||
if ( !m_bPlayerIsPackMember[i] )
|
||||
{
|
||||
DestroyBeam( i, pBall );
|
||||
continue;
|
||||
}
|
||||
|
||||
CTFPlayer *pPlayer = (CTFPlayer*) UTIL_PlayerByIndex( i );
|
||||
if ( !pPlayer || ( pPlayer == pCarrier ) || !pPlayer->IsAlive() )
|
||||
{
|
||||
DestroyBeam( i, pBall );
|
||||
continue;
|
||||
}
|
||||
|
||||
if ( !m_apPackBeams[i] )
|
||||
{
|
||||
CNewParticleEffect *pBeam = pParticles->Create( pEffectName, PATTACH_ABSORIGIN_FOLLOW );
|
||||
pParticles->AddControlPoint( pBeam, 1, pPlayer, PATTACH_ABSORIGIN_FOLLOW, 0, Vector(0,0,16) );
|
||||
m_apPackBeams[i] = pBeam;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
void C_TFPasstimeLogic::GetTrackPoints( Vector (&points)[16] )
|
||||
{
|
||||
memcpy( points, m_trackPoints.Base(), sizeof(points) );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
bool C_TFPasstimeLogic::GetImportantEntities( C_PasstimeBall **ppBall, C_TFPlayer **ppCarrier, C_TFPlayer **ppHomingTarget ) const
|
||||
{
|
||||
C_PasstimeBall *pBall = GetBall();
|
||||
if ( !pBall )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if ( ppBall )
|
||||
{
|
||||
*ppBall = pBall;
|
||||
}
|
||||
|
||||
if ( ppCarrier )
|
||||
{
|
||||
*ppCarrier = pBall->GetCarrier();
|
||||
}
|
||||
|
||||
if ( ppHomingTarget )
|
||||
{
|
||||
*ppHomingTarget = ToTFPlayer( pBall->GetHomingTarget() );
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
bool C_TFPasstimeLogic::GetBallReticleTarget( C_BaseEntity **ppEnt, bool *bHomingActive ) const
|
||||
{
|
||||
Assert( ppEnt );
|
||||
if ( !ppEnt )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
C_TFPlayer *pLocalPlayer = C_TFPlayer::GetLocalTFPlayer();
|
||||
if ( !pLocalPlayer )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
C_PasstimeBall *pBall = 0;
|
||||
C_TFPlayer *pCarrier = 0, *pHomingTarget = 0;
|
||||
if ( !GetImportantEntities( &pBall, &pCarrier, &pHomingTarget ) )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
C_BaseEntity *pEnt = pCarrier ? pCarrier : (C_BaseEntity*)pBall;
|
||||
if ( !pEnt
|
||||
|| (pEnt == pLocalPlayer)
|
||||
|| (pEnt->GetEffects() & EF_NODRAW)
|
||||
|| ((pEnt->GetTeamNumber() != TEAM_UNASSIGNED)
|
||||
&& (pEnt->GetTeamNumber() != pLocalPlayer->GetTeamNumber()))
|
||||
|| (pLocalPlayer->IsObserver() && (GetSpectatorMode() != OBS_MODE_ROAMING) && (GetSpectatorTarget() == pEnt->index)) )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
*ppEnt = pEnt;
|
||||
if ( bHomingActive )
|
||||
{
|
||||
*bHomingActive = pHomingTarget != 0;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
bool C_TFPasstimeLogic::BCanPlayerPickUpBall( C_TFPlayer *pPlayer ) const
|
||||
{
|
||||
return pPlayer
|
||||
&& pPlayer->IsAllowedToPickUpFlag()
|
||||
&& pPlayer->IsAlive() // NOTE: it's possible to be alive and dead at the same time
|
||||
&& !pPlayer->m_Shared.InCond( TF_COND_INVULNERABLE )
|
||||
&& !pPlayer->m_Shared.InCond( TF_COND_PHASE )
|
||||
&& !pPlayer->m_Shared.InCond( TF_COND_INVULNERABLE_WEARINGOFF )
|
||||
&& !pPlayer->m_Shared.InCond( TF_COND_SELECTED_TO_TELEPORT )
|
||||
&& !pPlayer->m_Shared.InCond( TF_COND_STEALTHED_BLINK )
|
||||
&& !pPlayer->m_Shared.InCond( TF_COND_TAUNTING )
|
||||
&& !pPlayer->m_Shared.InCond( TF_COND_HALLOWEEN_GHOST_MODE )
|
||||
&& !pPlayer->m_Shared.IsControlStunned()
|
||||
&& !pPlayer->m_Shared.IsStealthed()
|
||||
&& !pPlayer->m_Shared.IsCarryingObject();
|
||||
}
|
||||
|
||||
@@ -0,0 +1,70 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================//
|
||||
|
||||
#ifndef C_TF_PASSTIME_LOGIC_H
|
||||
#define C_TF_PASSTIME_LOGIC_H
|
||||
#ifdef _WIN32
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include "c_baseentity.h"
|
||||
#include "c_tf_passtime_ball.h"
|
||||
#include "utlvector.h"
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
class C_LocalTempEntity;
|
||||
class C_TFPlayer;
|
||||
class C_PasstimeReticle;
|
||||
class C_TFPasstimeLogic : public C_BaseEntity
|
||||
{
|
||||
public:
|
||||
DECLARE_CLASS( C_TFPasstimeLogic, C_BaseEntity );
|
||||
DECLARE_CLIENTCLASS();
|
||||
|
||||
C_TFPasstimeLogic();
|
||||
virtual ~C_TFPasstimeLogic();
|
||||
virtual void Spawn() OVERRIDE;
|
||||
virtual void ClientThink() OVERRIDE;
|
||||
virtual void PostDataUpdate( DataUpdateType_t updateType ) OVERRIDE;
|
||||
|
||||
C_PasstimeBall *GetBall() const { return m_hBall.Get(); }
|
||||
void GetTrackPoints( Vector (&points)[16] );
|
||||
int GetNumSections() const { return m_iNumSections; }
|
||||
int GetCurrentSection() const { return m_iCurrentSection; }
|
||||
|
||||
bool GetBallReticleTarget( C_BaseEntity **ppEnt, bool *bHomingActive ) const;
|
||||
bool BCanPlayerPickUpBall( C_TFPlayer *pPlayer ) const;
|
||||
|
||||
float GetMaxPassRange() const { return m_flMaxPassRange; }
|
||||
int GetBallPower() const { return m_iBallPower; }
|
||||
|
||||
private:
|
||||
bool GetImportantEntities( C_PasstimeBall **ppBall, C_TFPlayer **ppCarrier, C_TFPlayer **ppHomingTarget ) const;
|
||||
void DestroyBeam( int i, C_PasstimeBall *pBall );
|
||||
|
||||
void DestroyBeams( C_PasstimeBall *pBall );
|
||||
void UpdateBeams();
|
||||
|
||||
C_PasstimeReticle *m_pBallReticle;
|
||||
CUtlVector<C_PasstimeReticle*> m_pGoalReticles;
|
||||
C_PasstimeReticle *m_pPassReticle;
|
||||
CNewParticleEffect *m_apPackBeams[MAX_PLAYERS + 1];
|
||||
bool m_bPlayerIsPackMember[MAX_PLAYERS + 1];
|
||||
|
||||
CNetworkHandle( C_PasstimeBall, m_hBall );
|
||||
CNetworkArray( Vector, m_trackPoints, 16 );
|
||||
CNetworkVar( int, m_iNumSections );
|
||||
CNetworkVar( int, m_iCurrentSection );
|
||||
CNetworkVar( float, m_flMaxPassRange );
|
||||
CNetworkVar( int, m_iBallPower );
|
||||
CNetworkVar( float, m_flPackSpeed );
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
extern C_TFPasstimeLogic* g_pPasstimeLogic;
|
||||
|
||||
#endif // C_TF_PASSTIME_LOGIC_H
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,996 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
#ifndef C_TF_PLAYER_H
|
||||
#define C_TF_PLAYER_H
|
||||
#ifdef _WIN32
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include "tf_playeranimstate.h"
|
||||
#include "c_baseplayer.h"
|
||||
#include "tf_shareddefs.h"
|
||||
#include "baseparticleentity.h"
|
||||
#include "tf_player_shared.h"
|
||||
#include "c_tf_playerclass.h"
|
||||
#include "tf_item.h"
|
||||
#include "props_shared.h"
|
||||
#include "hintsystem.h"
|
||||
#include "c_playerattachedmodel.h"
|
||||
#include "c_playerrelativemodel.h"
|
||||
#include "iinput.h"
|
||||
#include "ihasattributes.h"
|
||||
#include "GameEventListener.h"
|
||||
#include "tf_item_inventory.h"
|
||||
#include "c_tf_mvm_boss_progress_user.h"
|
||||
#include "c_te_legacytempents.h"
|
||||
|
||||
|
||||
class C_MuzzleFlashModel;
|
||||
class C_BaseObject;
|
||||
class C_TFRagdoll;
|
||||
class C_TFWearable;
|
||||
class C_CaptureZone;
|
||||
class C_MerasmusBombEffect;
|
||||
class CTFReviveDialog;
|
||||
class C_TFDroppedWeapon;
|
||||
class C_PasstimePlayerReticle;
|
||||
class C_PasstimeAskForBallReticle;
|
||||
|
||||
extern ConVar tf_medigun_autoheal;
|
||||
extern ConVar cl_autorezoom;
|
||||
extern ConVar cl_autoreload;
|
||||
|
||||
enum EBonusEffectFilter_t
|
||||
{
|
||||
kEffectFilter_AttackerOnly,
|
||||
kEffectFilter_AttackerTeam,
|
||||
kEffectFilter_VictimOnly,
|
||||
kEffectFilter_VictimTeam,
|
||||
kEffectFilter_AttackerAndVictimOnly,
|
||||
kEffectFilter_BothTeams,
|
||||
};
|
||||
|
||||
struct BonusEffect_t
|
||||
{
|
||||
BonusEffect_t( const char* pszSoundName, const char* pszParticleName, EBonusEffectFilter_t eParticleFilter, EBonusEffectFilter_t eSoundFilter, bool bPlaySoundInAttackersEars )
|
||||
: m_pszSoundName( pszSoundName )
|
||||
, m_pszParticleName( pszParticleName )
|
||||
, m_eParticleFilter( eParticleFilter )
|
||||
, m_eSoundFilter( eSoundFilter )
|
||||
, m_bPlaySoundInAttackersEars( bPlaySoundInAttackersEars )
|
||||
|
||||
{}
|
||||
|
||||
const char* m_pszSoundName;
|
||||
const char* m_pszParticleName;
|
||||
EBonusEffectFilter_t m_eParticleFilter;
|
||||
EBonusEffectFilter_t m_eSoundFilter;
|
||||
bool m_bPlaySoundInAttackersEars;
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
class C_TFPlayer : public C_BasePlayer, public IHasAttributes, public IInventoryUpdateListener, public C_TFMvMBossProgressUser
|
||||
{
|
||||
public:
|
||||
|
||||
DECLARE_CLASS( C_TFPlayer, C_BasePlayer );
|
||||
DECLARE_CLIENTCLASS();
|
||||
DECLARE_PREDICTABLE();
|
||||
DECLARE_INTERPOLATION();
|
||||
|
||||
C_TFPlayer();
|
||||
~C_TFPlayer();
|
||||
|
||||
virtual void Spawn();
|
||||
|
||||
static C_TFPlayer* GetLocalTFPlayer();
|
||||
|
||||
virtual void UpdateOnRemove( void );
|
||||
|
||||
virtual const QAngle& GetRenderAngles();
|
||||
virtual void UpdateClientSideAnimation();
|
||||
virtual void SetDormant( bool bDormant );
|
||||
virtual void OnPreDataChanged( DataUpdateType_t updateType );
|
||||
virtual void OnDataChanged( DataUpdateType_t updateType );
|
||||
virtual void ProcessMuzzleFlashEvent();
|
||||
virtual void ValidateModelIndex( void );
|
||||
void Touch( CBaseEntity *pOther );
|
||||
|
||||
virtual Vector GetObserverCamOrigin( void );
|
||||
virtual int DrawModel( int flags );
|
||||
|
||||
virtual void ApplyBoneMatrixTransform( matrix3x4_t& transform );
|
||||
virtual void BuildTransformations( CStudioHdr *hdr, Vector *pos, Quaternion q[], const matrix3x4_t& cameraTransform, int boneMask, CBoneBitList &boneComputed );
|
||||
|
||||
virtual bool CreateMove( float flInputSampleTime, CUserCmd *pCmd ) OVERRIDE;
|
||||
void CreateVehicleMove( float flInputSampleTime, CUserCmd *pCmd );
|
||||
|
||||
virtual bool IsAllowedToSwitchWeapons( void );
|
||||
|
||||
void StopViewModelParticles( C_BaseEntity *pParticleEnt );
|
||||
|
||||
virtual void ClientThink();
|
||||
|
||||
// Deal with recording
|
||||
virtual void GetToolRecordingState( KeyValues *msg );
|
||||
|
||||
CTFWeaponBase *GetActiveTFWeapon( void ) const;
|
||||
bool IsActiveTFWeapon( CEconItemDefinition *weaponHandle ) const;
|
||||
bool IsActiveTFWeapon( const CSchemaItemDefHandle &weaponHandle ) const;
|
||||
|
||||
virtual void Simulate( void );
|
||||
virtual void FireEvent( const Vector& origin, const QAngle& angles, int event, const char *options ) OVERRIDE;
|
||||
virtual void UpdateStepSound( surfacedata_t *psurface, const Vector &vecOrigin, const Vector &vecVelocity ) OVERRIDE;
|
||||
|
||||
CNewParticleEffect *SpawnHalloweenSpellFootsteps( ParticleAttachment_t eParticleAttachment, int iHalloweenFootstepType );
|
||||
|
||||
void FireBullet( CTFWeaponBase *pWpn, const FireBulletsInfo_t &info, bool bDoEffects, int nDamageType, int nCustomDamageType = TF_DMG_CUSTOM_NONE );
|
||||
|
||||
void ImpactWaterTrace( trace_t &trace, const Vector &vecStart );
|
||||
|
||||
bool CanAttack( int iCanAttackFlags = 0 );
|
||||
|
||||
const C_TFPlayerClass *GetPlayerClass( void ) const { return &m_PlayerClass; }
|
||||
C_TFPlayerClass *GetPlayerClass( void ) { return &m_PlayerClass; }
|
||||
bool IsPlayerClass( int iClass ) const;
|
||||
virtual int GetMaxHealth( void ) const;
|
||||
int GetMaxHealthForBuffing() const;
|
||||
|
||||
virtual int GetRenderTeamNumber( void );
|
||||
|
||||
bool IsWeaponLowered( void );
|
||||
|
||||
void AvoidPlayers( CUserCmd *pCmd );
|
||||
|
||||
bool IsABot( void );
|
||||
|
||||
// Get the ID target entity index. The ID target is the player that is behind our crosshairs, used to
|
||||
// display the player's name.
|
||||
void UpdateIDTarget();
|
||||
int GetIDTarget() const;
|
||||
void SetForcedIDTarget( int iTarget );
|
||||
|
||||
void SetAnimation( PLAYER_ANIM playerAnim );
|
||||
|
||||
virtual float GetMinFOV() const;
|
||||
|
||||
virtual const QAngle& EyeAngles();
|
||||
|
||||
bool ShouldDrawSpyAsDisguised();
|
||||
virtual int GetBody( void );
|
||||
|
||||
int GetBuildResources( void );
|
||||
|
||||
// MATTTODO: object selection if necessary
|
||||
void SetSelectedObject( C_BaseObject *pObject ) {}
|
||||
|
||||
void GetTeamColor( Color &color );
|
||||
bool InSameDisguisedTeam( CBaseEntity *pEnt );
|
||||
|
||||
virtual void ComputeFxBlend( void );
|
||||
|
||||
// Taunts/VCDs
|
||||
virtual bool StartSceneEvent( CSceneEventInfo *info, CChoreoScene *scene, CChoreoEvent *event, CChoreoActor *actor, C_BaseEntity *pTarget );
|
||||
virtual bool ClearSceneEvent( CSceneEventInfo *info, bool fastKill, bool canceled );
|
||||
virtual void CalcView( Vector &eyeOrigin, QAngle &eyeAngles, float &zNear, float &zFar, float &fov );
|
||||
bool StartGestureSceneEvent( CSceneEventInfo *info, CChoreoScene *scene, CChoreoEvent *event, CChoreoActor *actor, CBaseEntity *pTarget );
|
||||
bool StopGestureSceneEvent( CSceneEventInfo *info, bool fastKill, bool canceled );
|
||||
void TurnOnTauntCam( void );
|
||||
void TurnOnTauntCam_Finish( void );
|
||||
void TurnOffTauntCam( void );
|
||||
void TurnOffTauntCam_Finish( void );
|
||||
bool IsTaunting( void ) const { return m_Shared.InCond( TF_COND_TAUNTING ); }
|
||||
|
||||
virtual void InitPhonemeMappings();
|
||||
|
||||
// Gibs.
|
||||
void InitPlayerGibs( void );
|
||||
void CheckAndUpdateGibType( void );
|
||||
void CreatePlayerGibs( const Vector &vecOrigin, const Vector &vecVelocity, float flImpactScale, bool bBurning, bool bWearableGibs=false, bool bOnlyHead=false, bool bDisguiseGibs=false );
|
||||
void DropPartyHat( breakablepropparams_t &breakParams, Vector &vecBreakVelocity );
|
||||
void DropWearable( C_TFWearable *pItem, const breakablepropparams_t ¶ms );
|
||||
|
||||
int GetObjectCount( void );
|
||||
C_BaseObject *GetObject( int index );
|
||||
C_BaseObject *GetObjectOfType( int iObjectType, int iObjectMode=0 ) const;
|
||||
int GetNumObjects( int iObjectType, int iObjectMode=0 );
|
||||
|
||||
virtual bool ShouldCollide( int collisionGroup, int contentsMask ) const;
|
||||
|
||||
float GetPercentInvisible( void );
|
||||
float GetEffectiveInvisibilityLevel( void ); // takes viewer into account
|
||||
virtual bool IsTransparent( void ) OVERRIDE { return GetPercentInvisible() > 0.f; }
|
||||
|
||||
virtual void AddDecal( const Vector& rayStart, const Vector& rayEnd,
|
||||
const Vector& decalCenter, int hitbox, int decalIndex, bool doTrace, trace_t& tr, int maxLODToDecal = ADDDECAL_TO_ALL_LODS );
|
||||
|
||||
virtual void CalcDeathCamView(Vector& eyeOrigin, QAngle& eyeAngles, float& fov);
|
||||
virtual Vector GetChaseCamViewOffset( CBaseEntity *target );
|
||||
virtual Vector GetDeathViewPosition();
|
||||
|
||||
void ClientPlayerRespawn( void );
|
||||
|
||||
virtual bool ShouldDraw();
|
||||
|
||||
virtual int GetVisionFilterFlags( bool bWeaponsCheck = false );
|
||||
virtual void CalculateVisionUsingCurrentFlags( void );
|
||||
|
||||
void CreateSaveMeEffect( MedicCallerType nType = CALLER_TYPE_NORMAL );
|
||||
void StopSaveMeEffect( bool bForceRemoveInstantly = false );
|
||||
|
||||
void CreateTauntWithMeEffect();
|
||||
void StopTauntWithMeEffect();
|
||||
|
||||
void CreateKart();
|
||||
void RemoveKart();
|
||||
C_BaseAnimating *GetKart() const { return m_pKart; }
|
||||
void CreateKartEffect( const char *pszEffectName );
|
||||
void StopKartEffect();
|
||||
void UpdateKartSounds();
|
||||
void StartKartBrakeEffect();
|
||||
void StopKartBrakeEffect();
|
||||
CNetworkVar( int, m_iKartState );
|
||||
|
||||
bool IsAllowedToTaunt( void );
|
||||
|
||||
virtual bool IsOverridingViewmodel( void );
|
||||
virtual int DrawOverriddenViewmodel( C_BaseViewModel *pViewmodel, int flags );
|
||||
|
||||
void SetHealer( C_TFPlayer *pHealer, float flChargeLevel );
|
||||
void SetWasHealedByLocalPlayer( bool bState ) { m_bWasHealedByLocalPlayer = bState; }
|
||||
void GetHealer( C_TFPlayer **pHealer, float *flChargeLevel ) { *pHealer = m_hHealer; *flChargeLevel = m_flHealerChargeLevel; }
|
||||
bool GetWasHealedByLocalPlayer() { return m_bWasHealedByLocalPlayer; }
|
||||
float MedicGetChargeLevel( CTFWeaponBase **pRetMedigun = NULL );
|
||||
bool MedicIsReleasingCharge( void );
|
||||
CBaseEntity *MedicGetHealTarget( void );
|
||||
|
||||
void StartBurningSound( void );
|
||||
void StopBurningSound( void );
|
||||
|
||||
void StopBlastJumpLoopSound( int iUserID );
|
||||
|
||||
void UpdateSpyStateChange( void );
|
||||
|
||||
void UpdateRecentlyTeleportedEffect( void );
|
||||
void UpdateOverhealEffect( void );
|
||||
void UpdatedMarkedForDeathEffect( bool bFroceStop = false );
|
||||
void CreateOverhealEffect( int iTeam );
|
||||
void UpdateRuneIcon( bool bForceStop = false );
|
||||
|
||||
bool CanShowClassMenu( void );
|
||||
bool CanShowTeamMenu( void );
|
||||
|
||||
void InitializePoseParams( void );
|
||||
void UpdateLookAt( void );
|
||||
|
||||
bool IsEnemyPlayer( void );
|
||||
void ShowNemesisIcon( bool bShow );
|
||||
void ShowDuelingIcon( bool bShow );
|
||||
void ShowIconForIT( bool bShow );
|
||||
|
||||
#ifdef STAGING_ONLY
|
||||
void UpdateTranqMark( bool bShow, bool bForceStop = false );
|
||||
void UpdateSpyClassStealParticle( bool bShow );
|
||||
#endif // STAGING_ONLY
|
||||
void ShowBirthdayEffect( bool bShow );
|
||||
|
||||
CUtlVector<EHANDLE> *GetSpawnedGibs( void ) { return &m_hSpawnedGibs; }
|
||||
|
||||
bool HasBombinomiconEffectOnDeath( void );
|
||||
|
||||
Vector GetClassEyeHeight( void );
|
||||
|
||||
void ForceUpdateObjectHudState( void );
|
||||
|
||||
bool GetMedigunAutoHeal( void ){ return tf_medigun_autoheal.GetBool(); }
|
||||
bool ShouldAutoRezoom( void ){ return cl_autorezoom.GetBool(); }
|
||||
bool ShouldAutoReload( void ){ return cl_autoreload.GetBool(); }
|
||||
|
||||
void GetTargetIDDataString( bool bIsDisguised, OUT_Z_BYTECAP(iMaxLenInBytes) wchar_t *sDataString, int iMaxLenInBytes, bool &bIsAmmoData, bool &bIsKillStreakData );
|
||||
|
||||
void RemoveDisguise( void );
|
||||
bool CanDisguise( void );
|
||||
bool CanDisguise_OnKill( void );
|
||||
|
||||
virtual void OnAchievementAchieved( int iAchievement );
|
||||
|
||||
virtual void OverrideView( CViewSetup *pSetup );
|
||||
|
||||
bool CanAirDash( void ) const;
|
||||
bool CanGetWet() const;
|
||||
|
||||
void CreateBoneAttachmentsFromWearables( C_TFRagdoll *pRagdoll, bool bDisguised );
|
||||
|
||||
bool CanUseFirstPersonCommand( void );
|
||||
|
||||
bool IsEffectRateLimited( EBonusEffectFilter_t effect, const C_TFPlayer* pAttacker ) const;
|
||||
bool ShouldPlayEffect( EBonusEffectFilter_t filter, const C_TFPlayer* pAttacker, const C_TFPlayer* pVictim ) const;
|
||||
virtual void FireGameEvent( IGameEvent *event );
|
||||
|
||||
virtual const char* ModifyEventParticles( const char* token );
|
||||
|
||||
// Set the distances the camera should use.
|
||||
void SetTauntCameraTargets( float back, float up );
|
||||
|
||||
// TF-specific color values for GlowEffect
|
||||
virtual void GetGlowEffectColor( float *r, float *g, float *b );
|
||||
void UpdateGlowColor( void );
|
||||
|
||||
virtual const Vector& GetRenderOrigin( void );
|
||||
|
||||
RTime32 GetSpottedInPVSTime() const { return m_rtSpottedInPVSTime; }
|
||||
RTime32 GetJoinedSpectatorTeamTime() const { return m_rtJoinedSpectatorTeam; }
|
||||
RTime32 GetJoinedNormalTeamTime() const { return m_rtJoinedNormalTeam; }
|
||||
|
||||
// IHasAttributes
|
||||
CAttributeManager *GetAttributeManager( void ) { return &m_AttributeManager; }
|
||||
CAttributeContainer *GetAttributeContainer( void ) { return NULL; }
|
||||
CBaseEntity *GetAttributeOwner( void ) { return NULL; }
|
||||
CAttributeList *GetAttributeList( void ) { return &m_AttributeList; }
|
||||
virtual void ReapplyProvision( void ) { return; }
|
||||
|
||||
// ITFMvMBossProgressUser
|
||||
virtual const char* GetBossProgressImageName() const OVERRIDE;
|
||||
virtual float GetBossStatusProgress() const OVERRIDE;
|
||||
|
||||
protected:
|
||||
CNetworkVarEmbedded( CAttributeContainerPlayer, m_AttributeManager );
|
||||
|
||||
// IClientNetworkable implementation.
|
||||
public:
|
||||
virtual void NotifyShouldTransmit( ShouldTransmitState_t state );
|
||||
|
||||
public:
|
||||
// Shared functions
|
||||
float GetMovementForwardPull( void ) const;
|
||||
bool CanPlayerMove() const;
|
||||
float TeamFortress_CalculateMaxSpeed( bool bIgnoreSpecialAbility = false ) const;
|
||||
void TeamFortress_SetSpeed();
|
||||
bool HasItem( void ) const; // Currently can have only one item at a time.
|
||||
void SetItem( C_TFItem *pItem );
|
||||
C_TFItem *GetItem( void ) const;
|
||||
bool HasTheFlag( ETFFlagType exceptionTypes[] = NULL, int nNumExceptions = 0 ) const;
|
||||
virtual bool IsAllowedToPickUpFlag( void ) const;
|
||||
float GetCritMult( void ) { return m_Shared.GetCritMult(); }
|
||||
|
||||
virtual void ItemPostFrame( void );
|
||||
|
||||
void SetOffHandWeapon( CTFWeaponBase *pWeapon );
|
||||
void HolsterOffHandWeapon( void );
|
||||
CTFWeaponBase* GetOffHandWeapon( void ) { return m_hOffHandWeapon; }
|
||||
|
||||
void GetActiveSets( CUtlVector<const CEconItemSetDefinition *> *pItemSets );
|
||||
|
||||
virtual int GetSkin();
|
||||
|
||||
float GetLastDamageTime( void ) const { return m_flLastDamageTime; }
|
||||
|
||||
virtual bool Weapon_CanSwitchTo( CBaseCombatWeapon *pWeapon );
|
||||
|
||||
virtual bool Weapon_ShouldSetLast( CBaseCombatWeapon *pOldWeapon, CBaseCombatWeapon *pNewWeapon ) OVERRIDE;
|
||||
virtual bool Weapon_Switch( C_BaseCombatWeapon *pWeapon, int viewmodelindex = 0 ) OVERRIDE;
|
||||
virtual void SelectItem( const char *pstr, int iSubType = 0 ) OVERRIDE;
|
||||
|
||||
virtual void UpdateWearables() OVERRIDE;
|
||||
CTFWearable *GetEquippedWearableForLoadoutSlot( int iLoadoutSlot );
|
||||
CBaseEntity *GetEntityForLoadoutSlot( int iLoadoutSlot ); //Gets whatever entity is associated with the loadout slot (wearable or weapon)
|
||||
|
||||
CTFWeaponBase *Weapon_OwnsThisID( int iWeaponID ) const;
|
||||
CTFWeaponBase *Weapon_GetWeaponByType( int iType );
|
||||
|
||||
virtual void GetStepSoundVelocities( float *velwalk, float *velrun );
|
||||
virtual void SetStepSoundTime( stepsoundtimes_t iStepSoundTime, bool bWalking );
|
||||
virtual const char *GetOverrideStepSound( const char *pszBaseStepSoundName );
|
||||
|
||||
virtual void OnEmitFootstepSound( const CSoundParameters& params, const Vector& vecOrigin, float fVolume );
|
||||
|
||||
virtual void ModifyEmitSoundParams( EmitSound_t ¶ms );
|
||||
|
||||
virtual void ThirdPersonSwitch( bool bThirdperson );
|
||||
|
||||
bool DoClassSpecialSkill( void );
|
||||
bool EndClassSpecialSkill( void );
|
||||
bool CanGoInvisible( bool bAllowWhileCarryingFlag = false );
|
||||
int GetMaxAmmo( int iAmmoIndex, int iClassIndex = -1 );
|
||||
|
||||
//-----------------------------------------------------------------------------------------------------
|
||||
// Return true if we are a "mini boss" in Mann Vs Machine mode
|
||||
bool IsMiniBoss( void ) const;
|
||||
bool ShouldTauntHintIconBeVisible() const;
|
||||
virtual bool IsHealthBarVisible( void ) const OVERRIDE;
|
||||
|
||||
bool CanStartPhase( void );
|
||||
|
||||
bool CanPickupBuilding( CBaseObject *pPickupObject );
|
||||
bool TryToPickupBuilding( void );
|
||||
void StartBuildingObjectOfType( int iType, int iObjectMode=0 );
|
||||
|
||||
void FeignDeath( CTakeDamageInfo& info );
|
||||
|
||||
C_CaptureZone *GetCaptureZoneStandingOn( void );
|
||||
C_CaptureZone *GetClosestCaptureZone( void );
|
||||
|
||||
float GetMetersRan( void ) { return m_fMetersRan; }
|
||||
void SetMetersRan( float fMeters, int iFrame );
|
||||
|
||||
CEconItemView *GetInspectItem( int *iLastItem );
|
||||
|
||||
void SetBodygroupsDirty( void );
|
||||
void RecalcBodygroupsIfDirty( void );
|
||||
|
||||
bool CanMoveDuringTaunt();
|
||||
bool ShouldStopTaunting();
|
||||
bool IsTauntForceMovingForward() const { return m_bTauntForceMoveForward; }
|
||||
float GetTauntMoveAcceleration() const { return m_flTauntMoveAccelerationTime; }
|
||||
float GetTauntMoveSpeed() const { return m_flTauntForceMoveForwardSpeed; }
|
||||
float GetTauntTurnAccelerationTime() const { return m_flTauntTurnAccelerationTime; }
|
||||
bool IsReadyToTauntWithPartner( void ) const { return m_bIsReadyToHighFive; }
|
||||
CTFPlayer * GetTauntPartner( void ) { return m_hHighFivePartner; }
|
||||
float GetTauntYaw( void ) { return m_flTauntYaw; }
|
||||
float GetPrevTauntYaw( void ) { return m_flPrevTauntYaw; }
|
||||
void SetTauntYaw( float flTauntYaw );
|
||||
int GetActiveTauntSlot() const { return m_nActiveTauntSlot; }
|
||||
void PlayTauntSoundLoop( const char *pszSoundLoopName );
|
||||
void StopTauntSoundLoop();
|
||||
float GetCurrentTauntMoveSpeed() const { return m_flCurrentTauntMoveSpeed; }
|
||||
void SetCurrentTauntMoveSpeed( float flSpeed ) { m_flCurrentTauntMoveSpeed = flSpeed; }
|
||||
float GetVehicleReverseTime() const { return m_flVehicleReverseTime; }
|
||||
void SetVehicleReverseTime( float flTime ) { m_flVehicleReverseTime = flTime; }
|
||||
|
||||
CEconItemView *GetTauntEconItemView() { return m_TauntEconItemView.IsValid() ? &m_TauntEconItemView : NULL; }
|
||||
|
||||
float GetHeadScale() const { return m_flHeadScale; }
|
||||
float GetTorsoScale() const { return m_flTorsoScale; }
|
||||
float GetHandScale() const { return m_flHandScale; }
|
||||
float GetLastResistTime() const { return m_flLastResistTime; }
|
||||
bool BRenderAsZombie( bool bWeaponsCheck = false );
|
||||
static void AdjustSkinIndexForZombie( int iClassIndex, int &iSkinIndex );
|
||||
|
||||
// Ragdolls.
|
||||
virtual C_BaseAnimating *BecomeRagdollOnClient();
|
||||
virtual IRagdoll *GetRepresentativeRagdoll() const;
|
||||
EHANDLE m_hRagdoll;
|
||||
Vector m_vecRagdollVelocity;
|
||||
|
||||
// Objects
|
||||
int CanBuild( int iObjectType, int iObjectMode=0 );
|
||||
CUtlVector< CHandle<C_BaseObject> > m_aObjects;
|
||||
|
||||
virtual CStudioHdr *OnNewModel( void );
|
||||
|
||||
void DisplaysHintsForTarget( C_BaseEntity *pTarget );
|
||||
|
||||
// Shadows
|
||||
virtual ShadowType_t ShadowCastType( void ) ;
|
||||
virtual void GetShadowRenderBounds( Vector &mins, Vector &maxs, ShadowType_t shadowType );
|
||||
virtual void GetRenderBounds( Vector& theMins, Vector& theMaxs );
|
||||
virtual bool GetShadowCastDirection( Vector *pDirection, ShadowType_t shadowType ) const;
|
||||
|
||||
CMaterialReference *GetInvulnMaterialRef( void ) { return &m_InvulnerableMaterial; }
|
||||
bool IsNemesisOfLocalPlayer();
|
||||
bool ShouldShowDuelingIcon();
|
||||
bool ShouldShowNemesisIcon();
|
||||
|
||||
virtual IMaterial *GetHeadLabelMaterial( void );
|
||||
|
||||
// Spy Cigarette
|
||||
bool CanLightCigarette( void );
|
||||
|
||||
void UpdateDemomanEyeEffect( int iDecapitations );
|
||||
const char* GetDemomanEyeEffectName( int iDecapitations );
|
||||
|
||||
int GetCurrency( void ){ return m_nCurrency; }
|
||||
|
||||
virtual void UpdateMVMEyeGlowEffect( bool bVisible );
|
||||
|
||||
void UpdateKillStreakEffects( int iCount, bool bKillScored = false );
|
||||
const char *GetEyeGlowEffect() { return m_pszEyeGlowEffectName; }
|
||||
Vector GetEyeGlowColor( bool bAlternate ) { return bAlternate? m_vEyeGlowColor1 : m_vEyeGlowColor2 ; }
|
||||
|
||||
// Bounty Mode
|
||||
int GetExperienceLevel( void ) { return m_nExperienceLevel; }
|
||||
|
||||
// Matchmaking
|
||||
bool GetMatchSafeToLeave() { return m_bMatchSafeToLeave; }
|
||||
|
||||
// Halloween silliness.
|
||||
void HalloweenBombHeadUpdate( void );
|
||||
|
||||
|
||||
bool IsUsingVRHeadset( void ){ return m_bUsingVRHeadset; }
|
||||
|
||||
bool ShouldPlayerDrawParticles( void );
|
||||
|
||||
bool IsPlayerOnSteamFriendsList( C_BasePlayer *pPlayer );
|
||||
|
||||
protected:
|
||||
|
||||
void ResetFlexWeights( CStudioHdr *pStudioHdr );
|
||||
|
||||
virtual void CalcInEyeCamView( Vector& eyeOrigin, QAngle& eyeAngles, float& fov );
|
||||
|
||||
virtual void UpdateGlowEffect( void );
|
||||
virtual void DestroyGlowEffect( void );
|
||||
|
||||
private:
|
||||
|
||||
bool ShouldShowPowerupGlowEffect();
|
||||
void GetPowerupGlowEffectColor( float *r, float *g, float *b );
|
||||
|
||||
void HandleTaunting( void );
|
||||
void TauntCamInterpolation( void );
|
||||
|
||||
void OnPlayerClassChange( void );
|
||||
void UpdatePartyHat( void );
|
||||
|
||||
void InitInvulnerableMaterial( void );
|
||||
|
||||
void GetHorriblyHackedRailgunPosition( const Vector& vStart, Vector *out_pvStartPos );
|
||||
void MaybeDrawRailgunBeam( IRecipientFilter *pFilter, CTFWeaponBase *pWeapon, const Vector& vStartPos, const Vector& vEndPos );
|
||||
|
||||
bool m_bWasTaunting;
|
||||
bool m_bTauntInterpolating;
|
||||
CameraThirdData_t m_TauntCameraData;
|
||||
float m_flTauntCamCurrentDist;
|
||||
float m_flTauntCamTargetDist;
|
||||
float m_flTauntCamCurrentDistUp;
|
||||
float m_flTauntCamTargetDistUp;
|
||||
|
||||
QAngle m_angTauntPredViewAngles;
|
||||
QAngle m_angTauntEngViewAngles;
|
||||
|
||||
CSoundPatch *m_pTauntSoundLoop;
|
||||
|
||||
C_TFPlayerClass m_PlayerClass;
|
||||
|
||||
// ID Target
|
||||
int m_iIDEntIndex;
|
||||
int m_iForcedIDTarget;
|
||||
|
||||
CNewParticleEffect *m_pTeleporterEffect;
|
||||
bool m_bToolRecordingVisibility;
|
||||
|
||||
int m_iOldSpawnCounter;
|
||||
|
||||
// Healer
|
||||
CHandle<C_TFPlayer> m_hHealer;
|
||||
bool m_bWasHealedByLocalPlayer;
|
||||
float m_flHealerChargeLevel;
|
||||
int m_iOldHealth;
|
||||
int m_nOldMaxHealth;
|
||||
|
||||
float m_fMetersRan;
|
||||
int m_iLastRanFrame;
|
||||
|
||||
HPARTICLEFFECT m_pEyeEffect;
|
||||
|
||||
bool m_bOldCustomModelVisible;
|
||||
|
||||
CHandle< C_BaseCombatWeapon > m_hOldActiveWeapon;
|
||||
|
||||
// Look At
|
||||
/*
|
||||
int m_headYawPoseParam;
|
||||
int m_headPitchPoseParam;
|
||||
float m_headYawMin;
|
||||
float m_headYawMax;
|
||||
float m_headPitchMin;
|
||||
float m_headPitchMax;
|
||||
float m_flLastBodyYaw;
|
||||
float m_flCurrentHeadYaw;
|
||||
float m_flCurrentHeadPitch;
|
||||
*/
|
||||
|
||||
// Spy cigarette smoke
|
||||
bool m_bCigaretteSmokeActive;
|
||||
|
||||
// Medic callout particle effect
|
||||
CNewParticleEffect *m_pSaveMeEffect;
|
||||
CNewParticleEffect *m_pTauntWithMeEffect;
|
||||
|
||||
bool m_bUpdateObjectHudState;
|
||||
bool m_bBodygroupsDirty;
|
||||
|
||||
HPARTICLEFFECT m_hKartDamageEffect;
|
||||
CNetworkVar( float, m_flKartNextAvailableBoost );
|
||||
CNetworkVar( int, m_iKartHealth );
|
||||
int m_iOldKartHealth;
|
||||
void UpdateKartEffects();
|
||||
|
||||
void UpdateKartState();
|
||||
int m_iOldKartState;
|
||||
|
||||
C_BaseAnimating *m_pKart;
|
||||
|
||||
public:
|
||||
float GetKartSpeedBoost( void );
|
||||
float GetKartHealth( void ) { return m_iKartHealth; }
|
||||
|
||||
CTFPlayerShared m_Shared;
|
||||
friend class CTFPlayerShared;
|
||||
|
||||
// Called by shared code.
|
||||
public:
|
||||
float GetClassChangeTime() const { return m_flChangeClassTime; }
|
||||
void SetFootStamps( int nFootStamps ) { m_nFootStamps = nFootStamps; }
|
||||
|
||||
void DoAnimationEvent( PlayerAnimEvent_t event, int nData = 0 );
|
||||
bool PlayAnimEventInPrediction( PlayerAnimEvent_t event );
|
||||
|
||||
bool GetPredictable( void ) const;
|
||||
|
||||
// Halloween
|
||||
void CreateBombonomiconHint();
|
||||
void DestroyBombonomiconHint();
|
||||
|
||||
void CleanUpAnimationOnSpawn();
|
||||
CTFPlayerAnimState *m_PlayerAnimState;
|
||||
|
||||
QAngle m_angEyeAngles;
|
||||
CInterpolatedVar< QAngle > m_iv_angEyeAngles;
|
||||
|
||||
CNetworkHandle( C_TFItem, m_hItem );
|
||||
|
||||
CNetworkHandle( C_TFWeaponBase, m_hOffHandWeapon );
|
||||
CNetworkHandle( C_TFPlayer, m_hCoach );
|
||||
CNetworkHandle( C_TFPlayer, m_hStudent );
|
||||
|
||||
CGlowObject *m_pStudentGlowEffect;
|
||||
CGlowObject *m_pPowerupGlowEffect;
|
||||
|
||||
int m_iOldPlayerClass; // Used to detect player class changes
|
||||
bool m_bIsDisplayingNemesisIcon;
|
||||
bool m_bIsDisplayingDuelingIcon;
|
||||
bool m_bIsDisplayingIconForIT;
|
||||
bool m_bIsDisplayingTranqMark;
|
||||
bool m_bShouldShowBirthdayEffect;
|
||||
|
||||
RuneTypes_t m_eDisplayingRuneIcon;
|
||||
|
||||
float m_flLastDamageTime;
|
||||
|
||||
bool m_bInPowerPlay;
|
||||
|
||||
int m_iSpawnCounter;
|
||||
bool m_bArenaSpectator;
|
||||
|
||||
bool m_bIsMiniBoss;
|
||||
bool m_bIsABot;
|
||||
int m_nBotSkill;
|
||||
int m_nOldBotSkill;
|
||||
bool m_bSaveMeParity;
|
||||
bool m_bOldSaveMeParity;
|
||||
bool m_bIsCoaching;
|
||||
|
||||
private:
|
||||
void UpdateTauntItem();
|
||||
void ParseSharedTauntDataFromEconItemView( CEconItemView *pEconItemView );
|
||||
|
||||
bool m_bAllowMoveDuringTaunt;
|
||||
bool m_bTauntForceMoveForward;
|
||||
float m_flTauntForceMoveForwardSpeed;
|
||||
float m_flTauntMoveAccelerationTime;
|
||||
float m_flTauntTurnSpeed;
|
||||
float m_flTauntTurnAccelerationTime;
|
||||
bool m_bIsReadyToHighFive;
|
||||
CNetworkHandle( C_TFPlayer, m_hHighFivePartner );
|
||||
int m_nForceTauntCam;
|
||||
float m_flTauntYaw;
|
||||
float m_flPrevTauntYaw;
|
||||
int m_nActiveTauntSlot;
|
||||
int m_nPrevTauntSlot;
|
||||
item_definition_index_t m_iTauntItemDefIndex;
|
||||
item_definition_index_t m_iPrevTauntItemDefIndex;
|
||||
float m_flCurrentTauntMoveSpeed;
|
||||
float m_flVehicleReverseTime;
|
||||
|
||||
int m_nTauntSequence;
|
||||
float m_flTauntStartTime;
|
||||
float m_flTauntDuration;
|
||||
|
||||
CEconItemView m_TauntEconItemView;
|
||||
|
||||
public:
|
||||
|
||||
int m_nOldWaterLevel;
|
||||
float m_flWaterEntryTime;
|
||||
bool m_bWaterExitEffectActive;
|
||||
|
||||
bool m_bDuckJumpInterp;
|
||||
float m_flFirstDuckJumpInterp;
|
||||
float m_flLastDuckJumpInterp;
|
||||
float m_flDuckJumpInterp;
|
||||
|
||||
CMaterialReference m_InvulnerableMaterial;
|
||||
|
||||
|
||||
// Burning
|
||||
CSoundPatch *m_pBurningSound;
|
||||
HPARTICLEFFECT m_pBurningEffect;
|
||||
float m_flBurnEffectStartTime;
|
||||
|
||||
// Urine
|
||||
HPARTICLEFFECT m_pUrineEffect;
|
||||
|
||||
// Milk
|
||||
HPARTICLEFFECT m_pMilkEffect;
|
||||
|
||||
// Soldier Buff
|
||||
HPARTICLEFFECT m_pSoldierOffensiveBuffEffect;
|
||||
HPARTICLEFFECT m_pSoldierDefensiveBuffEffect;
|
||||
HPARTICLEFFECT m_pSoldierOffensiveHealthRegenBuffEffect;
|
||||
HPARTICLEFFECT m_pSoldierNoHealingDamageBuffEffect;
|
||||
|
||||
// Speed boost
|
||||
HPARTICLEFFECT m_pSpeedBoostEffect;
|
||||
|
||||
// Taunt effects
|
||||
HPARTICLEFFECT m_pTauntEffect;
|
||||
|
||||
// Temp HACK for crit boost
|
||||
HPARTICLEFFECT m_pCritBoostEffect;
|
||||
|
||||
HPARTICLEFFECT m_pOverHealedEffect;
|
||||
HPARTICLEFFECT m_pPhaseStandingEffect;
|
||||
|
||||
HPARTICLEFFECT m_pStunnedEffect;
|
||||
|
||||
HPARTICLEFFECT m_pMegaHealEffect;
|
||||
HPARTICLEFFECT m_pRadiusHealEffect;
|
||||
HPARTICLEFFECT m_pKingRuneRadiusEffect;
|
||||
HPARTICLEFFECT m_pKingBuffRadiusEffect;
|
||||
HPARTICLEFFECT m_pRunePlagueEffect;
|
||||
C_LocalTempEntity* m_pTempShield;
|
||||
float m_flLastResistTime;
|
||||
|
||||
HPARTICLEFFECT m_pSappedPlayerEffect;
|
||||
HPARTICLEFFECT m_pMVMEyeGlowEffect[ 2 ];
|
||||
|
||||
// KillStreak Weapons
|
||||
char m_pszEyeGlowEffectName[MAX_PATH];
|
||||
Vector m_vEyeGlowColor1;
|
||||
Vector m_vEyeGlowColor2;
|
||||
HPARTICLEFFECT m_pEyeGlowEffect[ 2 ];
|
||||
float m_flNextSheenStartTime;
|
||||
|
||||
HPARTICLEFFECT m_pMVMBotRadiowave;
|
||||
|
||||
HPARTICLEFFECT m_pRuneChargeReadyEffect;
|
||||
|
||||
#ifdef STAGING_ONLY
|
||||
HPARTICLEFFECT m_pRocketPackEffect;
|
||||
#endif // STAGING_ONLY
|
||||
|
||||
enum EKartParticles
|
||||
{
|
||||
KART_PARTICLE_LEFT_LIGHT = 0,
|
||||
KART_PARTICLE_RIGHT_LIGHT,
|
||||
|
||||
KART_PARTICLE_LEFT_WHEEL,
|
||||
KART_PARTICLE_RIGHT_WHEEL,
|
||||
NUM_KART_PARTICLES
|
||||
};
|
||||
HPARTICLEFFECT m_pKartParticles[ NUM_KART_PARTICLES ];
|
||||
|
||||
enum EKartSounds
|
||||
{
|
||||
KART_SOUND_ENGINE_LOOP = 0,
|
||||
KART_SOUND_BURNOUT_LOOP,
|
||||
|
||||
NUM_KART_SOUNDS,
|
||||
};
|
||||
CSoundPatch *m_pKartSounds[ NUM_KART_SOUNDS ];
|
||||
|
||||
CNewParticleEffect *m_pDisguisingEffect;
|
||||
float m_flDisguiseEffectStartTime;
|
||||
float m_flDisguiseEndEffectStartTime;
|
||||
|
||||
EHANDLE m_hFirstGib;
|
||||
EHANDLE m_hHeadGib;
|
||||
CUtlVector<EHANDLE> m_hSpawnedGibs;
|
||||
|
||||
int m_iOldTeam;
|
||||
int m_iOldClass;
|
||||
int m_iOldDisguiseTeam;
|
||||
int m_iOldDisguiseClass;
|
||||
int m_iOldObserverMode;
|
||||
EHANDLE m_hOldObserverTarget;
|
||||
|
||||
bool m_bDisguised;
|
||||
int m_iPreviousMetal;
|
||||
|
||||
int GetNumActivePipebombs( void );
|
||||
|
||||
int m_iSpyMaskBodygroup;
|
||||
Vector m_vecCustomModelOrigin;
|
||||
|
||||
// Halloween
|
||||
CHandle<C_PlayerAttachedModel> m_hHalloweenBombHat;
|
||||
CHandle<C_MerasmusBombEffect> m_hBombonomiconHint;
|
||||
CHandle<C_PlayerAttachedModel> m_hHalloweenKartCage;
|
||||
float m_flBombDelay;
|
||||
|
||||
// Achievements
|
||||
float m_flSaveMeExpireTime;
|
||||
|
||||
//CountdownTimer m_LeaveServerTimer;
|
||||
|
||||
//----------------------------
|
||||
// INVENTORY MANAGEMENT
|
||||
public:
|
||||
// IInventoryUpdateListener
|
||||
virtual void InventoryUpdated( CPlayerInventory *pInventory );
|
||||
virtual void SOCacheUnsubscribed( const CSteamID & steamIDOwner ) { m_Shared.SetLoadoutUnavailable( true ); }
|
||||
void UpdateInventory( bool bInit );
|
||||
|
||||
// Inventory access
|
||||
CTFPlayerInventory *Inventory( void ) { return &m_Inventory; }
|
||||
|
||||
bool CanDisplayAllSeeEffect( EAttackBonusEffects_t effect ) const;
|
||||
void SetNextAllSeeEffectTime( EAttackBonusEffects_t effect, float flTime );
|
||||
|
||||
private:
|
||||
CTFPlayerInventory m_Inventory;
|
||||
bool m_bInventoryReceived;
|
||||
|
||||
private:
|
||||
float m_flChangeClassTime;
|
||||
|
||||
float m_flWaterImpactTime;
|
||||
RTime32 m_rtSpottedInPVSTime;
|
||||
RTime32 m_rtJoinedSpectatorTeam;
|
||||
RTime32 m_rtJoinedNormalTeam;
|
||||
|
||||
// Gibs.
|
||||
CUtlVector< int > m_aSillyGibs;
|
||||
CUtlVector< char* > m_aNormalGibs;
|
||||
CUtlVector<breakmodel_t> m_aGibs;
|
||||
|
||||
C_TFPlayer( const C_TFPlayer & );
|
||||
|
||||
mutable char m_bIsCalculatingMaximumSpeed;
|
||||
|
||||
// In-game currency
|
||||
int m_nCurrency;
|
||||
int m_nOldCurrency;
|
||||
|
||||
// Bounty Mode
|
||||
int m_nExperienceLevel;
|
||||
int m_nExperienceLevelProgress;
|
||||
int m_nPrevExperienceLevel;
|
||||
|
||||
// Matchmaking
|
||||
// is this player bound to the match on penalty of abandon. Sync'd via local-player-only DT
|
||||
bool m_bMatchSafeToLeave;
|
||||
|
||||
// Medic healtarget active weapon ammo/clip count
|
||||
uint16 m_nActiveWpnClip;
|
||||
|
||||
// Blast jump whistle
|
||||
CSoundPatch *m_pBlastJumpLoop;
|
||||
float m_flBlastJumpLaunchTime;
|
||||
|
||||
CNetworkVar( float, m_flHeadScale );
|
||||
CNetworkVar( float, m_flTorsoScale );
|
||||
CNetworkVar( float, m_flHandScale );
|
||||
|
||||
// Allseecrit throttle - other clients ask us if we can be the source of another particle+sound
|
||||
float m_flNextMiniCritEffectTime[ kBonusEffect_Count ];
|
||||
|
||||
CNetworkVar( bool, m_bUseBossHealthBar );
|
||||
|
||||
CNetworkVar( bool, m_bUsingVRHeadset );
|
||||
|
||||
CNetworkVar( bool, m_bForcedSkin );
|
||||
CNetworkVar( int, m_nForcedSkin );
|
||||
|
||||
int m_nFootStamps;
|
||||
|
||||
vgui::DHANDLE< CTFReviveDialog > m_hRevivePrompt;
|
||||
|
||||
public:
|
||||
void SetShowHudMenuTauntSelection( bool bShow ) { m_bShowHudMenuTauntSelection = bShow; }
|
||||
bool ShouldShowHudMenuTauntSelection() const { return m_bShowHudMenuTauntSelection; }
|
||||
|
||||
private:
|
||||
bool m_bShowHudMenuTauntSelection;
|
||||
|
||||
public:
|
||||
CBaseEntity *GetGrapplingHookTarget() const { return m_hGrapplingHookTarget; }
|
||||
|
||||
bool IsUsingActionSlot() const { return m_bUsingActionSlot; }
|
||||
void SetUsingActionSlot( bool bUsingActionSlot ) { m_bUsingActionSlot = bUsingActionSlot; }
|
||||
|
||||
void SetSecondaryLastWeapon( CBaseCombatWeapon *pSecondaryLastWeapon ) { m_hSecondaryLastWeapon = pSecondaryLastWeapon; }
|
||||
CBaseCombatWeapon* GetSecondaryLastWeapon() const { return m_hSecondaryLastWeapon; }
|
||||
|
||||
bool CanPickupDroppedWeapon( const C_TFDroppedWeapon *pWeapon );
|
||||
C_TFDroppedWeapon* GetDroppedWeaponInRange();
|
||||
|
||||
bool HasCampaignMedal( int iMedal );
|
||||
CampaignMedalDisplayType_t GetCampaignMedalType( void );
|
||||
const char *GetCampaignMedalImage( void );
|
||||
|
||||
void SetInspectTime( float flInspectTime ) { m_flInspectTime = flInspectTime; }
|
||||
bool IsInspecting() const;
|
||||
void HandleInspectHint();
|
||||
|
||||
bool AddOverheadEffect( const char *pszEffectName );
|
||||
void RemoveOverheadEffect( const char *pszEffectName, bool bRemoveInstantly );
|
||||
void UpdateOverheadEffects();
|
||||
Vector GetOverheadEffectPosition();
|
||||
|
||||
int GetSkinOverride() const { return m_iPlayerSkinOverride; }
|
||||
|
||||
private:
|
||||
CNetworkHandle( CBaseEntity, m_hGrapplingHookTarget );
|
||||
CNetworkHandle( CBaseCombatWeapon, m_hSecondaryLastWeapon );
|
||||
CNetworkVar( bool, m_bUsingActionSlot );
|
||||
CNetworkVar( int, m_iCampaignMedals );
|
||||
CNetworkVar( float, m_flInspectTime );
|
||||
|
||||
bool m_bNotifiedWeaponInspectThisLife;
|
||||
|
||||
C_PasstimePlayerReticle *m_pPasstimePlayerReticle;
|
||||
C_PasstimeAskForBallReticle *m_pPasstimeAskForBallReticle;
|
||||
|
||||
CUtlMap< const char *, HPARTICLEFFECT > m_mapOverheadEffects;
|
||||
float m_flOverheadEffectStartTime;
|
||||
|
||||
CNetworkVar( int, m_iPlayerSkinOverride );
|
||||
};
|
||||
|
||||
inline C_TFPlayer* ToTFPlayer( C_BaseEntity *pEntity )
|
||||
{
|
||||
if ( !pEntity || !pEntity->IsPlayer() )
|
||||
return NULL;
|
||||
|
||||
Assert( dynamic_cast<C_TFPlayer*>( pEntity ) != 0 );
|
||||
return static_cast< C_TFPlayer* >( pEntity );
|
||||
}
|
||||
|
||||
void SetAppropriateCamera( C_TFPlayer *pPlayer );
|
||||
|
||||
class C_TFPlayerPreviewEffect
|
||||
{
|
||||
public:
|
||||
// If you re-order this list, please update TF_ImportPreview_Effect* in tf_english.txt
|
||||
enum PREVIEW_EFFECT
|
||||
{
|
||||
PREVIEW_EFFECT_NONE,
|
||||
PREVIEW_EFFECT_UBER,
|
||||
//PREVIEW_EFFECT_CRIT, // Punting on particle effects for now
|
||||
PREVIEW_EFFECT_URINE,
|
||||
//PREVIEW_EFFECT_MILK, // Punting on particle effects for now
|
||||
//PREVIEW_EFFECT_INVIS, // The CMDLPanel draw path doesn't handle transparency at the moment
|
||||
PREVIEW_EFFECT_BURN,
|
||||
NUM_PREVIEW_EFFECTS
|
||||
};
|
||||
|
||||
public:
|
||||
C_TFPlayerPreviewEffect();
|
||||
|
||||
void SetEffect(PREVIEW_EFFECT nEffect) { m_nPreviewEffect = nEffect; }
|
||||
PREVIEW_EFFECT GetEffect() const { return m_nPreviewEffect; }
|
||||
|
||||
void SetTeam(int nTeam);
|
||||
int GetTeam() const { return m_nTeam; }
|
||||
|
||||
CMaterialReference *GetInvulnMaterialRef( void ) { return &m_InvulnerableMaterial; }
|
||||
|
||||
void Reset();
|
||||
|
||||
protected:
|
||||
PREVIEW_EFFECT m_nPreviewEffect;
|
||||
int m_nTeam;
|
||||
CMaterialReference m_InvulnerableMaterial;
|
||||
};
|
||||
extern C_TFPlayerPreviewEffect g_PlayerPreviewEffect;
|
||||
|
||||
#endif // C_TF_PLAYER_H
|
||||
@@ -0,0 +1,23 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
#ifndef C_TF_PLAYERCLASS_H
|
||||
#define C_TF_PLAYERCLASS_H
|
||||
#ifdef _WIN32
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include "tf_playerclass_shared.h"
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// TF Player Class
|
||||
//-----------------------------------------------------------------------------
|
||||
class C_TFPlayerClass : public CTFPlayerClassShared
|
||||
{
|
||||
public:
|
||||
|
||||
C_TFPlayerClass() {}
|
||||
};
|
||||
|
||||
#endif // C_TF_PLAYERCLASS_H
|
||||
@@ -0,0 +1,337 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose: TF's custom C_PlayerResource
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================//
|
||||
#include "cbase.h"
|
||||
#include "c_tf_playerresource.h"
|
||||
#include <shareddefs.h>
|
||||
#include <tf_shareddefs.h>
|
||||
#include "hud.h"
|
||||
#include "tf_gamerules.h"
|
||||
#include "tf_gc_client.h"
|
||||
#include "tf_lobby_server.h"
|
||||
|
||||
// memdbgon must be the last include file in a .cpp file!!!
|
||||
#include "tier0/memdbgon.h"
|
||||
|
||||
extern ConVar tf_mvm_respec_limit;
|
||||
extern ConVar tf_mvm_buybacks_method;
|
||||
|
||||
C_TF_PlayerResource *g_TF_PR;
|
||||
|
||||
IMPLEMENT_CLIENTCLASS_DT( C_TF_PlayerResource, DT_TFPlayerResource, CTFPlayerResource )
|
||||
RecvPropArray3( RECVINFO_ARRAY( m_iTotalScore ), RecvPropInt( RECVINFO( m_iTotalScore[0] ) ) ),
|
||||
RecvPropArray3( RECVINFO_ARRAY( m_iMaxHealth ), RecvPropInt( RECVINFO( m_iMaxHealth[0] ) ) ),
|
||||
RecvPropArray3( RECVINFO_ARRAY( m_iMaxBuffedHealth ), RecvPropInt( RECVINFO( m_iMaxBuffedHealth[0] ) ) ),
|
||||
RecvPropArray3( RECVINFO_ARRAY( m_iPlayerClass ), RecvPropInt( RECVINFO( m_iPlayerClass[0] ) ) ),
|
||||
RecvPropArray3( RECVINFO_ARRAY( m_bArenaSpectator ), RecvPropBool( RECVINFO( m_bArenaSpectator[0] ) ) ),
|
||||
RecvPropArray3( RECVINFO_ARRAY( m_iActiveDominations ), RecvPropInt( RECVINFO( m_iActiveDominations[0] ) ) ),
|
||||
RecvPropArray3( RECVINFO_ARRAY( m_flNextRespawnTime ), RecvPropTime( RECVINFO( m_flNextRespawnTime[0] ) ) ),
|
||||
RecvPropArray3( RECVINFO_ARRAY( m_iChargeLevel ), RecvPropInt( RECVINFO( m_iChargeLevel[0] ) ) ),
|
||||
RecvPropArray3( RECVINFO_ARRAY( m_iDamage ), RecvPropInt( RECVINFO( m_iDamage[0] ) ) ),
|
||||
RecvPropArray3( RECVINFO_ARRAY( m_iDamageAssist ), RecvPropInt( RECVINFO( m_iDamageAssist[0] ) ) ),
|
||||
RecvPropArray3( RECVINFO_ARRAY( m_iDamageBoss ), RecvPropInt( RECVINFO( m_iDamageBoss[0] ) ) ),
|
||||
RecvPropArray3( RECVINFO_ARRAY( m_iHealing ), RecvPropInt( RECVINFO( m_iHealing[0] ) ) ),
|
||||
RecvPropArray3( RECVINFO_ARRAY( m_iHealingAssist ), RecvPropInt( RECVINFO( m_iHealingAssist[0] ) ) ),
|
||||
RecvPropArray3( RECVINFO_ARRAY( m_iDamageBlocked ), RecvPropInt( RECVINFO( m_iDamageBlocked[0] ) ) ),
|
||||
RecvPropArray3( RECVINFO_ARRAY( m_iCurrencyCollected ), RecvPropInt( RECVINFO( m_iCurrencyCollected[0] ) ) ),
|
||||
RecvPropArray3( RECVINFO_ARRAY( m_iBonusPoints ), RecvPropInt( RECVINFO( m_iBonusPoints[0] ) ) ),
|
||||
RecvPropArray3( RECVINFO_ARRAY( m_iPlayerLevel ), RecvPropInt( RECVINFO( m_iPlayerLevel[0] ) ) ),
|
||||
RecvPropArray3( RECVINFO_ARRAY( m_iStreaks ), RecvPropInt( RECVINFO_ARRAY( m_iStreaks ) ) ),
|
||||
RecvPropArray3( RECVINFO_ARRAY( m_iUpgradeRefundCredits ), RecvPropInt( RECVINFO( m_iUpgradeRefundCredits[0] ) ) ),
|
||||
RecvPropArray3( RECVINFO_ARRAY( m_iBuybackCredits ), RecvPropInt( RECVINFO( m_iBuybackCredits[0] ) ) ),
|
||||
RecvPropInt( RECVINFO( m_iPartyLeaderRedTeamIndex ) ),
|
||||
RecvPropInt( RECVINFO( m_iPartyLeaderBlueTeamIndex ) ),
|
||||
RecvPropInt( RECVINFO( m_iEventTeamStatus ) ),
|
||||
RecvPropArray3( RECVINFO_ARRAY( m_iPlayerClassWhenKilled ), RecvPropInt( RECVINFO( m_iPlayerClassWhenKilled[0] ) ) ),
|
||||
RecvPropArray3( RECVINFO_ARRAY( m_iConnectionState ), RecvPropInt( RECVINFO( m_iConnectionState[0] ) ) ),
|
||||
END_RECV_TABLE()
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
C_TF_PlayerResource::C_TF_PlayerResource()
|
||||
{
|
||||
m_Colors[TEAM_UNASSIGNED] = COLOR_TF_SPECTATOR;
|
||||
m_Colors[TEAM_SPECTATOR] = COLOR_TF_SPECTATOR;
|
||||
m_Colors[TF_TEAM_RED] = COLOR_RED;
|
||||
m_Colors[TF_TEAM_BLUE] = COLOR_BLUE;
|
||||
|
||||
m_iPartyLeaderRedTeamIndex = 0;
|
||||
m_iPartyLeaderBlueTeamIndex = 0;
|
||||
m_iEventTeamStatus = 0;
|
||||
|
||||
ResetPlayerScoreStats();
|
||||
|
||||
g_TF_PR = this;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
C_TF_PlayerResource::~C_TF_PlayerResource()
|
||||
{
|
||||
g_TF_PR = NULL;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
int C_TF_PlayerResource::GetTeam( int iIndex )
|
||||
{
|
||||
bool bValid = ( iIndex >= 1 && iIndex <= MAX_PLAYERS );
|
||||
if ( !bValid )
|
||||
{
|
||||
Assert( bValid );
|
||||
return TEAM_UNASSIGNED;
|
||||
}
|
||||
|
||||
int iTeam = BaseClass::GetTeam( iIndex );
|
||||
|
||||
if ( iTeam == TEAM_UNASSIGNED )
|
||||
{
|
||||
// In MvM, force everybody to show as being on the defending team,
|
||||
// even if they have not picked a team yet
|
||||
if ( TFGameRules() && TFGameRules()->IsMannVsMachineMode() )
|
||||
{
|
||||
iTeam = TF_TEAM_PVE_DEFENDERS;
|
||||
}
|
||||
}
|
||||
|
||||
return iTeam;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
MM_PlayerConnectionState_t C_TF_PlayerResource::GetPlayerConnectionState( int iIndex ) const
|
||||
{
|
||||
if ( !iIndex || ( iIndex > MAX_PLAYERS ) )
|
||||
return MM_DISCONNECTED;
|
||||
|
||||
return m_iConnectionState[iIndex];
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Gets a value from an array member
|
||||
//-----------------------------------------------------------------------------
|
||||
int C_TF_PlayerResource::GetArrayValue( int iIndex, int *pArray, int iDefaultVal )
|
||||
{
|
||||
if ( !IsConnected( iIndex ) && !IsValid( iIndex ) )
|
||||
return iDefaultVal;
|
||||
|
||||
return pArray[iIndex];
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Gets a streak value
|
||||
//-----------------------------------------------------------------------------
|
||||
int C_TF_PlayerResource::GetStreak( unsigned int iIndex, CTFPlayerShared::ETFStreak streak_type )
|
||||
{
|
||||
if ( !IsConnected( iIndex ) && !IsValid( iIndex ) )
|
||||
return 0;
|
||||
|
||||
return m_iStreaks[ iIndex * CTFPlayerShared::kTFStreak_COUNT + streak_type ];
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
int C_TF_PlayerResource::GetNumRespecCredits( uint32 unIndex )
|
||||
{
|
||||
if ( !unIndex || unIndex > MAX_PLAYERS )
|
||||
return 0;
|
||||
|
||||
if ( !tf_mvm_respec_limit.GetBool() )
|
||||
return 1;
|
||||
|
||||
return GetArrayValue( unIndex, m_iUpgradeRefundCredits, 0 );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
int C_TF_PlayerResource::GetNumBuybackCredits( uint32 unIndex )
|
||||
{
|
||||
if ( !unIndex || unIndex > MAX_PLAYERS )
|
||||
return 0;
|
||||
|
||||
if ( !tf_mvm_buybacks_method.GetBool() )
|
||||
return 0;
|
||||
|
||||
return GetArrayValue( unIndex, m_iBuybackCredits, 0 );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
int C_TF_PlayerResource::GetCountForPlayerClass( int iTeam, int iClass, bool bExcludeLocalPlayer /*=false*/ )
|
||||
{
|
||||
int count = 0;
|
||||
int iLocalPlayerIndex = GetLocalPlayerIndex();
|
||||
|
||||
for ( int i = 1 ; i <= MAX_PLAYERS ; i++ )
|
||||
{
|
||||
if ( bExcludeLocalPlayer && ( i == iLocalPlayerIndex ) )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if ( ( GetTeam( i ) == iTeam ) && ( GetPlayerClass( i ) == iClass ) )
|
||||
{
|
||||
count++;
|
||||
}
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
int C_TF_PlayerResource::GetNumPlayersForTeam( int iTeam, bool bAliveOnly )
|
||||
{
|
||||
int count = 0;
|
||||
|
||||
for ( int playerIndex = 1 ; playerIndex <= MAX_PLAYERS; playerIndex++ )
|
||||
{
|
||||
if ( IsConnected( playerIndex ) )
|
||||
{
|
||||
if ( GetTeam( playerIndex ) == iTeam )
|
||||
{
|
||||
if ( bAliveOnly && !IsAlive( playerIndex ) )
|
||||
continue;
|
||||
|
||||
count++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
int C_TF_PlayerResource::GetDamage( unsigned int nIndex )
|
||||
{
|
||||
Assert( nIndex < ARRAYSIZE( m_aPlayerScoreStats ) );
|
||||
|
||||
return GetArrayValue( nIndex, m_iDamage, 0 ) + m_aPlayerScoreStats[nIndex].m_iPrevDamage;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
int C_TF_PlayerResource::GetDamageAssist( unsigned int nIndex )
|
||||
{
|
||||
Assert( nIndex < ARRAYSIZE( m_aPlayerScoreStats ) );
|
||||
|
||||
return GetArrayValue( nIndex, m_iDamageAssist, 0 ) + m_aPlayerScoreStats[nIndex].m_iPrevDamageAssist;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
int C_TF_PlayerResource::GetDamageBoss( unsigned int nIndex )
|
||||
{
|
||||
Assert( nIndex < ARRAYSIZE( m_aPlayerScoreStats ) );
|
||||
|
||||
return GetArrayValue( nIndex, m_iDamageBoss, 0 ) + m_aPlayerScoreStats[nIndex].m_iPrevDamageBoss;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
int C_TF_PlayerResource::GetHealing( unsigned int nIndex )
|
||||
{
|
||||
Assert( nIndex < ARRAYSIZE( m_aPlayerScoreStats ) );
|
||||
|
||||
return GetArrayValue( nIndex, m_iHealing, 0 ) + m_aPlayerScoreStats[nIndex].m_iPrevHealing;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
int C_TF_PlayerResource::GetHealingAssist( unsigned int nIndex )
|
||||
{
|
||||
Assert( nIndex < ARRAYSIZE( m_aPlayerScoreStats ) );
|
||||
|
||||
return GetArrayValue( nIndex, m_iHealingAssist, 0 ) + m_aPlayerScoreStats[nIndex].m_iPrevHealingAssist;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
int C_TF_PlayerResource::GetDamageBlocked( unsigned int nIndex )
|
||||
{
|
||||
Assert( nIndex < ARRAYSIZE( m_aPlayerScoreStats ) );
|
||||
|
||||
return GetArrayValue( nIndex, m_iDamageBlocked, 0 ) + m_aPlayerScoreStats[nIndex].m_iPrevDamageBlocked;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
int C_TF_PlayerResource::GetCurrencyCollected( unsigned int nIndex )
|
||||
{
|
||||
Assert( nIndex < ARRAYSIZE( m_aPlayerScoreStats ) );
|
||||
|
||||
return GetArrayValue( nIndex, m_iCurrencyCollected, 0 ) + m_aPlayerScoreStats[nIndex].m_iPrevCurrencyCollected;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
int C_TF_PlayerResource::GetBonusPoints( unsigned int nIndex )
|
||||
{
|
||||
Assert( nIndex < ARRAYSIZE( m_aPlayerScoreStats ) );
|
||||
|
||||
return GetArrayValue( nIndex, m_iBonusPoints, 0 ) + m_aPlayerScoreStats[nIndex].m_iPrevBonusPoints;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void C_TF_PlayerResource::UpdatePlayerScoreStats( void )
|
||||
{
|
||||
for ( int playerIndex = 0; playerIndex < ARRAYSIZE( m_aPlayerScoreStats ); playerIndex++ )
|
||||
{
|
||||
// Add current round stats to the accumulator
|
||||
m_aPlayerScoreStats[playerIndex].m_iPrevDamage += GetArrayValue( playerIndex, m_iDamage, 0 );
|
||||
m_aPlayerScoreStats[playerIndex].m_iPrevDamageAssist += GetArrayValue( playerIndex, m_iDamageAssist, 0 );
|
||||
m_aPlayerScoreStats[playerIndex].m_iPrevDamageBoss += GetArrayValue( playerIndex, m_iDamageBoss, 0 );
|
||||
m_aPlayerScoreStats[playerIndex].m_iPrevHealing += GetArrayValue( playerIndex, m_iHealing, 0 );
|
||||
m_aPlayerScoreStats[playerIndex].m_iPrevHealingAssist += GetArrayValue( playerIndex, m_iHealingAssist, 0 );
|
||||
m_aPlayerScoreStats[playerIndex].m_iPrevDamageBlocked += GetArrayValue( playerIndex, m_iDamageBlocked, 0 );
|
||||
m_aPlayerScoreStats[playerIndex].m_iPrevCurrencyCollected += GetArrayValue( playerIndex, m_iCurrencyCollected, 0 );
|
||||
m_aPlayerScoreStats[playerIndex].m_iPrevBonusPoints += GetArrayValue( playerIndex, m_iBonusPoints, 0 );
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void C_TF_PlayerResource::ResetPlayerScoreStats( int playerIndex /*= -1*/ )
|
||||
{
|
||||
if ( playerIndex == -1 )
|
||||
{
|
||||
Q_memset( m_aPlayerScoreStats, 0, sizeof( m_aPlayerScoreStats ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
// valid playerIndex should be 1-33 (32 players)
|
||||
Assert( playerIndex > 0 && playerIndex < ARRAYSIZE( m_aPlayerScoreStats ) );
|
||||
m_aPlayerScoreStats[playerIndex].m_iPrevDamage = 0;
|
||||
m_aPlayerScoreStats[playerIndex].m_iPrevDamageAssist = 0;
|
||||
m_aPlayerScoreStats[playerIndex].m_iPrevDamageBoss = 0;
|
||||
m_aPlayerScoreStats[playerIndex].m_iPrevHealing = 0;
|
||||
m_aPlayerScoreStats[playerIndex].m_iPrevHealingAssist = 0;
|
||||
m_aPlayerScoreStats[playerIndex].m_iPrevDamageBlocked = 0;
|
||||
m_aPlayerScoreStats[playerIndex].m_iPrevCurrencyCollected = 0;
|
||||
m_aPlayerScoreStats[playerIndex].m_iPrevBonusPoints = 0;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,128 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose: TF's custom C_PlayerResource
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================//
|
||||
|
||||
#ifndef C_TF_PLAYERRESOURCE_H
|
||||
#define C_TF_PLAYERRESOURCE_H
|
||||
#ifdef _WIN32
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include "tf_shareddefs.h"
|
||||
#include "c_playerresource.h"
|
||||
#include "tf_player_shared.h"
|
||||
|
||||
class C_TF_PlayerResource : public C_PlayerResource
|
||||
{
|
||||
DECLARE_CLASS( C_TF_PlayerResource, C_PlayerResource );
|
||||
public:
|
||||
DECLARE_CLIENTCLASS();
|
||||
|
||||
C_TF_PlayerResource();
|
||||
virtual ~C_TF_PlayerResource();
|
||||
|
||||
virtual int GetTeam( int index ) OVERRIDE;
|
||||
|
||||
int GetTotalScore( int iIndex ) { return GetArrayValue( iIndex, m_iTotalScore, 0 ); }
|
||||
int GetMaxHealth( int iIndex ) { return GetArrayValue( iIndex, m_iMaxHealth, TF_HEALTH_UNDEFINED ); }
|
||||
int GetMaxHealthForBuffing( int iIndex ) { return GetArrayValue( iIndex, m_iMaxBuffedHealth, TF_HEALTH_UNDEFINED ); }
|
||||
int GetPlayerClass( int iIndex ) { return GetArrayValue( iIndex, m_iPlayerClass, TF_CLASS_UNDEFINED ); }
|
||||
int GetActiveDominations( int iIndex ) { return GetArrayValue( iIndex, m_iActiveDominations, 0 ); }
|
||||
float GetNextRespawnTime( int iIndex ) { return (IsConnected(iIndex) ? m_flNextRespawnTime[iIndex] : 0); }
|
||||
int GetChargeLevel( int iIndex ) { return GetArrayValue( iIndex, m_iChargeLevel, 0 ); }
|
||||
int GetDamage( unsigned int nIndex );
|
||||
int GetDamageAssist( unsigned int nIndex );
|
||||
int GetDamageBoss( unsigned int nIndex );
|
||||
int GetHealing( unsigned int nIndex );
|
||||
int GetHealingAssist( unsigned int nIndex );
|
||||
int GetDamageBlocked( unsigned int nIndex );
|
||||
int GetCurrencyCollected( unsigned int nIndex );
|
||||
int GetBonusPoints( unsigned int nIndex );
|
||||
int GetPlayerLevel( unsigned int nIndex ) { return GetArrayValue( nIndex, m_iPlayerLevel, 0 ); }
|
||||
int GetStreak( unsigned int nIndex, CTFPlayerShared::ETFStreak streak_type );
|
||||
int GetNumRespecCredits( uint32 unIndex );
|
||||
int GetNumBuybackCredits( uint32 unIndex );
|
||||
|
||||
void UpdatePlayerScoreStats( void );
|
||||
void ResetPlayerScoreStats( int playerIndex = -1 );
|
||||
|
||||
bool IsArenaSpectator( int iIndex )
|
||||
{
|
||||
if ( !IsConnected( iIndex ) )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
return m_bArenaSpectator[iIndex];
|
||||
}
|
||||
|
||||
int GetCountForPlayerClass( int iTeam, int iClass, bool bExcludeLocalPlayer = false );
|
||||
|
||||
int GetNumPlayersForTeam( int iTeam, bool bAliveOnly );
|
||||
|
||||
bool HasPremadeParties(){ return ( ( m_iPartyLeaderRedTeamIndex > 0 ) && ( m_iPartyLeaderBlueTeamIndex > 0 ) ); }
|
||||
int GetPartyLeaderRedTeamIndex(){ return m_iPartyLeaderRedTeamIndex; }
|
||||
int GetPartyLeaderBlueTeamIndex(){ return m_iPartyLeaderBlueTeamIndex; }
|
||||
int GetEventTeamStatus() { return m_iEventTeamStatus; }
|
||||
|
||||
int GetPlayerClassWhenKilled( int iIndex ) { return GetArrayValue( iIndex, m_iPlayerClassWhenKilled, TF_CLASS_UNDEFINED ); }
|
||||
|
||||
MM_PlayerConnectionState_t GetPlayerConnectionState( int iIndex ) const;
|
||||
|
||||
protected:
|
||||
int GetArrayValue( int iIndex, int *pArray, int defaultVal );
|
||||
|
||||
int m_iTotalScore[MAX_PLAYERS+1];
|
||||
int m_iMaxHealth[MAX_PLAYERS+1];
|
||||
// !! This is actually m_iMaxHealthForBuffing, but we can't fix it now because of demos :-/
|
||||
int m_iMaxBuffedHealth[MAX_PLAYERS+1];
|
||||
int m_iPlayerClass[MAX_PLAYERS+1];
|
||||
bool m_bArenaSpectator[MAX_PLAYERS+1];
|
||||
int m_iActiveDominations[MAX_PLAYERS+1];
|
||||
|
||||
// These variables are only networked in tournament mode
|
||||
float m_flNextRespawnTime[MAX_PLAYERS+1];
|
||||
int m_iChargeLevel[MAX_PLAYERS+1];
|
||||
|
||||
private:
|
||||
int m_iDamage[MAX_PLAYERS+1];
|
||||
int m_iDamageAssist[MAX_PLAYERS+1];
|
||||
int m_iDamageBoss[MAX_PLAYERS+1];
|
||||
int m_iHealing[MAX_PLAYERS+1];
|
||||
int m_iHealingAssist[MAX_PLAYERS+1];
|
||||
int m_iDamageBlocked[MAX_PLAYERS+1];
|
||||
int m_iCurrencyCollected[MAX_PLAYERS+1];
|
||||
int m_iBonusPoints[MAX_PLAYERS+1];
|
||||
int m_iPlayerLevel[MAX_PLAYERS+1];
|
||||
// Pseudo multidimensional array [MAX_PLAYERS + 1][CTFPlayerShared::kTFStreak_COUNT]
|
||||
int m_iStreaks[(MAX_PLAYERS+1) * CTFPlayerShared::kTFStreak_COUNT];
|
||||
int m_iUpgradeRefundCredits[MAX_PLAYERS + 1];
|
||||
int m_iBuybackCredits[MAX_PLAYERS + 1];
|
||||
|
||||
int m_iPartyLeaderBlueTeamIndex;
|
||||
int m_iPartyLeaderRedTeamIndex;
|
||||
int m_iEventTeamStatus;
|
||||
|
||||
int m_iPlayerClassWhenKilled[MAX_PLAYERS+1];
|
||||
MM_PlayerConnectionState_t m_iConnectionState[MAX_PLAYERS+1];
|
||||
|
||||
struct PlayerScoreboardStats_t
|
||||
{
|
||||
int m_iPrevDamage;
|
||||
int m_iPrevDamageAssist;
|
||||
int m_iPrevDamageBoss;
|
||||
int m_iPrevHealing;
|
||||
int m_iPrevHealingAssist;
|
||||
int m_iPrevDamageBlocked;
|
||||
int m_iPrevCurrencyCollected;
|
||||
int m_iPrevBonusPoints;
|
||||
};
|
||||
|
||||
PlayerScoreboardStats_t m_aPlayerScoreStats[MAX_PLAYERS+1];
|
||||
};
|
||||
|
||||
extern C_TF_PlayerResource *g_TF_PR;
|
||||
|
||||
#endif // C_TF_PLAYERRESOURCE_H
|
||||
@@ -0,0 +1,375 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
#include "cbase.h"
|
||||
#include "c_tf_projectile_arrow.h"
|
||||
#include "particles_new.h"
|
||||
#include "SpriteTrail.h"
|
||||
#include "c_tf_player.h"
|
||||
#include "collisionutils.h"
|
||||
#include "util_shared.h"
|
||||
#include "c_rope.h"
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
IMPLEMENT_NETWORKCLASS_ALIASED( TFProjectile_Arrow, DT_TFProjectile_Arrow )
|
||||
|
||||
BEGIN_NETWORK_TABLE( C_TFProjectile_Arrow, DT_TFProjectile_Arrow )
|
||||
RecvPropBool( RECVINFO( m_bArrowAlight ) ),
|
||||
RecvPropBool( RECVINFO( m_bCritical ) ),
|
||||
RecvPropInt( RECVINFO( m_iProjectileType ) ),
|
||||
END_NETWORK_TABLE()
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
IMPLEMENT_NETWORKCLASS_ALIASED( TFProjectile_HealingBolt, DT_TFProjectile_HealingBolt )
|
||||
|
||||
BEGIN_NETWORK_TABLE( C_TFProjectile_HealingBolt, DT_TFProjectile_HealingBolt )
|
||||
END_NETWORK_TABLE()
|
||||
|
||||
IMPLEMENT_NETWORKCLASS_ALIASED( TFProjectile_GrapplingHook, DT_TFProjectile_GrapplingHook )
|
||||
|
||||
BEGIN_NETWORK_TABLE( C_TFProjectile_GrapplingHook, DT_TFProjectile_GrapplingHook )
|
||||
END_NETWORK_TABLE()
|
||||
|
||||
#define NEAR_MISS_THRESHOLD 120
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
C_TFProjectile_Arrow::C_TFProjectile_Arrow( void )
|
||||
{
|
||||
m_fAttachTime = 0.f;
|
||||
m_nextNearMissCheck = 0.f;
|
||||
m_bNearMiss = false;
|
||||
m_bArrowAlight = false;
|
||||
m_bCritical = true;
|
||||
m_pCritEffect = NULL;
|
||||
m_iCachedDeflect = false;
|
||||
m_flLifeTime = 40.0f;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
C_TFProjectile_Arrow::~C_TFProjectile_Arrow( void )
|
||||
{
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void C_TFProjectile_Arrow::OnDataChanged( DataUpdateType_t updateType )
|
||||
{
|
||||
if ( updateType == DATA_UPDATE_CREATED )
|
||||
{
|
||||
SetNextClientThink( CLIENT_THINK_ALWAYS );
|
||||
|
||||
#ifdef STAGING_ONLY
|
||||
if ( m_iProjectileType == TF_PROJECTILE_SNIPERBULLET )
|
||||
{
|
||||
switch ( GetTeamNumber() )
|
||||
{
|
||||
case TF_TEAM_BLUE:
|
||||
ParticleProp()->Create( "bullet_distortion_trail", PATTACH_ABSORIGIN_FOLLOW );
|
||||
break;
|
||||
case TF_TEAM_RED:
|
||||
ParticleProp()->Create( "bullet_distortion_trail", PATTACH_ABSORIGIN_FOLLOW );
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if ( m_bArrowAlight )
|
||||
#else
|
||||
if ( m_bArrowAlight )
|
||||
#endif // STAGING_ONLY
|
||||
{
|
||||
ParticleProp()->Create( "flying_flaming_arrow", PATTACH_POINT_FOLLOW, "muzzle" );
|
||||
}
|
||||
}
|
||||
if ( m_bCritical )
|
||||
{
|
||||
if ( updateType == DATA_UPDATE_CREATED || m_iCachedDeflect != GetDeflected() )
|
||||
{
|
||||
CreateCritTrail();
|
||||
}
|
||||
}
|
||||
m_iCachedDeflect = GetDeflected();
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void C_TFProjectile_Arrow::NotifyBoneAttached( C_BaseAnimating* attachTarget )
|
||||
{
|
||||
BaseClass::NotifyBoneAttached( attachTarget );
|
||||
|
||||
m_fAttachTime = gpGlobals->curtime;
|
||||
SetNextClientThink( CLIENT_THINK_ALWAYS );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void C_TFProjectile_Arrow::ClientThink( void )
|
||||
{
|
||||
// Perform a near-miss check.
|
||||
if ( !m_bNearMiss && (gpGlobals->curtime > m_nextNearMissCheck) )
|
||||
{
|
||||
CheckNearMiss();
|
||||
m_nextNearMissCheck = gpGlobals->curtime + 0.05f;
|
||||
}
|
||||
|
||||
// Remove crit effect if we hit a wall.
|
||||
if ( GetMoveType() == MOVETYPE_NONE && m_pCritEffect )
|
||||
{
|
||||
ParticleProp()->StopEmission( m_pCritEffect );
|
||||
m_pCritEffect = NULL;
|
||||
}
|
||||
|
||||
BaseClass::ClientThink();
|
||||
|
||||
// DO THIS LAST: Destroy us automatically after a period of time.
|
||||
if ( m_pAttachedTo )
|
||||
{
|
||||
if ( gpGlobals->curtime - m_fAttachTime > m_flLifeTime )
|
||||
{
|
||||
Release();
|
||||
return;
|
||||
}
|
||||
else if ( m_pAttachedTo->IsEffectActive( EF_NODRAW ) && !IsEffectActive( EF_NODRAW ) )
|
||||
{
|
||||
AddEffects( EF_NODRAW );
|
||||
UpdateVisibility();
|
||||
}
|
||||
else if ( !m_pAttachedTo->IsEffectActive( EF_NODRAW ) && IsEffectActive( EF_NODRAW ) && (m_pAttachedTo != C_BasePlayer::GetLocalPlayer()) )
|
||||
{
|
||||
RemoveEffects( EF_NODRAW );
|
||||
UpdateVisibility();
|
||||
}
|
||||
}
|
||||
|
||||
if ( IsDormant() && !IsEffectActive( EF_NODRAW ) )
|
||||
{
|
||||
AddEffects( EF_NODRAW );
|
||||
UpdateVisibility();
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void C_TFProjectile_Arrow::CheckNearMiss( void )
|
||||
{
|
||||
// Check against the local player. If we're near him play a near miss sound.
|
||||
C_TFPlayer *pLocalPlayer = C_TFPlayer::GetLocalTFPlayer();
|
||||
if ( !pLocalPlayer || !pLocalPlayer->IsAlive() )
|
||||
return;
|
||||
|
||||
// If we are attached to something or stationary we don't want to do near miss checks.
|
||||
if ( m_pAttachedTo || (GetMoveType() == MOVETYPE_NONE) )
|
||||
{
|
||||
m_bNearMiss = true;
|
||||
return;
|
||||
}
|
||||
|
||||
// Can't hear near miss sounds from friendly arrows.
|
||||
if ( pLocalPlayer->GetTeamNumber() == GetTeamNumber() )
|
||||
return;
|
||||
|
||||
Vector vecPlayerPos = pLocalPlayer->GetAbsOrigin();
|
||||
Vector vecArrowPos = GetAbsOrigin(), forward;
|
||||
AngleVectors( GetAbsAngles(), &forward );
|
||||
Vector vecArrowDest = GetAbsOrigin() + forward * 200.f;
|
||||
|
||||
// If the arrow is moving away from the player just stop checking.
|
||||
float dist1 = vecArrowPos.DistToSqr( vecPlayerPos );
|
||||
float dist2 = vecArrowDest.DistToSqr( vecPlayerPos );
|
||||
if ( dist2 > dist1 )
|
||||
{
|
||||
m_bNearMiss = true;
|
||||
return;
|
||||
}
|
||||
|
||||
// Check to see if the arrow is passing near the player.
|
||||
Vector vecClosestPoint;
|
||||
float dist;
|
||||
CalcClosestPointOnLineSegment( vecPlayerPos, vecArrowPos, vecArrowDest, vecClosestPoint, &dist );
|
||||
dist = vecPlayerPos.DistTo( vecClosestPoint );
|
||||
if ( dist > NEAR_MISS_THRESHOLD )
|
||||
return;
|
||||
|
||||
// The arrow is passing close to the local player.
|
||||
m_bNearMiss = true;
|
||||
SetNextClientThink( CLIENT_THINK_NEVER );
|
||||
|
||||
// If the arrow is about to hit something, don't play the sound and stop this check.
|
||||
trace_t tr;
|
||||
UTIL_TraceLine( vecArrowPos, vecArrowPos + forward * 400.f, CONTENTS_HITBOX|CONTENTS_MONSTER|CONTENTS_SOLID, this, COLLISION_GROUP_NONE, &tr );
|
||||
if ( tr.DidHit() )
|
||||
return;
|
||||
|
||||
// We're good for a near miss!
|
||||
float soundlen = 0;
|
||||
EmitSound_t params;
|
||||
params.m_flSoundTime = 0;
|
||||
params.m_pSoundName = "Weapon_Arrow.Nearmiss";
|
||||
params.m_pflSoundDuration = &soundlen;
|
||||
CSingleUserRecipientFilter localFilter( pLocalPlayer );
|
||||
EmitSound( localFilter, pLocalPlayer->entindex(), params );
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void C_TFProjectile_Arrow::CreateCritTrail( void )
|
||||
{
|
||||
if ( IsDormant() )
|
||||
return;
|
||||
|
||||
if ( m_pCritEffect )
|
||||
{
|
||||
ParticleProp()->StopEmission( m_pCritEffect );
|
||||
m_pCritEffect = NULL;
|
||||
}
|
||||
|
||||
if ( m_bCritical )
|
||||
{
|
||||
switch( GetTeamNumber() )
|
||||
{
|
||||
case TF_TEAM_BLUE:
|
||||
m_pCritEffect = ParticleProp()->Create( "critical_rocket_blue", PATTACH_ABSORIGIN_FOLLOW );
|
||||
break;
|
||||
case TF_TEAM_RED:
|
||||
m_pCritEffect = ParticleProp()->Create( "critical_rocket_red", PATTACH_ABSORIGIN_FOLLOW );
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
void C_TFProjectile_HealingBolt::OnDataChanged( DataUpdateType_t updateType )
|
||||
{
|
||||
if ( updateType == DATA_UPDATE_CREATED )
|
||||
{
|
||||
switch( GetTeamNumber() )
|
||||
{
|
||||
case TF_TEAM_BLUE:
|
||||
ParticleProp()->Create( "healshot_trail_blue", PATTACH_ABSORIGIN_FOLLOW );
|
||||
break;
|
||||
case TF_TEAM_RED:
|
||||
ParticleProp()->Create( "healshot_trail_red", PATTACH_ABSORIGIN_FOLLOW );
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
BaseClass::OnDataChanged( updateType );
|
||||
}
|
||||
|
||||
|
||||
void C_TFProjectile_GrapplingHook::OnDataChanged( DataUpdateType_t updateType )
|
||||
{
|
||||
BaseClass::OnDataChanged( updateType );
|
||||
|
||||
if ( updateType == DATA_UPDATE_CREATED )
|
||||
{
|
||||
int nTeam = GetTeamNumber();
|
||||
C_TFPlayer *pTFPlayer = ToTFPlayer( GetOwnerEntity() );
|
||||
if ( pTFPlayer && pTFPlayer->IsPlayerClass( TF_CLASS_SPY ) && pTFPlayer->m_Shared.InCond( TF_COND_DISGUISED ) && pTFPlayer->GetTeamNumber() != GetLocalPlayerTeam() )
|
||||
{
|
||||
nTeam = pTFPlayer->m_Shared.GetDisguiseTeam();
|
||||
}
|
||||
|
||||
const char *pszMaterialName = "cable/cable";
|
||||
switch ( nTeam )
|
||||
{
|
||||
case TF_TEAM_BLUE:
|
||||
pszMaterialName = "cable/cable_blue";
|
||||
break;
|
||||
case TF_TEAM_RED:
|
||||
pszMaterialName = "cable/cable_red";
|
||||
break;
|
||||
}
|
||||
|
||||
C_BaseEntity *pStartEnt = GetOwnerEntity();
|
||||
int iAttachment = 0;
|
||||
|
||||
if ( pTFPlayer )
|
||||
{
|
||||
CTFWeaponBase *pWeapon = assert_cast< CTFWeaponBase* >( pTFPlayer->GetActiveWeapon() );
|
||||
if ( pWeapon )
|
||||
{
|
||||
pStartEnt = pWeapon;
|
||||
int iMuzzle = pWeapon->LookupAttachment( "muzzle" );
|
||||
if ( iMuzzle != -1 )
|
||||
{
|
||||
iAttachment = iMuzzle;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int iHookAttachment = LookupAttachment( "rope_locator" );
|
||||
if ( iHookAttachment == -1 )
|
||||
iHookAttachment = 0;
|
||||
|
||||
m_hRope = C_RopeKeyframe::Create( pStartEnt, this, iAttachment, iHookAttachment, 2, pszMaterialName );
|
||||
|
||||
SetNextClientThink( CLIENT_THINK_ALWAYS );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void C_TFProjectile_GrapplingHook::UpdateOnRemove()
|
||||
{
|
||||
RemoveRope();
|
||||
|
||||
BaseClass::UpdateOnRemove();
|
||||
}
|
||||
|
||||
|
||||
void C_TFProjectile_GrapplingHook::ClientThink()
|
||||
{
|
||||
UpdateRope();
|
||||
}
|
||||
|
||||
|
||||
void C_TFProjectile_GrapplingHook::UpdateRope()
|
||||
{
|
||||
C_TFPlayer *pTFPlayer = ToTFPlayer( GetOwnerEntity() );
|
||||
if ( !pTFPlayer || !pTFPlayer->IsAlive() )
|
||||
{
|
||||
RemoveRope();
|
||||
return;
|
||||
}
|
||||
|
||||
Vector vecStart = pTFPlayer->WorldSpaceCenter();
|
||||
if ( pTFPlayer->GetActiveWeapon() )
|
||||
{
|
||||
int iAttachment = pTFPlayer->GetActiveWeapon()->LookupAttachment( "muzzle" );
|
||||
if ( iAttachment != -1 )
|
||||
{
|
||||
GetAttachment( iAttachment, vecStart );
|
||||
}
|
||||
}
|
||||
|
||||
float flDist = vecStart.DistTo( WorldSpaceCenter() );
|
||||
|
||||
if ( m_hRope )
|
||||
{
|
||||
float flHangDist = pTFPlayer->GetGrapplingHookTarget() ? 0.1f * flDist : 1.5f * flDist;
|
||||
assert_cast< C_RopeKeyframe* >( m_hRope.Get() )->SetupHangDistance( flHangDist );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void C_TFProjectile_GrapplingHook::RemoveRope()
|
||||
{
|
||||
if ( m_hRope )
|
||||
{
|
||||
m_hRope->Release();
|
||||
m_hRope = NULL;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,89 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
#ifndef C_TF_PROJECTILE_ARROW_H
|
||||
#define C_TF_PROJECTILE_ARROW_H
|
||||
#ifdef _WIN32
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include "tf_weaponbase_rocket.h"
|
||||
|
||||
#define CTFProjectile_Arrow C_TFProjectile_Arrow
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Arrow projectile.
|
||||
//-----------------------------------------------------------------------------
|
||||
class C_TFProjectile_Arrow : public C_TFBaseRocket
|
||||
{
|
||||
DECLARE_CLASS( C_TFProjectile_Arrow, C_TFBaseRocket );
|
||||
|
||||
public:
|
||||
|
||||
DECLARE_NETWORKCLASS();
|
||||
|
||||
C_TFProjectile_Arrow();
|
||||
~C_TFProjectile_Arrow();
|
||||
|
||||
virtual void OnDataChanged( DataUpdateType_t updateType );
|
||||
virtual void NotifyBoneAttached( C_BaseAnimating* attachTarget );
|
||||
virtual void ClientThink( void );
|
||||
|
||||
void CheckNearMiss( void );
|
||||
|
||||
void CreateCritTrail( void );
|
||||
|
||||
void SetLifeTime( float flLifetime ) { m_flLifeTime = flLifetime; }
|
||||
|
||||
private:
|
||||
|
||||
float m_fAttachTime;
|
||||
float m_nextNearMissCheck;
|
||||
bool m_bNearMiss;
|
||||
bool m_bArrowAlight;
|
||||
bool m_bCritical;
|
||||
CNewParticleEffect *m_pCritEffect;
|
||||
int m_iCachedDeflect;
|
||||
|
||||
float m_flLifeTime;
|
||||
|
||||
CNetworkVar( int, m_iProjectileType );
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Arrow projectile.
|
||||
//-----------------------------------------------------------------------------
|
||||
class C_TFProjectile_HealingBolt : public C_TFProjectile_Arrow
|
||||
{
|
||||
DECLARE_CLASS( C_TFProjectile_HealingBolt, C_TFProjectile_Arrow );
|
||||
|
||||
virtual void OnDataChanged( DataUpdateType_t updateType );
|
||||
|
||||
public:
|
||||
|
||||
DECLARE_NETWORKCLASS();
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Grappling Hook projectile.
|
||||
//-----------------------------------------------------------------------------
|
||||
class C_TFProjectile_GrapplingHook : public C_TFProjectile_Arrow
|
||||
{
|
||||
DECLARE_CLASS( C_TFProjectile_GrapplingHook, C_TFProjectile_Arrow );
|
||||
public:
|
||||
DECLARE_NETWORKCLASS();
|
||||
|
||||
virtual void OnDataChanged( DataUpdateType_t updateType );
|
||||
virtual void UpdateOnRemove();
|
||||
virtual void ClientThink();
|
||||
private:
|
||||
void UpdateRope();
|
||||
void RemoveRope();
|
||||
|
||||
CHandle< C_RopeKeyframe > m_hRope;
|
||||
};
|
||||
|
||||
#endif // C_TF_PROJECTILE_ARROW_H
|
||||
@@ -0,0 +1,98 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
#include "cbase.h"
|
||||
#include "c_tf_projectile_energy_ball.h"
|
||||
#include "particles_new.h"
|
||||
#include "SpriteTrail.h"
|
||||
#include "c_tf_player.h"
|
||||
#include "collisionutils.h"
|
||||
#include "util_shared.h"
|
||||
#include "tf_weapon_rocketlauncher.h"
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
IMPLEMENT_NETWORKCLASS_ALIASED( TFProjectile_EnergyBall, DT_TFProjectile_EnergyBall )
|
||||
|
||||
BEGIN_NETWORK_TABLE( C_TFProjectile_EnergyBall, DT_TFProjectile_EnergyBall )
|
||||
RecvPropBool( RECVINFO( m_bChargedShot ) ),
|
||||
RecvPropVector( RECVINFO( m_vColor1 ) ),
|
||||
RecvPropVector( RECVINFO( m_vColor2 ) )
|
||||
END_NETWORK_TABLE()
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
C_TFProjectile_EnergyBall::C_TFProjectile_EnergyBall( void )
|
||||
{
|
||||
pEffect = NULL;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
C_TFProjectile_EnergyBall::~C_TFProjectile_EnergyBall( void )
|
||||
{
|
||||
if ( pEffect )
|
||||
{
|
||||
ParticleProp()->StopEmission( pEffect );
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void C_TFProjectile_EnergyBall::CreateTrails( void )
|
||||
{
|
||||
if ( IsDormant() )
|
||||
return;
|
||||
|
||||
if ( pEffect )
|
||||
{
|
||||
ParticleProp()->StopEmission( pEffect );
|
||||
pEffect = NULL;
|
||||
}
|
||||
|
||||
bool bDeflected = m_iCachedDeflect != GetDeflected();
|
||||
|
||||
if ( pEffect == NULL )
|
||||
{
|
||||
ParticleProp()->Init( this );
|
||||
pEffect = ParticleProp()->Create( GetTrailParticleName(), PATTACH_ABSORIGIN_FOLLOW, 0 );
|
||||
|
||||
if ( pEffect )
|
||||
{
|
||||
if ( bDeflected )
|
||||
{
|
||||
if ( GetTeamNumber() == TF_TEAM_BLUE )
|
||||
{
|
||||
pEffect->SetControlPoint( CUSTOM_COLOR_CP1, TF_PARTICLE_WEAPON_BLUE_1 );
|
||||
pEffect->SetControlPoint( CUSTOM_COLOR_CP2, TF_PARTICLE_WEAPON_BLUE_2 );
|
||||
}
|
||||
else
|
||||
{
|
||||
pEffect->SetControlPoint( CUSTOM_COLOR_CP1, TF_PARTICLE_WEAPON_RED_1 );
|
||||
pEffect->SetControlPoint( CUSTOM_COLOR_CP2, TF_PARTICLE_WEAPON_RED_2 );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
pEffect->SetControlPoint( CUSTOM_COLOR_CP1, m_vColor1 );
|
||||
pEffect->SetControlPoint( CUSTOM_COLOR_CP2, m_vColor2 );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
const char *C_TFProjectile_EnergyBall::GetTrailParticleName( void )
|
||||
{
|
||||
if ( m_bChargedShot )
|
||||
return ( GetTeamNumber() == TF_TEAM_RED ) ? "drg_cow_rockettrail_charged" : "drg_cow_rockettrail_charged_blue";
|
||||
else
|
||||
return ( GetTeamNumber() == TF_TEAM_RED ) ? "drg_cow_rockettrail_normal" : "drg_cow_rockettrail_normal_blue";
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
#ifndef C_TF_PROJECTILE_ENERGY_BALL_H
|
||||
#define C_TF_PROJECTILE_ENERGY_BALL_H
|
||||
#ifdef _WIN32
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include "tf_weaponbase_rocket.h"
|
||||
|
||||
#define CTFProjectile_EnergyBall C_TFProjectile_EnergyBall
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: EnergyBall projectile.
|
||||
//-----------------------------------------------------------------------------
|
||||
class C_TFProjectile_EnergyBall : public C_TFBaseRocket
|
||||
{
|
||||
DECLARE_CLASS( C_TFProjectile_EnergyBall, C_TFBaseRocket );
|
||||
|
||||
public:
|
||||
|
||||
DECLARE_NETWORKCLASS();
|
||||
|
||||
C_TFProjectile_EnergyBall();
|
||||
~C_TFProjectile_EnergyBall();
|
||||
|
||||
virtual void CreateTrails( void );
|
||||
virtual const char *GetTrailParticleName( void );
|
||||
|
||||
private:
|
||||
CNewParticleEffect *pEffect;
|
||||
bool m_bChargedShot;
|
||||
|
||||
Vector m_vColor1;
|
||||
Vector m_vColor2;
|
||||
};
|
||||
|
||||
#endif // C_TF_PROJECTILE_ENERGY_BALL_H
|
||||
@@ -0,0 +1,108 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
#include "cbase.h"
|
||||
#include "c_tf_projectile_flare.h"
|
||||
#include "tf_weapon_flaregun.h"
|
||||
#include "c_tf_player.h"
|
||||
#include "particles_new.h"
|
||||
|
||||
IMPLEMENT_NETWORKCLASS_ALIASED( TFProjectile_Flare, DT_TFProjectile_Flare )
|
||||
|
||||
BEGIN_NETWORK_TABLE( C_TFProjectile_Flare, DT_TFProjectile_Flare )
|
||||
RecvPropBool( RECVINFO( m_bCritical ) ),
|
||||
END_NETWORK_TABLE()
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
C_TFProjectile_Flare::C_TFProjectile_Flare( void )
|
||||
{
|
||||
pEffect = NULL;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
C_TFProjectile_Flare::~C_TFProjectile_Flare( void )
|
||||
{
|
||||
if ( pEffect )
|
||||
{
|
||||
ParticleProp()->StopEmission( pEffect );
|
||||
pEffect = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void C_TFProjectile_Flare::OnDataChanged( DataUpdateType_t updateType )
|
||||
{
|
||||
BaseClass::OnDataChanged( updateType );
|
||||
|
||||
if ( updateType == DATA_UPDATE_CREATED )
|
||||
{
|
||||
CreateTrails();
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
const char *GetFlareTrailParticleName( int iTeamNumber, bool bCritical, int nType )
|
||||
{
|
||||
if ( nType == FLAREGUN_GRORDBORT )
|
||||
{
|
||||
return "drg_manmelter_projectile";
|
||||
}
|
||||
else if ( nType == FLAREGUN_SCORCHSHOT )
|
||||
{
|
||||
if ( iTeamNumber == TF_TEAM_BLUE )
|
||||
{
|
||||
return ( bCritical ? "scorchshot_trail_crit_blue" : "scorchshot_trail_blue" );
|
||||
}
|
||||
else
|
||||
{
|
||||
return ( bCritical ? "scorchshot_trail_crit_red" : "scorchshot_trail_red" );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( iTeamNumber == TF_TEAM_BLUE )
|
||||
{
|
||||
return ( bCritical ? "flaregun_trail_crit_blue" : "flaregun_trail_blue" );
|
||||
}
|
||||
else
|
||||
{
|
||||
return ( bCritical ? "flaregun_trail_crit_red" : "flaregun_trail_red" );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void C_TFProjectile_Flare::CreateTrails( void )
|
||||
{
|
||||
if ( IsDormant() )
|
||||
return;
|
||||
|
||||
if ( pEffect )
|
||||
{
|
||||
ParticleProp()->StopEmission( pEffect );
|
||||
pEffect = NULL;
|
||||
}
|
||||
|
||||
int nType = 0;
|
||||
|
||||
C_TFFlareGun *pFlareGun = dynamic_cast< C_TFFlareGun* >( GetLauncher() );
|
||||
if ( pFlareGun )
|
||||
{
|
||||
nType = pFlareGun->GetFlareGunType();
|
||||
}
|
||||
|
||||
pEffect = ParticleProp()->Create( GetFlareTrailParticleName( GetTeamNumber(), m_bCritical, nType ), PATTACH_ABSORIGIN_FOLLOW );
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
#ifndef C_TF_PROJECTILE_FLARE_H
|
||||
#define C_TF_PROJECTILE_FLARE_H
|
||||
#ifdef _WIN32
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include "tf_weaponbase_rocket.h"
|
||||
|
||||
#define CTFProjectile_Flare C_TFProjectile_Flare
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Flare projectile.
|
||||
//-----------------------------------------------------------------------------
|
||||
class C_TFProjectile_Flare : public C_TFBaseRocket
|
||||
{
|
||||
DECLARE_CLASS( C_TFProjectile_Flare, C_TFBaseRocket );
|
||||
|
||||
public:
|
||||
|
||||
DECLARE_NETWORKCLASS();
|
||||
|
||||
C_TFProjectile_Flare();
|
||||
~C_TFProjectile_Flare();
|
||||
|
||||
virtual void OnDataChanged( DataUpdateType_t updateType );
|
||||
|
||||
void CreateTrails( void );
|
||||
|
||||
private:
|
||||
|
||||
bool m_bCritical;
|
||||
CNewParticleEffect *pEffect;
|
||||
};
|
||||
|
||||
#endif // C_TF_PROJECTILE_FLARE_H
|
||||
@@ -0,0 +1,144 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
#include "cbase.h"
|
||||
#include "c_tf_projectile_rocket.h"
|
||||
#include "particles_new.h"
|
||||
#include "tf_gamerules.h"
|
||||
|
||||
IMPLEMENT_NETWORKCLASS_ALIASED( TFProjectile_Rocket, DT_TFProjectile_Rocket )
|
||||
|
||||
BEGIN_NETWORK_TABLE( C_TFProjectile_Rocket, DT_TFProjectile_Rocket )
|
||||
RecvPropBool( RECVINFO( m_bCritical ) ),
|
||||
END_NETWORK_TABLE()
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
C_TFProjectile_Rocket::C_TFProjectile_Rocket( void )
|
||||
{
|
||||
pEffect = NULL;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
C_TFProjectile_Rocket::~C_TFProjectile_Rocket( void )
|
||||
{
|
||||
if ( pEffect )
|
||||
{
|
||||
ParticleProp()->StopEmission( pEffect );
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void C_TFProjectile_Rocket::OnDataChanged(DataUpdateType_t updateType)
|
||||
{
|
||||
BaseClass::OnDataChanged(updateType);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void C_TFProjectile_Rocket::CreateTrails( void )
|
||||
{
|
||||
if ( IsDormant() )
|
||||
return;
|
||||
|
||||
bool bUsingCustom = false;
|
||||
|
||||
if ( pEffect )
|
||||
{
|
||||
ParticleProp()->StopEmission( pEffect );
|
||||
pEffect = NULL;
|
||||
}
|
||||
|
||||
int iAttachment = LookupAttachment( "trail" );
|
||||
if ( iAttachment == INVALID_PARTICLE_ATTACHMENT )
|
||||
return;
|
||||
|
||||
if ( enginetrace->GetPointContents( GetAbsOrigin() ) & MASK_WATER )
|
||||
{
|
||||
ParticleProp()->Create( "rockettrail_underwater", PATTACH_POINT_FOLLOW, "trail" );
|
||||
bUsingCustom = true;
|
||||
}
|
||||
else if ( GetTeamNumber() == TEAM_UNASSIGNED )
|
||||
{
|
||||
ParticleProp()->Create( "rockettrail_underwater", PATTACH_POINT_FOLLOW, "trail" );
|
||||
bUsingCustom = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Halloween Spell Effect Check
|
||||
int iHalloweenSpell = 0;
|
||||
// if the owner is a Sentry, Check its owner
|
||||
CBaseObject *pSentry = GetOwnerEntity() && GetOwnerEntity()->IsBaseObject() ? assert_cast<CBaseObject*>( GetOwnerEntity() ) : NULL;
|
||||
if ( TF_IsHolidayActive( kHoliday_HalloweenOrFullMoon ) )
|
||||
{
|
||||
if ( pSentry )
|
||||
{
|
||||
CALL_ATTRIB_HOOK_INT_ON_OTHER( pSentry->GetOwner(), iHalloweenSpell, halloween_pumpkin_explosions );
|
||||
}
|
||||
else
|
||||
{
|
||||
CALL_ATTRIB_HOOK_INT_ON_OTHER( GetOwnerEntity(), iHalloweenSpell, halloween_pumpkin_explosions );
|
||||
}
|
||||
}
|
||||
|
||||
// Mini rockets from airstrike RL
|
||||
if ( iHalloweenSpell > 0 )
|
||||
{
|
||||
ParticleProp()->Create( "halloween_rockettrail", PATTACH_POINT_FOLLOW, iAttachment );
|
||||
bUsingCustom = true;
|
||||
}
|
||||
else if ( !pSentry )
|
||||
{
|
||||
if ( GetLauncher() )
|
||||
{
|
||||
int iMiniRocket = 0;
|
||||
CALL_ATTRIB_HOOK_INT_ON_OTHER( GetLauncher(), iMiniRocket, mini_rockets );
|
||||
if ( iMiniRocket )
|
||||
{
|
||||
ParticleProp()->Create( "rockettrail_airstrike", PATTACH_POINT_FOLLOW, iAttachment );
|
||||
bUsingCustom = true;
|
||||
|
||||
// rockettrail_airstrike_line
|
||||
CTFPlayer *pPlayer = ToTFPlayer( GetOwnerEntity() );
|
||||
if ( pPlayer && pPlayer->m_Shared.InCond( TF_COND_BLASTJUMPING ) )
|
||||
{
|
||||
ParticleProp()->Create( "rockettrail_airstrike_line", PATTACH_POINT_FOLLOW, iAttachment );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ( !bUsingCustom )
|
||||
{
|
||||
if ( GetTrailParticleName() )
|
||||
{
|
||||
ParticleProp()->Create( GetTrailParticleName(), PATTACH_POINT_FOLLOW, iAttachment );
|
||||
}
|
||||
}
|
||||
|
||||
if ( m_bCritical )
|
||||
{
|
||||
switch( GetTeamNumber() )
|
||||
{
|
||||
case TF_TEAM_BLUE:
|
||||
pEffect = ParticleProp()->Create( "critical_rocket_blue", PATTACH_ABSORIGIN_FOLLOW );
|
||||
break;
|
||||
case TF_TEAM_RED:
|
||||
pEffect = ParticleProp()->Create( "critical_rocket_red", PATTACH_ABSORIGIN_FOLLOW );
|
||||
break;
|
||||
default:
|
||||
pEffect = ParticleProp()->Create( "eyeboss_projectile", PATTACH_ABSORIGIN_FOLLOW );
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
#ifndef C_TF_PROJECTILE_ROCKET_H
|
||||
#define C_TF_PROJECTILE_ROCKET_H
|
||||
#ifdef _WIN32
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include "tf_weaponbase_rocket.h"
|
||||
|
||||
#define CTFProjectile_Rocket C_TFProjectile_Rocket
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Rocket projectile.
|
||||
//-----------------------------------------------------------------------------
|
||||
class C_TFProjectile_Rocket : public C_TFBaseRocket
|
||||
{
|
||||
DECLARE_CLASS( C_TFProjectile_Rocket, C_TFBaseRocket );
|
||||
public:
|
||||
DECLARE_NETWORKCLASS();
|
||||
|
||||
C_TFProjectile_Rocket();
|
||||
~C_TFProjectile_Rocket();
|
||||
|
||||
virtual void OnDataChanged(DataUpdateType_t updateType);
|
||||
|
||||
virtual void CreateTrails( void );
|
||||
virtual const char *GetTrailParticleName( void ) { return "rockettrail"; }
|
||||
|
||||
private:
|
||||
bool m_bCritical;
|
||||
|
||||
CNewParticleEffect *pEffect;
|
||||
};
|
||||
|
||||
#endif // C_TF_PROJECTILE_ROCKET_H
|
||||
@@ -0,0 +1,240 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose: TF version of the stickybolt code.
|
||||
// I broke off our own version because I didn't want to accidentally break HL2.
|
||||
// $Workfile: $
|
||||
// $Date: $
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
// $Log: $
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================//
|
||||
#include "cbase.h"
|
||||
#include "c_basetempentity.h"
|
||||
#include "fx.h"
|
||||
#include "decals.h"
|
||||
#include "iefx.h"
|
||||
#include "engine/IEngineSound.h"
|
||||
#include "materialsystem/imaterialvar.h"
|
||||
#include "IEffects.h"
|
||||
#include "engine/IEngineTrace.h"
|
||||
#include "vphysics/constraints.h"
|
||||
#include "engine/ivmodelinfo.h"
|
||||
#include "tempent.h"
|
||||
#include "c_te_legacytempents.h"
|
||||
#include "engine/ivdebugoverlay.h"
|
||||
#include "c_te_effect_dispatch.h"
|
||||
#include "c_tf_player.h"
|
||||
#include "GameEventListener.h"
|
||||
#include "tf_shareddefs.h"
|
||||
|
||||
// memdbgon must be the last include file in a .cpp file!!!
|
||||
#include "tier0/memdbgon.h"
|
||||
|
||||
extern IPhysicsSurfaceProps *physprops;
|
||||
IPhysicsObject *GetWorldPhysObject( void );
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Creates a Bolt in the world and Ragdolls
|
||||
// For Attached Bolts on players look at hud_bowcharge "arrow_impact" which should be moved here
|
||||
//-----------------------------------------------------------------------------
|
||||
void CreateCrossbowBoltTF( const Vector &vecOrigin, const Vector &vecDirection, const int iFlags, unsigned char nColor )
|
||||
{
|
||||
const char* pszModelName = NULL;
|
||||
float flDirOffset = 5.0f;
|
||||
float flScale = 1.0f;
|
||||
float flLifeTime = 30.0f;
|
||||
switch ( iFlags )
|
||||
{
|
||||
case TF_PROJECTILE_STICKY_BALL:
|
||||
pszModelName = g_pszArrowModels[MODEL_SNOWBALL];
|
||||
break;
|
||||
case TF_PROJECTILE_ARROW:
|
||||
pszModelName = g_pszArrowModels[MODEL_ARROW_REGULAR];
|
||||
break;
|
||||
case TF_PROJECTILE_BUILDING_REPAIR_BOLT:
|
||||
pszModelName = g_pszArrowModels[MODEL_ARROW_BUILDING_REPAIR];
|
||||
flDirOffset = -2.0f;
|
||||
break;
|
||||
case TF_PROJECTILE_FESTIVE_ARROW:
|
||||
pszModelName = g_pszArrowModels[MODEL_FESTIVE_ARROW_REGULAR];
|
||||
break;
|
||||
case TF_PROJECTILE_HEALING_BOLT:
|
||||
#ifdef STAGING_ONLY
|
||||
case TF_PROJECTILE_MILK_BOLT:
|
||||
#endif
|
||||
pszModelName = g_pszArrowModels[MODEL_SYRINGE];
|
||||
flDirOffset = 0.0f;
|
||||
flScale = 3.0f;
|
||||
break;
|
||||
case TF_PROJECTILE_FESTIVE_HEALING_BOLT:
|
||||
pszModelName = g_pszArrowModels[MODEL_FESTIVE_HEALING_BOLT];
|
||||
flScale = 2.5f;
|
||||
break;
|
||||
case TF_PROJECTILE_BREAD_MONSTER:
|
||||
case TF_PROJECTILE_BREADMONSTER_JARATE:
|
||||
case TF_PROJECTILE_BREADMONSTER_MADMILK:
|
||||
pszModelName = g_pszArrowModels[MODEL_BREAD_MONSTER];
|
||||
flLifeTime = 8.0f;
|
||||
flScale = 2.5f;
|
||||
break;
|
||||
case TF_PROJECTILE_GRAPPLINGHOOK:
|
||||
pszModelName = g_pszArrowModels[MODEL_GRAPPLINGHOOK];
|
||||
flDirOffset = 0.0f;
|
||||
flLifeTime = 0.1f;
|
||||
break;
|
||||
#ifdef STAGING_ONLY
|
||||
case TF_PROJECTILE_THROWING_KNIFE:
|
||||
pszModelName = g_pszArrowModels[MODEL_THROWING_KNIFE];
|
||||
break;
|
||||
case TF_PROJECTILE_SNIPERBULLET:
|
||||
pszModelName = g_pszArrowModels[MODEL_SYRINGE];
|
||||
break;
|
||||
#endif // STAGING_ONLY
|
||||
default:
|
||||
// Unsupported Model
|
||||
Assert( 0 );
|
||||
pszModelName = g_pszArrowModels[MODEL_ARROW_REGULAR];
|
||||
return;
|
||||
}
|
||||
model_t *pModel = (model_t *)engine->LoadModel( pszModelName );
|
||||
|
||||
QAngle vAngles;
|
||||
VectorAngles( vecDirection, vAngles );
|
||||
C_LocalTempEntity *arrow = tempents->SpawnTempModel( pModel, vecOrigin - vecDirection * flDirOffset, vAngles, Vector(0, 0, 0 ), flLifeTime, FTENT_NONE );
|
||||
|
||||
if ( arrow )
|
||||
{
|
||||
arrow->SetModelScale( flScale );
|
||||
arrow->m_nSkin = nColor;
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void StickRagdollNowTF(
|
||||
const Vector &vecOrigin,
|
||||
const Vector &vecDirection,
|
||||
const ClientEntityHandle_t &entHandle,
|
||||
const int boneIndexAttached,
|
||||
const int physicsBoneIndex,
|
||||
const int iShooterIndex,
|
||||
const int iHitGroup,
|
||||
const int iVictim,
|
||||
const int iFlags,
|
||||
unsigned char nColor
|
||||
) {
|
||||
Ray_t shotRay;
|
||||
trace_t tr;
|
||||
|
||||
UTIL_TraceLine( vecOrigin - vecDirection * 16, vecOrigin + vecDirection * 64, MASK_SOLID_BRUSHONLY, NULL, COLLISION_GROUP_NONE, &tr );
|
||||
if ( tr.surface.flags & SURF_SKY )
|
||||
return;
|
||||
|
||||
C_BaseAnimating *pModel = dynamic_cast< C_BaseAnimating * >( entHandle.Get() );
|
||||
if ( pModel )
|
||||
{
|
||||
IPhysicsObject *pPhysicsObject = NULL;
|
||||
ragdoll_t *pRagdollT = NULL;
|
||||
if ( pModel->m_pRagdoll )
|
||||
{
|
||||
CRagdoll *pCRagdoll = dynamic_cast < CRagdoll * > ( pModel->m_pRagdoll );
|
||||
if ( pCRagdoll )
|
||||
{
|
||||
pRagdollT = pCRagdoll->GetRagdoll();
|
||||
if ( physicsBoneIndex < pRagdollT->listCount )
|
||||
{
|
||||
pPhysicsObject = pRagdollT->list[physicsBoneIndex].pObject;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
IPhysicsObject *pReference = GetWorldPhysObject();
|
||||
|
||||
if ( pReference == NULL || pPhysicsObject == NULL )
|
||||
return;
|
||||
|
||||
float frand = (float) rand() / VALVE_RAND_MAX;
|
||||
Vector adjust = vecDirection*7 + vecDirection * frand * 7;
|
||||
|
||||
Vector vecBonePos;
|
||||
QAngle boneAngles;
|
||||
pPhysicsObject->GetPosition( &vecBonePos, &boneAngles );
|
||||
|
||||
QAngle angles;
|
||||
pPhysicsObject->SetPosition( vecOrigin-adjust, boneAngles, true );
|
||||
|
||||
pPhysicsObject->EnableMotion( false );
|
||||
|
||||
int nNodeIndex = pRagdollT->list[physicsBoneIndex].parentIndex;
|
||||
|
||||
// find largest mass bone
|
||||
float flTargetMass = 0;
|
||||
for ( int i = 0; i < pRagdollT->listCount; i++ )
|
||||
{
|
||||
flTargetMass = MAX(flTargetMass, pRagdollT->list[i].pObject->GetMass() );
|
||||
}
|
||||
|
||||
// walk the chain of bones from the pinned bone to the root and set each to the max mass
|
||||
// This helps transmit the impulses required to stabilize the constraint -- it keeps the body from
|
||||
// leaving the constraint because of some high mass bone hanging at the other end of the chain
|
||||
while ( nNodeIndex >= 0 )
|
||||
{
|
||||
if ( pRagdollT->list[nNodeIndex].pConstraint )
|
||||
{
|
||||
float flCurrentMass = pRagdollT->list[nNodeIndex].pObject->GetMass();
|
||||
flCurrentMass = MAX(flCurrentMass, flTargetMass);
|
||||
pRagdollT->list[nNodeIndex].pObject->SetMass( flCurrentMass );
|
||||
}
|
||||
nNodeIndex = pRagdollT->list[nNodeIndex].parentIndex;
|
||||
}
|
||||
}
|
||||
|
||||
UTIL_ImpactTrace( &tr, 0 );
|
||||
|
||||
CreateCrossbowBoltTF( vecOrigin, vecDirection, iFlags, nColor );
|
||||
|
||||
//Achievement stuff.
|
||||
if ( iHitGroup == HITGROUP_HEAD )
|
||||
{
|
||||
CTFPlayer *pLocalPlayer = C_TFPlayer::GetLocalTFPlayer();
|
||||
|
||||
if ( pLocalPlayer && pLocalPlayer->entindex() == iShooterIndex )
|
||||
{
|
||||
CTFPlayer *pVictim = ToTFPlayer( UTIL_PlayerByIndex( iVictim ) );
|
||||
|
||||
if ( pVictim && pVictim->IsPlayerClass( TF_CLASS_HEAVYWEAPONS ) )
|
||||
{
|
||||
IGameEvent *event = gameeventmanager->CreateEvent( "player_pinned" );
|
||||
|
||||
if ( event )
|
||||
{
|
||||
gameeventmanager->FireEventClientSide( event );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void StickyBoltCallbackTF( const CEffectData &data )
|
||||
{
|
||||
StickRagdollNowTF(
|
||||
data.m_vOrigin,
|
||||
data.m_vNormal,
|
||||
data.m_hEntity,
|
||||
data.m_nAttachmentIndex,
|
||||
data.m_nMaterial,
|
||||
data.m_nHitBox,
|
||||
data.m_nDamageType,
|
||||
data.m_nSurfaceProp,
|
||||
data.m_fFlags,
|
||||
data.m_nColor
|
||||
);
|
||||
}
|
||||
|
||||
DECLARE_CLIENT_EFFECT( "TFBoltImpact", StickyBoltCallbackTF );
|
||||
@@ -0,0 +1,60 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose: Play VCD on taunt prop
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================//
|
||||
#include "cbase.h"
|
||||
|
||||
#include "c_basecombatcharacter.h"
|
||||
#include "choreoevent.h"
|
||||
#include "c_sceneentity.h"
|
||||
|
||||
#include "c_tf_taunt_prop.h"
|
||||
|
||||
// memdbgon must be the last include file in a .cpp file!!!
|
||||
#include "tier0/memdbgon.h"
|
||||
|
||||
IMPLEMENT_CLIENTCLASS_DT( C_TFTauntProp, DT_TFTauntProp, CTFTauntProp )
|
||||
END_RECV_TABLE()
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
bool C_TFTauntProp::StartSceneEvent( CSceneEventInfo *info, CChoreoScene *scene, CChoreoEvent *event, CChoreoActor *actor, CBaseEntity *pTarget )
|
||||
{
|
||||
switch ( event->GetType() )
|
||||
{
|
||||
case CChoreoEvent::SEQUENCE:
|
||||
case CChoreoEvent::GESTURE:
|
||||
{
|
||||
// Get the (gesture) sequence.
|
||||
info->m_nSequence = LookupSequence( event->GetParameters() );
|
||||
if ( info->m_nSequence < 0 )
|
||||
return false;
|
||||
|
||||
SetSequence( info->m_nSequence );
|
||||
SetPlaybackRate( 1.0f );
|
||||
SetCycle( scene->GetTime() / scene->GetDuration() );
|
||||
}
|
||||
return true;
|
||||
default:
|
||||
return BaseClass::StartSceneEvent( info, scene, event, actor, pTarget );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
bool C_TFTauntProp::ClearSceneEvent( CSceneEventInfo *info, bool fastKill, bool canceled )
|
||||
{
|
||||
switch ( info->m_pEvent->GetType() )
|
||||
{
|
||||
case CChoreoEvent::SEQUENCE:
|
||||
case CChoreoEvent::GESTURE:
|
||||
//return StopGestureSceneEvent( info, fastKill, canceled );
|
||||
default:
|
||||
return BaseClass::ClearSceneEvent( info, fastKill, canceled );
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose: Play VCD on taunt prop
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================//
|
||||
#ifndef C_TF_TAUNT_PROP_H
|
||||
#define C_TF_TAUNT_PROP_H
|
||||
#ifdef _WIN32
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
class C_TFTauntProp : public C_BaseCombatCharacter
|
||||
{
|
||||
DECLARE_CLASS( C_TFTauntProp, C_BaseCombatCharacter );
|
||||
public:
|
||||
DECLARE_CLIENTCLASS();
|
||||
|
||||
virtual bool StartSceneEvent( CSceneEventInfo *info, CChoreoScene *scene, CChoreoEvent *event, CChoreoActor *actor, C_BaseEntity *pTarget ) OVERRIDE;
|
||||
virtual bool ClearSceneEvent( CSceneEventInfo *info, bool fastKill, bool canceled ) OVERRIDE;
|
||||
};
|
||||
|
||||
#endif // C_TF_TAUNT_PROP_H
|
||||
@@ -0,0 +1,262 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose: Client side C_TFTeam class
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================
|
||||
#include "cbase.h"
|
||||
#include "engine/IEngineSound.h"
|
||||
#include "hud.h"
|
||||
#include "recvproxy.h"
|
||||
#include "c_tf_team.h"
|
||||
#include "c_tf_player.h"
|
||||
#include "tf_shareddefs.h"
|
||||
#include "tf_gamerules.h"
|
||||
#include "c_tf_playerresource.h"
|
||||
|
||||
// memdbgon must be the last include file in a .cpp file!!!
|
||||
#include "tier0/memdbgon.h"
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: RecvProxy that converts the Player's object UtlVector to entindexes
|
||||
//-----------------------------------------------------------------------------
|
||||
void RecvProxy_TeamObjectList( const CRecvProxyData *pData, void *pStruct, void *pOut )
|
||||
{
|
||||
C_TFTeam *pPlayer = (C_TFTeam*)pStruct;
|
||||
CBaseHandle *pHandle = (CBaseHandle*)(&(pPlayer->m_aObjects[pData->m_iElement]));
|
||||
RecvProxy_IntToEHandle( pData, pStruct, pHandle );
|
||||
}
|
||||
|
||||
void RecvProxyArrayLength_TeamObjects( void *pStruct, int objectID, int currentArrayLength )
|
||||
{
|
||||
C_TFTeam *pPlayer = (C_TFTeam*)pStruct;
|
||||
|
||||
if ( pPlayer->m_aObjects.Count() != currentArrayLength )
|
||||
{
|
||||
pPlayer->m_aObjects.SetSize( currentArrayLength );
|
||||
}
|
||||
}
|
||||
|
||||
IMPLEMENT_CLIENTCLASS_DT( C_TFTeam, DT_TFTeam, CTFTeam )
|
||||
|
||||
RecvPropInt( RECVINFO( m_nFlagCaptures ) ),
|
||||
RecvPropInt( RECVINFO( m_iRole ) ),
|
||||
|
||||
RecvPropArray2(
|
||||
RecvProxyArrayLength_TeamObjects,
|
||||
RecvPropInt( "team_object_array_element", 0, SIZEOF_IGNORE, 0, RecvProxy_TeamObjectList ),
|
||||
MAX_PLAYERS * MAX_OBJECTS_PER_PLAYER,
|
||||
0,
|
||||
"team_object_array" ),
|
||||
|
||||
RecvPropEHandle( RECVINFO( m_hLeader ) ),
|
||||
|
||||
END_RECV_TABLE()
|
||||
|
||||
#define TEAM_THINK_RATE 0.5f
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
C_TFTeam::C_TFTeam()
|
||||
{
|
||||
m_nFlagCaptures = 0;
|
||||
m_bUsingCustomTeamName = false;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
C_TFTeam::~C_TFTeam()
|
||||
{
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void C_TFTeam::OnDataChanged( DataUpdateType_t updateType )
|
||||
{
|
||||
BaseClass::OnDataChanged( updateType );
|
||||
|
||||
if ( updateType == DATA_UPDATE_CREATED )
|
||||
{
|
||||
SetNextClientThink( gpGlobals->curtime + TEAM_THINK_RATE );
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
char* C_TFTeam::Get_Name( void )
|
||||
{
|
||||
// Use Get_Localized_Name() instead
|
||||
AssertMsg( false, "Use Get_Localized_Name() instead" );
|
||||
return "";
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void C_TFTeam::ClientThink()
|
||||
{
|
||||
BaseClass::ClientThink();
|
||||
|
||||
UpdateTeamName();
|
||||
SetNextClientThink( gpGlobals->curtime + TEAM_THINK_RATE );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void C_TFTeam::UpdateTeamName( void )
|
||||
{
|
||||
m_bUsingCustomTeamName = false;
|
||||
|
||||
const wchar_t *pwzName = NULL;
|
||||
if ( TFGameRules() && TFGameRules()->IsInTournamentMode() && ( ( m_iTeamNum == TF_TEAM_RED ) || ( m_iTeamNum == TF_TEAM_BLUE ) ) )
|
||||
{
|
||||
if ( TFGameRules()->IsCompetitiveMode() )
|
||||
{
|
||||
if ( g_TF_PR && ( g_TF_PR->HasPremadeParties() || g_TF_PR->GetEventTeamStatus() ) )
|
||||
{
|
||||
wchar_t wszTempName[MAX_TEAM_NAME_LENGTH];
|
||||
wchar_t *pFormat = g_pVGuiLocalize->Find( "#TF_Team_PartyLeader" );
|
||||
if ( !pFormat )
|
||||
{
|
||||
pFormat = L"%s";
|
||||
}
|
||||
|
||||
if ( g_TF_PR->GetEventTeamStatus() )
|
||||
{
|
||||
// GetEventTeamStatus() returns a value in the following range
|
||||
// enum WarMatch
|
||||
// {
|
||||
// NOPE = 0;
|
||||
// INVADERS_ARE_PYRO = 1;
|
||||
// INVADERS_ARE_HEAVY = 2;
|
||||
// };
|
||||
const char *pszTeamName = ( m_iTeamNum == TF_TEAM_BLUE ) ?
|
||||
( g_TF_PR->GetEventTeamStatus() == 1 ? "#TF_Pyro" : "#TF_HWGuy" ) :
|
||||
( g_TF_PR->GetEventTeamStatus() == 1 ? "#TF_HWGuy" : "#TF_Pyro" );
|
||||
wchar_t *pwzWarTeam = g_pVGuiLocalize->Find( pszTeamName );
|
||||
V_swprintf_safe( m_wzTeamname, pFormat, pwzWarTeam );
|
||||
m_bUsingCustomTeamName = true;
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
int iPlayerIndex = ( m_iTeamNum == TF_TEAM_RED ) ? g_TF_PR->GetPartyLeaderRedTeamIndex() : g_TF_PR->GetPartyLeaderBlueTeamIndex();
|
||||
if ( g_TF_PR->IsConnected( iPlayerIndex ) )
|
||||
{
|
||||
g_pVGuiLocalize->ConvertANSIToUnicode( UTIL_SafeName( g_TF_PR->GetPlayerName( iPlayerIndex ) ), wszTempName, sizeof( wszTempName ) );
|
||||
V_swprintf_safe( m_wzTeamname, pFormat, wszTempName );
|
||||
m_bUsingCustomTeamName = true;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
const char *pTemp = ( m_iTeamNum == TF_TEAM_BLUE ) ? mp_tournament_blueteamname.GetString() : mp_tournament_redteamname.GetString();
|
||||
if ( pTemp && pTemp[0] )
|
||||
{
|
||||
g_pVGuiLocalize->ConvertANSIToUnicode( pTemp, m_wzTeamname, sizeof( m_wzTeamname ) );
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ( m_iTeamNum == TF_TEAM_BLUE )
|
||||
{
|
||||
pwzName = g_pVGuiLocalize->Find( "#TF_BlueTeam_Name" );
|
||||
if ( !pwzName )
|
||||
{
|
||||
pwzName = L"BLU";
|
||||
}
|
||||
}
|
||||
else if ( m_iTeamNum == TF_TEAM_RED )
|
||||
{
|
||||
if ( TFGameRules() && TFGameRules()->IsMannVsMachineMode() )
|
||||
{
|
||||
pwzName = g_pVGuiLocalize->Find( "#TF_Defenders" );
|
||||
if ( !pwzName )
|
||||
{
|
||||
pwzName = L"DEFENDERS";
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
pwzName = g_pVGuiLocalize->Find( "#TF_RedTeam_Name" );
|
||||
if ( !pwzName )
|
||||
{
|
||||
pwzName = L"RED";
|
||||
}
|
||||
}
|
||||
}
|
||||
else if ( m_iTeamNum == TEAM_SPECTATOR )
|
||||
{
|
||||
pwzName = g_pVGuiLocalize->Find( "#TF_Spectators" );
|
||||
if ( !pwzName )
|
||||
{
|
||||
pwzName = L"SPECTATORS";
|
||||
}
|
||||
}
|
||||
|
||||
V_wcscpy_safe( m_wzTeamname, pwzName ? pwzName : L"" );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Get the C_TFTeam for the specified team number
|
||||
//-----------------------------------------------------------------------------
|
||||
C_TFTeam *GetGlobalTFTeam( int iTeamNumber )
|
||||
{
|
||||
for ( int i = 0; i < g_Teams.Count(); i++ )
|
||||
{
|
||||
if ( g_Teams[i]->GetTeamNumber() == iTeamNumber )
|
||||
return ( dynamic_cast< C_TFTeam* >( g_Teams[i] ) );
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
int C_TFTeam::GetNumObjects( int iObjectType )
|
||||
{
|
||||
// Asking for a count of a specific object type?
|
||||
if ( iObjectType > 0 )
|
||||
{
|
||||
int iCount = 0;
|
||||
for ( int i = 0; i < GetNumObjects(); i++ )
|
||||
{
|
||||
CBaseObject *pObject = GetObject(i);
|
||||
if ( pObject && pObject->GetType() == iObjectType )
|
||||
{
|
||||
iCount++;
|
||||
}
|
||||
}
|
||||
return iCount;
|
||||
}
|
||||
|
||||
return m_aObjects.Count();
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
CBaseObject *C_TFTeam::GetObject( int num )
|
||||
{
|
||||
Assert( num >= 0 && num < m_aObjects.Count() );
|
||||
return m_aObjects[ num ];
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
C_BasePlayer *C_TFTeam::GetTeamLeader( void )
|
||||
{
|
||||
return m_hLeader.Get();
|
||||
}
|
||||
@@ -0,0 +1,68 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose: Client side CTFTeam class
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================
|
||||
|
||||
#ifndef C_TF_TEAM_H
|
||||
#define C_TF_TEAM_H
|
||||
#ifdef _WIN32
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include "c_team.h"
|
||||
#include "shareddefs.h"
|
||||
#include "c_baseobject.h"
|
||||
|
||||
class C_BaseEntity;
|
||||
class C_BaseObject;
|
||||
class CBaseTechnology;
|
||||
class C_TFPlayer;
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: TF's Team manager
|
||||
//-----------------------------------------------------------------------------
|
||||
class C_TFTeam : public C_Team
|
||||
{
|
||||
DECLARE_CLASS( C_TFTeam, C_Team );
|
||||
DECLARE_CLIENTCLASS();
|
||||
|
||||
public:
|
||||
|
||||
C_TFTeam();
|
||||
virtual ~C_TFTeam();
|
||||
|
||||
int GetFlagCaptures( void ) { return m_nFlagCaptures; }
|
||||
int GetRole( void ) { return m_iRole; }
|
||||
char *Get_Name( void );
|
||||
|
||||
int GetNumObjects( int iObjectType = -1 );
|
||||
CBaseObject *GetObject( int num );
|
||||
|
||||
CUtlVector< CHandle<C_BaseObject> > m_aObjects;
|
||||
|
||||
C_BasePlayer *GetTeamLeader( void );
|
||||
void UpdateTeamName( void );
|
||||
const wchar_t *Get_Localized_Name( void ){ return m_wzTeamname; };
|
||||
|
||||
virtual void OnDataChanged( DataUpdateType_t updateType ) OVERRIDE;
|
||||
|
||||
bool IsUsingCustomTeamName( void ) { return m_bUsingCustomTeamName; }
|
||||
|
||||
// IClientThinkable override
|
||||
virtual void ClientThink();
|
||||
|
||||
private:
|
||||
|
||||
int m_nFlagCaptures;
|
||||
int m_iRole;
|
||||
|
||||
CNetworkHandle( C_BasePlayer, m_hLeader );
|
||||
wchar_t m_wzTeamname[ MAX_TEAM_NAME_LENGTH ];
|
||||
bool m_bUsingCustomTeamName;
|
||||
};
|
||||
|
||||
C_TFTeam *GetGlobalTFTeam( int iTeamNumber );
|
||||
|
||||
#endif // C_TF_TEAM_H
|
||||
@@ -0,0 +1,460 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose: Client's CWeaponBuilder class
|
||||
//
|
||||
// $Workfile: $
|
||||
// $Date: $
|
||||
// $NoKeywords: $
|
||||
//=============================================================================//
|
||||
#include "cbase.h"
|
||||
#include "hud.h"
|
||||
#include "in_buttons.h"
|
||||
#include "clientmode_tf.h"
|
||||
#include "engine/IEngineSound.h"
|
||||
#include "c_tf_weapon_builder.h"
|
||||
#include "c_weapon__stubs.h"
|
||||
#include "iinput.h"
|
||||
#include <vgui/IVGui.h>
|
||||
#include "c_tf_player.h"
|
||||
#include "c_vguiscreen.h"
|
||||
#include "ienginevgui.h"
|
||||
|
||||
STUB_WEAPON_CLASS_IMPLEMENT( tf_weapon_builder, C_TFWeaponBuilder );
|
||||
PRECACHE_WEAPON_REGISTER( tf_weapon_builder );
|
||||
|
||||
// SUPER HACK TO FIX DEMOS. For a couple days, we accidently renamed
|
||||
// CTFWeaponBuilder to C_TFWeaponBuilder on the server. This was fine for
|
||||
// playing the game but broke all previously recorded demos. Fixing this and
|
||||
// re-renaming the class back to the original name fixed all demos recorded
|
||||
// with the brokenly-renamed class. To handle these demos that think the class
|
||||
// is called C_TFWeaponBuilder on the server, we're creating a new class that derives from
|
||||
// the real C_TFWeaponBuilder and does nothing special except that it calls
|
||||
// IMPLEMENT_CLIENTCLASS and maps itself to serverclass "C_TFWeaponBuilder"
|
||||
// (which, if you've followed along, doesn't exist anymore).
|
||||
//
|
||||
// As a history lesson, this broke from the change in tf_player_shared.h in cl 1722245
|
||||
class C_TFWeaponBuilderReplayHack : public C_TFWeaponBuilder
|
||||
{
|
||||
DECLARE_CLASS( C_TFWeaponBuilderReplayHack, C_TFWeaponBuilder );
|
||||
public:
|
||||
DECLARE_CLIENTCLASS();
|
||||
DECLARE_PREDICTABLE();
|
||||
};
|
||||
IMPLEMENT_CLIENTCLASS( C_TFWeaponBuilderReplayHack, DT_TFWeaponBuilder, C_TFWeaponBuilder )
|
||||
BEGIN_PREDICTION_DATA( C_TFWeaponBuilderReplayHack )
|
||||
END_PREDICTION_DATA()
|
||||
|
||||
|
||||
IMPLEMENT_NETWORKCLASS_ALIASED( TFWeaponBuilder, DT_TFWeaponBuilder )
|
||||
|
||||
// Recalc object sprite when we receive a new object type to build
|
||||
void RecvProxy_ObjectType( const CRecvProxyData *pData, void *pStruct, void *pOut )
|
||||
{
|
||||
// Pass to normal Int recvproxy
|
||||
RecvProxy_Int32ToInt32( pData, pStruct, pOut );
|
||||
|
||||
// Reset the object sprite
|
||||
C_TFWeaponBuilder *pBuilder = ( C_TFWeaponBuilder * )pStruct;
|
||||
pBuilder->SetupObjectSelectionSprite();
|
||||
}
|
||||
|
||||
BEGIN_NETWORK_TABLE_NOBASE( C_TFWeaponBuilder, DT_BuilderLocalData )
|
||||
RecvPropInt( RECVINFO(m_iObjectType), 0, RecvProxy_ObjectType ),
|
||||
RecvPropEHandle( RECVINFO(m_hObjectBeingBuilt) ),
|
||||
RecvPropArray3( RECVINFO_ARRAY( m_aBuildableObjectTypes ), RecvPropBool( RECVINFO( m_aBuildableObjectTypes[0] ) ) ),
|
||||
END_NETWORK_TABLE()
|
||||
|
||||
BEGIN_NETWORK_TABLE( C_TFWeaponBuilder, DT_TFWeaponBuilder )
|
||||
RecvPropInt( RECVINFO(m_iBuildState) ),
|
||||
RecvPropDataTable( "BuilderLocalData", 0, 0, &REFERENCE_RECV_TABLE( DT_BuilderLocalData ) ),
|
||||
RecvPropInt( RECVINFO(m_iObjectMode) ),
|
||||
RecvPropFloat( RECVINFO( m_flWheatleyTalkingUntil) ),
|
||||
END_RECV_TABLE()
|
||||
|
||||
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
IMPLEMENT_NETWORKCLASS_ALIASED( TFWeaponSapper, DT_TFWeaponSapper )
|
||||
BEGIN_NETWORK_TABLE( C_TFWeaponSapper, DT_TFWeaponSapper )
|
||||
RecvPropFloat( RECVINFO( m_flChargeBeginTime ) ),
|
||||
END_NETWORK_TABLE()
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
C_TFWeaponBuilder::C_TFWeaponBuilder()
|
||||
{
|
||||
m_iBuildState = 0;
|
||||
m_iObjectType = BUILDER_INVALID_OBJECT;
|
||||
m_pSelectionTextureActive = NULL;
|
||||
m_pSelectionTextureInactive = NULL;
|
||||
m_iValidBuildPoseParam = -1;
|
||||
m_flWheatleyTalkingUntil = 0;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
C_TFWeaponBuilder::~C_TFWeaponBuilder()
|
||||
{
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
// Output : char const
|
||||
//-----------------------------------------------------------------------------
|
||||
const char *C_TFWeaponBuilder::GetCurrentSelectionObjectName( void )
|
||||
{
|
||||
if ( m_iObjectType == -1 || (m_iBuildState == BS_SELECTING) )
|
||||
return "";
|
||||
|
||||
return GetObjectInfo( m_iObjectType )->m_pBuilderWeaponName;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
bool C_TFWeaponBuilder::Deploy( void )
|
||||
{
|
||||
bool bDeploy = BaseClass::Deploy();
|
||||
|
||||
if ( bDeploy )
|
||||
{
|
||||
m_flNextPrimaryAttack = gpGlobals->curtime + 0.35f;
|
||||
m_flNextSecondaryAttack = gpGlobals->curtime; // asap
|
||||
|
||||
CTFPlayer *pPlayer = ToTFPlayer( GetOwner() );
|
||||
if (!pPlayer)
|
||||
return false;
|
||||
|
||||
pPlayer->SetNextAttack( gpGlobals->curtime );
|
||||
|
||||
m_iWorldModelIndex = modelinfo->GetModelIndex( GetWorldModel() );
|
||||
}
|
||||
|
||||
return bDeploy;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void C_TFWeaponBuilder::SecondaryAttack( void )
|
||||
{
|
||||
if ( m_bInAttack2 )
|
||||
return;
|
||||
|
||||
// require a re-press
|
||||
m_bInAttack2 = true;
|
||||
|
||||
CTFPlayer *pOwner = ToTFPlayer( GetOwner() );
|
||||
if ( !pOwner )
|
||||
return;
|
||||
|
||||
pOwner->DoClassSpecialSkill();
|
||||
|
||||
m_flNextSecondaryAttack = gpGlobals->curtime + 0.2f;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: cache the build pos pose param
|
||||
//-----------------------------------------------------------------------------
|
||||
CStudioHdr *C_TFWeaponBuilder::OnNewModel( void )
|
||||
{
|
||||
CStudioHdr *hdr = BaseClass::OnNewModel();
|
||||
|
||||
m_iValidBuildPoseParam = LookupPoseParameter( "valid_build_pos" );
|
||||
|
||||
return hdr;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
// ----------------------------------------------------------------------------
|
||||
void C_TFWeaponBuilder::PostDataUpdate( DataUpdateType_t type )
|
||||
{
|
||||
if ( type == DATA_UPDATE_CREATED )
|
||||
{
|
||||
// m_iViewModelIndex is set by the base Precache(), which didn't know what
|
||||
// type of object we built, so it didn't get the right viewmodel index.
|
||||
// Now that our data is filled in, go and get the right index.
|
||||
const char *pszViewModel = GetViewModel(0);
|
||||
if ( pszViewModel && pszViewModel[0] )
|
||||
{
|
||||
m_iViewModelIndex = CBaseEntity::PrecacheModel( pszViewModel );
|
||||
}
|
||||
}
|
||||
|
||||
BaseClass::PostDataUpdate( type );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: only called for local player
|
||||
//-----------------------------------------------------------------------------
|
||||
void C_TFWeaponBuilder::Redraw()
|
||||
{
|
||||
if ( m_iValidBuildPoseParam >= 0 )
|
||||
{
|
||||
CTFPlayer *pOwner = ToTFPlayer( GetOwner() );
|
||||
if ( !pOwner )
|
||||
return;
|
||||
|
||||
// Assuming here that our model is the same as our viewmodel's model!
|
||||
CBaseViewModel *pViewModel = pOwner->GetViewModel(0);
|
||||
|
||||
if ( pViewModel )
|
||||
{
|
||||
float flPoseParamValue = pViewModel->GetPoseParameter( m_iValidBuildPoseParam );
|
||||
|
||||
C_BaseObject *pObj = m_hObjectBeingBuilt.Get();
|
||||
|
||||
if ( pObj && pObj->WasLastPlacementPosValid() )
|
||||
{
|
||||
// pose param approach 1.0
|
||||
flPoseParamValue = Approach( 1.0, flPoseParamValue, 3.0 * gpGlobals->frametime );
|
||||
}
|
||||
else
|
||||
{
|
||||
// pose param approach 0.0
|
||||
flPoseParamValue = Approach( 0.0, flPoseParamValue, 1.5 * gpGlobals->frametime );
|
||||
}
|
||||
|
||||
pViewModel->SetPoseParameter( m_iValidBuildPoseParam, flPoseParamValue );
|
||||
}
|
||||
}
|
||||
|
||||
BaseClass::Redraw();
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
// Output : Returns true on success, false on failure.
|
||||
//-----------------------------------------------------------------------------
|
||||
bool C_TFWeaponBuilder::IsPlacingObject( void )
|
||||
{
|
||||
if ( m_iBuildState == BS_PLACING || m_iBuildState == BS_PLACING_INVALID )
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
int C_TFWeaponBuilder::GetSlot( void ) const
|
||||
{
|
||||
return GetObjectInfo( m_iObjectType )->m_SelectionSlot;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
int C_TFWeaponBuilder::GetPosition( void ) const
|
||||
{
|
||||
return GetObjectInfo( m_iObjectType )->m_SelectionPosition;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void C_TFWeaponBuilder::SetupObjectSelectionSprite( void )
|
||||
{
|
||||
#ifdef CLIENT_DLL
|
||||
// Use the sprite details from the text file, with a custom sprite
|
||||
char *iconTexture = GetObjectInfo( m_iObjectType )->m_pIconActive;
|
||||
if ( iconTexture && iconTexture[ 0 ] )
|
||||
{
|
||||
m_pSelectionTextureActive = gHUD.GetIcon( iconTexture );
|
||||
}
|
||||
else
|
||||
{
|
||||
m_pSelectionTextureActive = NULL;
|
||||
}
|
||||
|
||||
iconTexture = GetObjectInfo( m_iObjectType )->m_pIconInactive;
|
||||
if ( iconTexture && iconTexture[ 0 ] )
|
||||
{
|
||||
m_pSelectionTextureInactive = gHUD.GetIcon( iconTexture );
|
||||
}
|
||||
else
|
||||
{
|
||||
m_pSelectionTextureInactive = NULL;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
CHudTexture const *C_TFWeaponBuilder::GetSpriteActive( void ) const
|
||||
{
|
||||
return m_pSelectionTextureActive;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
CHudTexture const *C_TFWeaponBuilder::GetSpriteInactive( void ) const
|
||||
{
|
||||
return m_pSelectionTextureInactive;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
// Output : char const
|
||||
//-----------------------------------------------------------------------------
|
||||
const char *C_TFWeaponBuilder::GetPrintName( void ) const
|
||||
{
|
||||
return GetObjectInfo( m_iObjectType )->m_AltModes[m_iObjectMode].pszStatusName;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
int C_TFWeaponBuilder::GetSubType( void )
|
||||
{
|
||||
return m_iObjectType;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Return true if this weapon can be selected via the weapon selection
|
||||
//-----------------------------------------------------------------------------
|
||||
bool C_TFWeaponBuilder::CanBeSelected( void )
|
||||
{
|
||||
CTFPlayer *pOwner = ToTFPlayer( GetOwner() );
|
||||
if ( !pOwner )
|
||||
return false;
|
||||
|
||||
if ( pOwner->CanBuild( m_iObjectType, m_iObjectMode ) != CB_CAN_BUILD )
|
||||
return false;
|
||||
|
||||
return HasAmmo();
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Return true if this weapon should be visible in the weapon selection
|
||||
//-----------------------------------------------------------------------------
|
||||
bool C_TFWeaponBuilder::VisibleInWeaponSelection( void )
|
||||
{
|
||||
if ( BaseClass::VisibleInWeaponSelection() == false )
|
||||
return false;
|
||||
if ( m_iObjectType != BUILDER_INVALID_OBJECT )
|
||||
return GetObjectInfo( m_iObjectType )->m_bVisibleInWeaponSelection;
|
||||
return false;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Return true if this weapon has some ammo
|
||||
//-----------------------------------------------------------------------------
|
||||
bool C_TFWeaponBuilder::HasAmmo( void )
|
||||
{
|
||||
CTFPlayer *pOwner = ToTFPlayer( GetOwner() );
|
||||
if ( !pOwner )
|
||||
return false;
|
||||
|
||||
int iCost = pOwner->m_Shared.CalculateObjectCost( pOwner, m_iObjectType );
|
||||
return ( pOwner->GetBuildResources() >= iCost );
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
// -----------------------------------------------------------------------------
|
||||
bool C_TFWeaponBuilder::CanBuildObjectType( int iObjectType )
|
||||
{
|
||||
if ( iObjectType < 0 || iObjectType >= OBJ_LAST )
|
||||
return false;
|
||||
|
||||
return m_aBuildableObjectTypes[iObjectType];
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
// -----------------------------------------------------------------------------
|
||||
void C_TFWeaponBuilder::UpdateAttachmentModels( void )
|
||||
{
|
||||
if ( m_iObjectType != BUILDER_INVALID_OBJECT && GetObjectInfo( m_iObjectType )->m_bUseItemInfo )
|
||||
{
|
||||
BaseClass::UpdateAttachmentModels();
|
||||
}
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
// -----------------------------------------------------------------------------
|
||||
const char *C_TFWeaponBuilder::GetViewModel( int iViewModel ) const
|
||||
{
|
||||
if ( GetPlayerOwner() == NULL )
|
||||
{
|
||||
return BaseClass::GetViewModel();
|
||||
}
|
||||
|
||||
if ( m_iObjectType != BUILDER_INVALID_OBJECT )
|
||||
{
|
||||
if ( GetObjectInfo( m_iObjectType )->m_bUseItemInfo )
|
||||
return BaseClass::GetViewModel();
|
||||
|
||||
return GetObjectInfo( m_iObjectType )->m_pViewModel;
|
||||
}
|
||||
|
||||
return BaseClass::GetViewModel();
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
const char *C_TFWeaponBuilder::GetWorldModel( void ) const
|
||||
{
|
||||
if ( GetPlayerOwner() == NULL )
|
||||
{
|
||||
return BaseClass::GetWorldModel();
|
||||
}
|
||||
|
||||
if ( m_iObjectType != BUILDER_INVALID_OBJECT )
|
||||
{
|
||||
return GetObjectInfo( m_iObjectType )->m_pPlayerModel;
|
||||
}
|
||||
|
||||
return BaseClass::GetWorldModel();
|
||||
}
|
||||
|
||||
Activity C_TFWeaponBuilder::GetDrawActivity( void )
|
||||
{
|
||||
// sapper used to call different draw animations , one when invis and one when not.
|
||||
// now you can go invis *while* deploying, so let's always use the one-handed deploy.
|
||||
if ( GetType() == OBJ_ATTACHMENT_SAPPER )
|
||||
{
|
||||
return ACT_VM_DRAW_DEPLOYED;
|
||||
}
|
||||
|
||||
return BaseClass::GetDrawActivity();
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
bool C_TFWeaponBuilder::EffectMeterShouldFlash( void )
|
||||
{
|
||||
if ( !GetOwner() )
|
||||
return false;
|
||||
|
||||
int iRoboSapper = 0;
|
||||
CALL_ATTRIB_HOOK_INT_ON_OTHER( GetOwner(), iRoboSapper, robo_sapper );
|
||||
|
||||
return ( iRoboSapper && GetEffectBarProgress() >= 1.f );
|
||||
}
|
||||
|
||||
const char *C_TFWeaponSapper::GetViewModel( int iViewModel ) const
|
||||
{
|
||||
// Skip over Builder's version
|
||||
return C_TFWeaponBase::GetViewModel();
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
const char *C_TFWeaponSapper::GetWorldModel( void ) const
|
||||
{
|
||||
// Skip over Builder's version
|
||||
return C_TFWeaponBase::GetWorldModel();
|
||||
}
|
||||
@@ -0,0 +1,132 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================//
|
||||
|
||||
#ifndef C_TF_WEAPON_BUILDER_H
|
||||
#define C_TF_WEAPON_BUILDER_H
|
||||
#ifdef _WIN32
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include "tf_weaponbase.h"
|
||||
#include "c_baseobject.h"
|
||||
|
||||
#define CTFWeaponBuilder C_TFWeaponBuilder
|
||||
#define CTFWeaponSapper C_TFWeaponSapper
|
||||
|
||||
//=============================================================================
|
||||
// Purpose: Client version of CWeaponBuiler
|
||||
//=============================================================================
|
||||
class C_TFWeaponBuilder : public C_TFWeaponBase
|
||||
{
|
||||
DECLARE_CLASS( C_TFWeaponBuilder, C_TFWeaponBase );
|
||||
public:
|
||||
DECLARE_CLIENTCLASS();
|
||||
DECLARE_PREDICTABLE();
|
||||
|
||||
C_TFWeaponBuilder();
|
||||
~C_TFWeaponBuilder();
|
||||
|
||||
virtual void Redraw();
|
||||
|
||||
virtual void SecondaryAttack();
|
||||
|
||||
virtual bool IsPlacingObject( void );
|
||||
|
||||
virtual const char *GetCurrentSelectionObjectName( void );
|
||||
|
||||
virtual const char *GetViewModel( int iViewModel ) const;
|
||||
virtual const char *GetWorldModel( void ) const;
|
||||
|
||||
virtual bool Deploy( void );
|
||||
virtual void PostDataUpdate( DataUpdateType_t type );
|
||||
|
||||
C_BaseObject *GetPlacementModel( void ) { return m_hObjectBeingBuilt.Get(); }
|
||||
|
||||
virtual void UpdateAttachmentModels( void );
|
||||
|
||||
virtual int GetSlot( void ) const;
|
||||
virtual int GetPosition( void ) const;
|
||||
|
||||
void SetupObjectSelectionSprite( void );
|
||||
|
||||
virtual CHudTexture const *GetSpriteActive( void ) const;
|
||||
virtual CHudTexture const *GetSpriteInactive( void ) const;
|
||||
|
||||
virtual const char *GetPrintName( void ) const;
|
||||
|
||||
virtual int GetSubType( void );
|
||||
|
||||
virtual bool CanBeSelected( void );
|
||||
virtual bool VisibleInWeaponSelection( void );
|
||||
|
||||
virtual bool HasAmmo( void );
|
||||
|
||||
virtual int GetWeaponID( void ) const { return TF_WEAPON_BUILDER; }
|
||||
|
||||
int GetType( void ) { return m_iObjectType; }
|
||||
bool CanBuildObjectType( int iObjectType );
|
||||
|
||||
virtual Activity GetDrawActivity( void );
|
||||
|
||||
virtual CStudioHdr *OnNewModel( void );
|
||||
|
||||
virtual float InternalGetEffectBarRechargeTime( void ) { return 15.0; }
|
||||
virtual int GetEffectBarAmmo( void ) { return TF_AMMO_GRENADES2; }
|
||||
float GetProgress( void ) { return GetEffectBarProgress(); }
|
||||
const char* GetEffectLabelText( void ) { return "#TF_Sapper"; }
|
||||
virtual bool EffectMeterShouldFlash( void );
|
||||
|
||||
public:
|
||||
// Builder Data
|
||||
int m_iBuildState;
|
||||
unsigned int m_iObjectType;
|
||||
unsigned int m_iObjectMode;
|
||||
float m_flStartTime;
|
||||
float m_flTotalTime;
|
||||
|
||||
CHudTexture *m_pSelectionTextureActive;
|
||||
CHudTexture *m_pSelectionTextureInactive;
|
||||
|
||||
// Our placement model
|
||||
CHandle<C_BaseObject> m_hObjectBeingBuilt;
|
||||
|
||||
int m_iValidBuildPoseParam;
|
||||
|
||||
// Wheatly Data
|
||||
float m_flWheatleyTalkingUntil;
|
||||
|
||||
private:
|
||||
C_TFWeaponBuilder( const C_TFWeaponBuilder & );
|
||||
bool m_aBuildableObjectTypes[OBJ_LAST];
|
||||
};
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
class C_TFWeaponSapper : public C_TFWeaponBuilder, public ITFChargeUpWeapon
|
||||
{
|
||||
DECLARE_CLASS( C_TFWeaponSapper, C_TFWeaponBuilder );
|
||||
public:
|
||||
DECLARE_NETWORKCLASS();
|
||||
//DECLARE_PREDICTABLE();
|
||||
|
||||
// ITFChargeUpWeapon
|
||||
virtual bool CanCharge( void ) { return GetChargeMaxTime() > 0; }
|
||||
virtual float GetChargeBeginTime( void ) { return m_flChargeBeginTime; }
|
||||
virtual float GetChargeMaxTime( void ) { float flChargeTime = 0; CALL_ATTRIB_HOOK_FLOAT( flChargeTime, sapper_deploy_time ); return flChargeTime; };
|
||||
|
||||
virtual const char *GetViewModel( int iViewModel ) const;
|
||||
virtual const char *GetWorldModel( void ) const;
|
||||
|
||||
bool IsWheatleyTalking( void ) { return gpGlobals->curtime <= m_flWheatleyTalkingUntil; }
|
||||
|
||||
CNetworkVar( float, m_flChargeBeginTime );
|
||||
};
|
||||
|
||||
|
||||
#endif // C_TF_WEAPON_BUILDER_H
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,161 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
#ifndef TF_CLIENTMODE_H
|
||||
#define TF_CLIENTMODE_H
|
||||
#ifdef _WIN32
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include "clientmode_shared.h"
|
||||
#include "tf_viewport.h"
|
||||
#include "GameUI/IGameUI.h"
|
||||
#include "halloween/tf_weapon_spellbook.h"
|
||||
#include "tf_hud_teamgoal_tournament.h"
|
||||
|
||||
class CHudMenuEngyBuild;
|
||||
class CHudMenuEngyDestroy;
|
||||
class CHudMenuSpyDisguise;
|
||||
class CTFFreezePanel;
|
||||
class CItemQuickSwitchPanel;
|
||||
class CHudEurekaEffectTeleportMenu;
|
||||
class CHudMenuTauntSelection;
|
||||
class CHudInspectPanel;
|
||||
class CHudUpgradePanel;
|
||||
#ifdef STAGING_ONLY
|
||||
class CHudMenuSpyBuild;
|
||||
#endif // STAGING_ONLY
|
||||
#if defined( _X360 )
|
||||
class CTFClientScoreBoardDialog;
|
||||
#endif
|
||||
|
||||
class ClientModeTFNormal : public ClientModeShared
|
||||
{
|
||||
DECLARE_CLASS( ClientModeTFNormal, ClientModeShared );
|
||||
|
||||
private:
|
||||
|
||||
// IClientMode overrides.
|
||||
public:
|
||||
|
||||
ClientModeTFNormal();
|
||||
virtual ~ClientModeTFNormal();
|
||||
|
||||
virtual void Init();
|
||||
virtual void InitViewport();
|
||||
virtual void Shutdown();
|
||||
|
||||
virtual void LevelInit( const char *newmap ) OVERRIDE;
|
||||
|
||||
// virtual int KeyInput( int down, ButtonCode_t keynum, const char *pszCurrentBinding );
|
||||
|
||||
virtual float GetViewModelFOV( void );
|
||||
virtual bool ShouldDrawViewModel();
|
||||
virtual bool ShouldDrawCrosshair( void );
|
||||
virtual bool ShouldBlackoutAroundHUD() OVERRIDE;
|
||||
virtual HeadtrackMovementMode_t ShouldOverrideHeadtrackControl() OVERRIDE;
|
||||
|
||||
int GetDeathMessageStartHeight( void );
|
||||
|
||||
virtual void FireGameEvent( IGameEvent *event );
|
||||
virtual void PostRenderVGui();
|
||||
|
||||
virtual bool CreateMove( float flInputSampleTime, CUserCmd *cmd );
|
||||
|
||||
virtual int HudElementKeyInput( int down, ButtonCode_t keynum, const char *pszCurrentBinding );
|
||||
virtual int HandleSpectatorKeyInput( int down, ButtonCode_t keynum, const char *pszCurrentBinding );
|
||||
|
||||
virtual bool DoPostScreenSpaceEffects( const CViewSetup *pSetup );
|
||||
virtual void Update();
|
||||
virtual void ComputeVguiResConditions( KeyValues *pkvConditions ) OVERRIDE;
|
||||
|
||||
virtual bool IsInfoPanelAllowed() OVERRIDE;
|
||||
virtual void InfoPanelDisplayed() OVERRIDE;
|
||||
virtual bool IsHTMLInfoPanelAllowed() OVERRIDE;
|
||||
|
||||
IGameUI *GameUI( void ) { return m_pGameUI; }
|
||||
|
||||
const char *GetLastConnectedServerName( void ) const; // return the name of the last server we have connected to
|
||||
uint32 GetLastConnectedServerIP( void ) const; // return the IP of the last server we have connected to
|
||||
int GetLastConnectedServerPort( void ) const; // return the port of the last server we have connected to
|
||||
|
||||
void PrintTextToChat( const char *pText, KeyValues *pKeyValues = NULL );
|
||||
void PrintTextToChatPlayer( int iPlayerIndex, const char *pText, KeyValues *pKeyValues = NULL );
|
||||
|
||||
#if !defined(NO_STEAM)
|
||||
STEAM_CALLBACK_MANUAL( ClientModeTFNormal, OnScreenshotRequested, ScreenshotRequested_t, m_CallbackScreenshotRequested );
|
||||
#endif
|
||||
|
||||
bool IsEngyBuildVisible() const;
|
||||
bool IsEngyDestroyVisible() const;
|
||||
bool IsEngyEurekaTeleportVisible() const;
|
||||
bool IsSpyDisguiseVisible() const;
|
||||
bool IsUpgradePanelVisible() const;
|
||||
bool IsTauntSelectPanelVisible() const;
|
||||
|
||||
virtual void OnDemoRecordStart( char const* pDemoBaseName ) OVERRIDE;
|
||||
virtual void OnDemoRecordStop() OVERRIDE;
|
||||
|
||||
private:
|
||||
// void UpdateSpectatorMode( void );
|
||||
|
||||
private:
|
||||
CHudMenuEngyBuild *m_pMenuEngyBuild;
|
||||
CHudMenuEngyDestroy *m_pMenuEngyDestroy;
|
||||
CHudMenuSpyDisguise *m_pMenuSpyDisguise;
|
||||
CHudMenuTauntSelection *m_pMenuTauntSelection;
|
||||
CHudUpgradePanel *m_pMenuUpgradePanel;
|
||||
#ifdef STAGING_ONLY
|
||||
CHudMenuSpyBuild *m_pMenuSpyBuild;
|
||||
#endif // STAGING_ONLY
|
||||
CHudSpellMenu *m_pMenuSpell;
|
||||
CHudEurekaEffectTeleportMenu *m_pEurekaTeleportMenu;
|
||||
CHudTeamGoalTournament *m_pTeamGoalTournament;
|
||||
|
||||
CTFFreezePanel *m_pFreezePanel;
|
||||
CItemQuickSwitchPanel *m_pQuickSwitch;
|
||||
CHudInspectPanel *m_pInspectPanel;
|
||||
IGameUI *m_pGameUI;
|
||||
bool m_wasConnectedLastUpdate;
|
||||
|
||||
char *m_lastServerName;
|
||||
uint32 m_lastServerIP;
|
||||
int m_lastServerPort;
|
||||
uint32 m_lastServerConnectTime;
|
||||
|
||||
float m_flNextAllowedHighFiveHintTime;
|
||||
|
||||
bool m_bInfoPanelShown;
|
||||
bool m_bRestrictInfoPanel;
|
||||
|
||||
void AskFavoriteOrBlacklist() const;
|
||||
|
||||
#if defined( _X360 )
|
||||
CTFClientScoreBoardDialog *m_pScoreboard;
|
||||
#endif
|
||||
};
|
||||
|
||||
inline const char *ClientModeTFNormal::GetLastConnectedServerName( void ) const
|
||||
{
|
||||
return m_lastServerName;
|
||||
}
|
||||
|
||||
inline uint32 ClientModeTFNormal::GetLastConnectedServerIP( void ) const
|
||||
{
|
||||
return m_lastServerIP;
|
||||
}
|
||||
|
||||
inline int ClientModeTFNormal::GetLastConnectedServerPort( void ) const
|
||||
{
|
||||
return m_lastServerPort;
|
||||
}
|
||||
|
||||
extern IClientMode *GetClientModeNormal();
|
||||
extern ClientModeTFNormal* GetClientModeTFNormal();
|
||||
|
||||
void PlayOutOfGameSound( const char *pszSound );
|
||||
float PlaySoundEntry( const char* pszSoundEntryName ); // Returns the duration of the sound
|
||||
#endif // TF_CLIENTMODE_H
|
||||
@@ -0,0 +1,273 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
// c_eyeball_boss.cpp
|
||||
|
||||
#include "cbase.h"
|
||||
#include "NextBot/C_NextBot.h"
|
||||
#include "c_eyeball_boss.h"
|
||||
#include "tf_shareddefs.h"
|
||||
|
||||
// memdbgon must be the last include file in a .cpp file!!!
|
||||
#include "tier0/memdbgon.h"
|
||||
|
||||
#undef NextBot
|
||||
|
||||
#ifdef STAGING_ONLY
|
||||
static ConVar cl_eyeball_boss_debug( "cl_eyeball_boss_debug", "0" );
|
||||
#endif
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
IMPLEMENT_CLIENTCLASS_DT( C_EyeballBoss, DT_EyeballBoss, CEyeballBoss )
|
||||
|
||||
RecvPropVector( RECVINFO( m_lookAtSpot ) ),
|
||||
RecvPropInt( RECVINFO( m_attitude ) ),
|
||||
|
||||
END_RECV_TABLE()
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
C_EyeballBoss::C_EyeballBoss()
|
||||
{
|
||||
m_ghostEffect = NULL;
|
||||
m_auraEffect = NULL;
|
||||
m_attitude = EYEBALL_CALM;
|
||||
m_priorAttitude = m_attitude;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
C_EyeballBoss::~C_EyeballBoss()
|
||||
{
|
||||
if ( m_ghostEffect )
|
||||
{
|
||||
ParticleProp()->StopEmission( m_ghostEffect );
|
||||
m_ghostEffect = NULL;
|
||||
}
|
||||
|
||||
if ( m_auraEffect )
|
||||
{
|
||||
ParticleProp()->StopEmission( m_auraEffect );
|
||||
m_auraEffect = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
void C_EyeballBoss::Spawn( void )
|
||||
{
|
||||
BaseClass::Spawn();
|
||||
|
||||
m_leftRightPoseParameter = -1;
|
||||
m_upDownPoseParameter = -1;
|
||||
|
||||
m_myAngles = vec3_angle;
|
||||
|
||||
m_attitude = EYEBALL_CALM;
|
||||
m_priorAttitude = m_attitude;
|
||||
|
||||
SetNextClientThink( CLIENT_THINK_ALWAYS );
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
void C_EyeballBoss::OnPreDataChanged( DataUpdateType_t updateType )
|
||||
{
|
||||
BaseClass::OnPreDataChanged( updateType );
|
||||
|
||||
m_priorAttitude = m_attitude;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
void C_EyeballBoss::OnDataChanged( DataUpdateType_t updateType )
|
||||
{
|
||||
BaseClass::OnDataChanged( updateType );
|
||||
|
||||
if ( updateType == DATA_UPDATE_CREATED )
|
||||
{
|
||||
const char *pszMaterial = NULL;
|
||||
const char *pszAuraEffect = "eyeboss_aura_calm";
|
||||
switch ( GetTeamNumber() )
|
||||
{
|
||||
case TF_TEAM_RED:
|
||||
{
|
||||
pszAuraEffect = "eyeboss_team_red";
|
||||
//pszMaterial = "models/effects/invulnfx_red.vmt";
|
||||
}
|
||||
break;
|
||||
case TF_TEAM_BLUE:
|
||||
{
|
||||
pszAuraEffect = "eyeboss_team_blue";
|
||||
//pszMaterial = "models/effects/invulnfx_blue.vmt";
|
||||
}
|
||||
break;
|
||||
default:
|
||||
{
|
||||
if ( !m_ghostEffect )
|
||||
{
|
||||
m_ghostEffect = ParticleProp()->Create( "ghost_pumpkin", PATTACH_ABSORIGIN_FOLLOW );
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if ( !m_auraEffect )
|
||||
{
|
||||
m_auraEffect = ParticleProp()->Create( pszAuraEffect, PATTACH_ABSORIGIN_FOLLOW );
|
||||
}
|
||||
|
||||
if ( pszMaterial )
|
||||
{
|
||||
m_InvulnerableMaterial.Init( pszMaterial, TEXTURE_GROUP_CLIENT_EFFECTS );
|
||||
}
|
||||
else
|
||||
{
|
||||
m_InvulnerableMaterial.Shutdown();
|
||||
}
|
||||
}
|
||||
else if ( GetTeamNumber() == TF_TEAM_HALLOWEEN )
|
||||
{
|
||||
// update eyeball aura
|
||||
if ( m_attitude != m_priorAttitude )
|
||||
{
|
||||
// kill the old aura
|
||||
if ( m_auraEffect )
|
||||
{
|
||||
ParticleProp()->StopEmission( m_auraEffect );
|
||||
}
|
||||
|
||||
switch( m_attitude )
|
||||
{
|
||||
case EYEBALL_CALM:
|
||||
m_auraEffect = ParticleProp()->Create( "eyeboss_aura_calm", PATTACH_ABSORIGIN_FOLLOW );
|
||||
break;
|
||||
|
||||
case EYEBALL_GRUMPY:
|
||||
m_auraEffect = ParticleProp()->Create( "eyeboss_aura_grumpy", PATTACH_ABSORIGIN_FOLLOW );
|
||||
break;
|
||||
|
||||
case EYEBALL_ANGRY:
|
||||
m_auraEffect = ParticleProp()->Create( "eyeboss_aura_angry", PATTACH_ABSORIGIN_FOLLOW );
|
||||
break;
|
||||
}
|
||||
|
||||
m_priorAttitude = m_attitude;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
void C_EyeballBoss::ClientThink( void )
|
||||
{
|
||||
// update eyeball aim
|
||||
if ( m_leftRightPoseParameter < 0 )
|
||||
{
|
||||
m_leftRightPoseParameter = LookupPoseParameter( "left_right" );
|
||||
}
|
||||
|
||||
if ( m_upDownPoseParameter < 0 )
|
||||
{
|
||||
m_upDownPoseParameter = LookupPoseParameter( "up_down" );
|
||||
}
|
||||
|
||||
|
||||
Vector myForward, myRight, myUp;
|
||||
AngleVectors( m_myAngles, &myForward, &myRight, &myUp );
|
||||
|
||||
#ifdef STAGING_ONLY
|
||||
if ( cl_eyeball_boss_debug.GetBool() )
|
||||
{
|
||||
QAngle myAbsAngles = GetAbsAngles();
|
||||
|
||||
DevMsg( "%3.2f: EYEBALL BEFORE AIM m_myAngles( %f, %f, %f ), myForward( %f, %f, %f ), GetAbsAngles( %f, %f, %f )\n",
|
||||
gpGlobals->curtime, m_myAngles.x, m_myAngles.y, m_myAngles.z, myForward.x, myForward.y, myForward.z,
|
||||
myAbsAngles.x, myAbsAngles.y, myAbsAngles.z );
|
||||
}
|
||||
#endif
|
||||
|
||||
const float myApproachRate = 3.0f; // 1.0f;
|
||||
|
||||
Vector toTarget = m_lookAtSpot - WorldSpaceCenter();
|
||||
toTarget.NormalizeInPlace();
|
||||
|
||||
myForward += toTarget * myApproachRate * gpGlobals->frametime;
|
||||
myForward.NormalizeInPlace();
|
||||
|
||||
QAngle myNewAngles;
|
||||
VectorAngles( myForward, myNewAngles );
|
||||
|
||||
SetAbsAngles( myNewAngles );
|
||||
m_myAngles = myNewAngles;
|
||||
|
||||
#ifdef STAGING_ONLY
|
||||
if ( cl_eyeball_boss_debug.GetBool() )
|
||||
{
|
||||
QAngle myAbsAngles = GetAbsAngles();
|
||||
|
||||
DevMsg( "%3.2f: EYEBALL AFTER AIM m_myAngles( %f, %f, %f ), myForward( %f, %f, %f ), GetAbsAngles( %f, %f, %f )\n",
|
||||
gpGlobals->curtime, m_myAngles.x, m_myAngles.y, m_myAngles.z, myForward.x, myForward.y, myForward.z,
|
||||
myAbsAngles.x, myAbsAngles.y, myAbsAngles.z );
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
// set pose parameters to aim pupil directly at target
|
||||
float toTargetRight = DotProduct( myRight, toTarget );
|
||||
float toTargetUp = DotProduct( myUp, toTarget );
|
||||
|
||||
if ( m_leftRightPoseParameter >= 0 )
|
||||
{
|
||||
int angle = -50 * toTargetRight;
|
||||
|
||||
SetPoseParameter( m_leftRightPoseParameter, angle );
|
||||
}
|
||||
|
||||
if ( m_upDownPoseParameter >= 0 )
|
||||
{
|
||||
int angle = -50 * toTargetUp;
|
||||
|
||||
SetPoseParameter( m_upDownPoseParameter, angle );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
void C_EyeballBoss::SetDormant( bool bDormant )
|
||||
{
|
||||
BaseClass::SetDormant( bDormant );
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
void C_EyeballBoss::FireEvent( const Vector& origin, const QAngle& angles, int event, const char *options )
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
QAngle const &C_EyeballBoss::GetRenderAngles( void )
|
||||
{
|
||||
return m_myAngles;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
int C_EyeballBoss::InternalDrawModel( int flags )
|
||||
{
|
||||
bool bUseInvulnMaterial = ( GetTeamNumber() == TF_TEAM_RED ) || ( GetTeamNumber() == TF_TEAM_BLUE );
|
||||
|
||||
if ( bUseInvulnMaterial )
|
||||
{
|
||||
modelrender->ForcedMaterialOverride( m_InvulnerableMaterial );
|
||||
}
|
||||
|
||||
int ret = BaseClass::InternalDrawModel( flags );
|
||||
|
||||
if ( bUseInvulnMaterial )
|
||||
{
|
||||
modelrender->ForcedMaterialOverride( NULL );
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
@@ -0,0 +1,55 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
#ifndef C_EYEBALL_BOSS_H
|
||||
#define C_EYEBALL_BOSS_H
|
||||
|
||||
#include "c_ai_basenpc.h"
|
||||
|
||||
#define EYEBALL_ANGRY 2
|
||||
#define EYEBALL_GRUMPY 1
|
||||
#define EYEBALL_CALM 0
|
||||
|
||||
//--------------------------------------------------------------------------------------------------------
|
||||
/**
|
||||
* The client-side implementation of the Halloween Eyeball Boss
|
||||
*/
|
||||
class C_EyeballBoss : public C_NextBotCombatCharacter
|
||||
{
|
||||
public:
|
||||
DECLARE_CLASS( C_EyeballBoss, C_NextBotCombatCharacter );
|
||||
DECLARE_CLIENTCLASS();
|
||||
|
||||
C_EyeballBoss();
|
||||
virtual ~C_EyeballBoss();
|
||||
|
||||
virtual void Spawn( void );
|
||||
virtual void OnPreDataChanged( DataUpdateType_t updateType );
|
||||
virtual void OnDataChanged( DataUpdateType_t updateType );
|
||||
virtual bool IsNextBot() { return true; }
|
||||
|
||||
virtual void FireEvent( const Vector& origin, const QAngle& angles, int event, const char *options );
|
||||
virtual void ClientThink();
|
||||
virtual void SetDormant( bool bDormant );
|
||||
|
||||
virtual QAngle const &GetRenderAngles( void );
|
||||
virtual int InternalDrawModel( int flags );
|
||||
|
||||
private:
|
||||
C_EyeballBoss( const C_EyeballBoss & ); // not defined, not accessible
|
||||
|
||||
Vector m_lookAtSpot;
|
||||
int m_attitude;
|
||||
int m_priorAttitude;
|
||||
|
||||
QAngle m_myAngles;
|
||||
|
||||
int m_leftRightPoseParameter;
|
||||
int m_upDownPoseParameter;
|
||||
|
||||
HPARTICLEFFECT m_ghostEffect;
|
||||
|
||||
HPARTICLEFFECT m_auraEffect;
|
||||
|
||||
CMaterialReference m_InvulnerableMaterial;
|
||||
};
|
||||
|
||||
#endif // C_EYEBALL_BOSS_H
|
||||
@@ -0,0 +1,101 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
// C_HeadlessHatman.cpp
|
||||
|
||||
#include "cbase.h"
|
||||
#include "NextBot/C_NextBot.h"
|
||||
#include "c_headless_hatman.h"
|
||||
|
||||
// memdbgon must be the last include file in a .cpp file!!!
|
||||
#include "tier0/memdbgon.h"
|
||||
|
||||
#undef NextBot
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
IMPLEMENT_CLIENTCLASS_DT( C_HeadlessHatman, DT_HeadlessHatman, CHeadlessHatman )
|
||||
END_RECV_TABLE()
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
C_HeadlessHatman::C_HeadlessHatman()
|
||||
{
|
||||
m_ghostEffect = NULL;
|
||||
m_leftEyeEffect = NULL;
|
||||
m_rightEyeEffect = NULL;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
C_HeadlessHatman::~C_HeadlessHatman()
|
||||
{
|
||||
if ( m_ghostEffect )
|
||||
{
|
||||
ParticleProp()->StopEmission( m_ghostEffect );
|
||||
m_ghostEffect = NULL;
|
||||
}
|
||||
|
||||
if ( m_leftEyeEffect )
|
||||
{
|
||||
ParticleProp()->StopEmission( m_leftEyeEffect );
|
||||
m_leftEyeEffect = NULL;
|
||||
}
|
||||
|
||||
if ( m_rightEyeEffect )
|
||||
{
|
||||
ParticleProp()->StopEmission( m_rightEyeEffect );
|
||||
m_rightEyeEffect = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
void C_HeadlessHatman::Spawn( void )
|
||||
{
|
||||
BaseClass::Spawn();
|
||||
|
||||
m_vecViewOffset = Vector( 0, 0, 100.0f );
|
||||
|
||||
if ( !m_ghostEffect )
|
||||
{
|
||||
m_ghostEffect = ParticleProp()->Create( "ghost_pumpkin", PATTACH_ABSORIGIN_FOLLOW );
|
||||
}
|
||||
|
||||
SetNextClientThink( gpGlobals->curtime + 1.0f );
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
void C_HeadlessHatman::ClientThink( void )
|
||||
{
|
||||
if ( !m_leftEyeEffect )
|
||||
{
|
||||
m_leftEyeEffect = ParticleProp()->Create( "halloween_boss_eye_glow", PATTACH_POINT_FOLLOW, "lefteye" );
|
||||
}
|
||||
|
||||
if ( !m_rightEyeEffect )
|
||||
{
|
||||
m_rightEyeEffect = ParticleProp()->Create( "halloween_boss_eye_glow", PATTACH_POINT_FOLLOW, "righteye" );
|
||||
}
|
||||
|
||||
SetNextClientThink( CLIENT_THINK_NEVER );
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Return the origin for player observers tracking this target
|
||||
Vector C_HeadlessHatman::GetObserverCamOrigin( void )
|
||||
{
|
||||
return EyePosition();
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
void C_HeadlessHatman::FireEvent( const Vector& origin, const QAngle& angles, int event, const char *options )
|
||||
{
|
||||
if ( event == 7001 )
|
||||
{
|
||||
// footstep event
|
||||
EmitSound( "Halloween.HeadlessBossFootfalls" );
|
||||
|
||||
ParticleProp()->Create( "halloween_boss_foot_impact", PATTACH_ABSORIGIN, 0 );
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
#ifndef C_HEADLESS_HATMAN_H
|
||||
#define C_HEADLESS_HATMAN_H
|
||||
|
||||
#include "c_ai_basenpc.h"
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------------
|
||||
/**
|
||||
* The client-side implementation of the Dark Knight
|
||||
*/
|
||||
class C_HeadlessHatman : public C_NextBotCombatCharacter
|
||||
{
|
||||
public:
|
||||
DECLARE_CLASS( C_HeadlessHatman, C_NextBotCombatCharacter );
|
||||
DECLARE_CLIENTCLASS();
|
||||
|
||||
C_HeadlessHatman();
|
||||
virtual ~C_HeadlessHatman();
|
||||
|
||||
public:
|
||||
virtual void Spawn( void );
|
||||
virtual bool IsNextBot() { return true; }
|
||||
|
||||
virtual Vector GetObserverCamOrigin( void ); // Return the origin for player observers tracking this target
|
||||
|
||||
virtual void FireEvent( const Vector& origin, const QAngle& angles, int event, const char *options );
|
||||
|
||||
virtual void ClientThink();
|
||||
|
||||
private:
|
||||
C_HeadlessHatman( const C_HeadlessHatman & ); // not defined, not accessible
|
||||
|
||||
HPARTICLEFFECT m_ghostEffect;
|
||||
HPARTICLEFFECT m_leftEyeEffect;
|
||||
HPARTICLEFFECT m_rightEyeEffect;
|
||||
};
|
||||
|
||||
#endif // C_HEADLESS_HATMAN_H
|
||||
@@ -0,0 +1,148 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
//
|
||||
//
|
||||
//=============================================================================
|
||||
#include "cbase.h"
|
||||
#include "NextBot/C_NextBot.h"
|
||||
#include "c_merasmus.h"
|
||||
|
||||
// memdbgon must be the last include file in a .cpp file!!!
|
||||
#include "tier0/memdbgon.h"
|
||||
|
||||
#undef NextBot
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
IMPLEMENT_CLIENTCLASS_DT( C_Merasmus, DT_Merasmus, CMerasmus )
|
||||
RecvPropBool( RECVINFO( m_bRevealed ) ),
|
||||
RecvPropBool( RECVINFO( m_bIsDoingAOEAttack ) ),
|
||||
RecvPropBool( RECVINFO( m_bStunned ) ),
|
||||
END_RECV_TABLE()
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
C_Merasmus::C_Merasmus()
|
||||
{
|
||||
m_ghostEffect = NULL;
|
||||
m_aoeEffect = NULL;
|
||||
m_stunEffect = NULL;
|
||||
m_bRevealed = false;
|
||||
m_bWasRevealed = false;
|
||||
m_bIsDoingAOEAttack = false;
|
||||
m_bStunned = false;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
C_Merasmus::~C_Merasmus()
|
||||
{
|
||||
if ( m_ghostEffect )
|
||||
{
|
||||
ParticleProp()->StopEmission( m_ghostEffect );
|
||||
m_ghostEffect = NULL;
|
||||
}
|
||||
|
||||
if ( m_aoeEffect )
|
||||
{
|
||||
ParticleProp()->StopEmission( m_aoeEffect );
|
||||
m_aoeEffect = NULL;
|
||||
}
|
||||
|
||||
if ( m_stunEffect )
|
||||
{
|
||||
ParticleProp()->StopEmission( m_stunEffect );
|
||||
m_stunEffect = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
void C_Merasmus::Spawn( void )
|
||||
{
|
||||
BaseClass::Spawn();
|
||||
|
||||
m_vecViewOffset = Vector( 0, 0, 100.0f );
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Return the origin for player observers tracking this target
|
||||
Vector C_Merasmus::GetObserverCamOrigin( void )
|
||||
{
|
||||
return EyePosition();
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
void C_Merasmus::OnPreDataChanged( DataUpdateType_t updateType )
|
||||
{
|
||||
BaseClass::OnPreDataChanged( updateType );
|
||||
|
||||
m_bWasRevealed = m_bRevealed;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
void C_Merasmus::OnDataChanged( DataUpdateType_t updateType )
|
||||
{
|
||||
BaseClass::OnDataChanged( updateType );
|
||||
|
||||
if ( m_bRevealed != m_bWasRevealed )
|
||||
{
|
||||
if ( m_bRevealed )
|
||||
{
|
||||
if ( !m_ghostEffect )
|
||||
{
|
||||
m_ghostEffect = ParticleProp()->Create( "merasmus_ambient_body", PATTACH_ABSORIGIN_FOLLOW );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( m_ghostEffect )
|
||||
{
|
||||
ParticleProp()->StopEmission( m_ghostEffect );
|
||||
m_ghostEffect = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// book attack
|
||||
if ( m_bIsDoingAOEAttack )
|
||||
{
|
||||
if ( !m_aoeEffect )
|
||||
{
|
||||
m_aoeEffect = ParticleProp()->Create( "merasmus_book_attack", PATTACH_POINT_FOLLOW, LookupAttachment( "effect_hand_R" ), Vector( 16.f, 0.f, 0.f ) );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( m_aoeEffect )
|
||||
{
|
||||
ParticleProp()->StopEmission( m_aoeEffect );
|
||||
m_aoeEffect = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
// stunned
|
||||
if ( m_bStunned )
|
||||
{
|
||||
if ( !m_stunEffect )
|
||||
{
|
||||
m_stunEffect = ParticleProp()->Create( "merasmus_dazed", PATTACH_POINT_FOLLOW, LookupAttachment( "head" ) );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( m_stunEffect )
|
||||
{
|
||||
ParticleProp()->StopEmission( m_stunEffect );
|
||||
m_stunEffect = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int C_Merasmus::GetSkin()
|
||||
{
|
||||
return ( m_bIsDoingAOEAttack || m_bStunned ) ? 0 : 1;
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
//
|
||||
//
|
||||
//=============================================================================
|
||||
#ifndef C_MERASMUS_H
|
||||
#define C_MERASMUS_H
|
||||
|
||||
#include "c_ai_basenpc.h"
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------------
|
||||
/**
|
||||
* The client-side implementation of the Dark Knight
|
||||
*/
|
||||
class C_Merasmus : public C_NextBotCombatCharacter
|
||||
{
|
||||
public:
|
||||
DECLARE_CLASS( C_Merasmus, C_NextBotCombatCharacter );
|
||||
DECLARE_CLIENTCLASS();
|
||||
|
||||
C_Merasmus();
|
||||
virtual ~C_Merasmus();
|
||||
|
||||
public:
|
||||
virtual void Spawn( void );
|
||||
virtual bool IsNextBot() { return true; }
|
||||
|
||||
virtual Vector GetObserverCamOrigin( void ); // Return the origin for player observers tracking this target
|
||||
|
||||
virtual void OnPreDataChanged( DataUpdateType_t updateType );
|
||||
virtual void OnDataChanged( DataUpdateType_t updateType );
|
||||
|
||||
virtual int GetSkin();
|
||||
|
||||
private:
|
||||
C_Merasmus( const C_Merasmus & ); // not defined, not accessible
|
||||
|
||||
HPARTICLEFFECT m_ghostEffect;
|
||||
HPARTICLEFFECT m_aoeEffect;
|
||||
HPARTICLEFFECT m_stunEffect;
|
||||
|
||||
bool m_bWasRevealed;
|
||||
CNetworkVar( bool, m_bRevealed );
|
||||
CNetworkVar( bool, m_bIsDoingAOEAttack );
|
||||
CNetworkVar( bool, m_bStunned );
|
||||
};
|
||||
|
||||
#endif // C_MERASMUS_H
|
||||
@@ -0,0 +1,29 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
//
|
||||
//
|
||||
//=============================================================================
|
||||
#include "cbase.h"
|
||||
#include "c_merasmus_dancer.h"
|
||||
|
||||
// memdbgon must be the last include file in a .cpp file!!!
|
||||
#include "tier0/memdbgon.h"
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
IMPLEMENT_CLIENTCLASS_DT( C_MerasmusDancer, DT_MerasmusDancer, CMerasmusDancer )
|
||||
END_RECV_TABLE()
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
C_MerasmusDancer::C_MerasmusDancer()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
C_MerasmusDancer::~C_MerasmusDancer()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,26 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
//
|
||||
//
|
||||
//=============================================================================
|
||||
#ifndef C_MERASMUS_DANCER_H
|
||||
#define C_MERASMUS_DANCER_H
|
||||
|
||||
#include "c_baseanimating.h"
|
||||
|
||||
//--------------------------------------------------------------------------------------------------------
|
||||
|
||||
class C_MerasmusDancer : public C_BaseAnimating
|
||||
{
|
||||
public:
|
||||
DECLARE_CLASS( C_MerasmusDancer, C_BaseAnimating );
|
||||
DECLARE_CLIENTCLASS();
|
||||
|
||||
C_MerasmusDancer();
|
||||
virtual ~C_MerasmusDancer();
|
||||
|
||||
private:
|
||||
C_MerasmusDancer( const C_MerasmusDancer & ); // not defined, not accessible
|
||||
};
|
||||
|
||||
#endif // C_MERASMUS_DANCER_H
|
||||
@@ -0,0 +1,38 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
// c_eyeball_boss.cpp
|
||||
|
||||
#include "cbase.h"
|
||||
#include "NextBot/C_NextBot.h"
|
||||
#include "c_zombie.h"
|
||||
#include "tf_shareddefs.h"
|
||||
|
||||
// memdbgon must be the last include file in a .cpp file!!!
|
||||
#include "tier0/memdbgon.h"
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
IMPLEMENT_CLIENTCLASS_DT( C_Zombie, DT_Zombie, CZombie )
|
||||
RecvPropFloat( RECVINFO( m_flHeadScale ) ),
|
||||
END_RECV_TABLE()
|
||||
|
||||
|
||||
C_Zombie::C_Zombie()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
bool C_Zombie::ShouldCollide( int collisionGroup, int contentsMask ) const
|
||||
{
|
||||
if ( collisionGroup == COLLISION_GROUP_PLAYER_MOVEMENT )
|
||||
return false;
|
||||
|
||||
return BaseClass::ShouldCollide( collisionGroup, contentsMask );
|
||||
}
|
||||
|
||||
extern void BuildBigHeadTransformations( CBaseAnimating *pObject, CStudioHdr *hdr, Vector *pos, Quaternion q[], const matrix3x4_t& cameraTransform, int boneMask, CBoneBitList &boneComputed, float flScale );
|
||||
void C_Zombie::BuildTransformations( CStudioHdr *hdr, Vector *pos, Quaternion q[], const matrix3x4_t& cameraTransform, int boneMask, CBoneBitList &boneComputed )
|
||||
{
|
||||
BaseClass::BuildTransformations( hdr, pos, q, cameraTransform, boneMask, boneComputed );
|
||||
|
||||
m_BoneAccessor.SetWritableBones( BONE_USED_BY_ANYTHING );
|
||||
BuildBigHeadTransformations( this, hdr, pos, q, cameraTransform, boneMask, boneComputed, m_flHeadScale );
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
#ifndef C_ZOMBIE_H
|
||||
#define C_ZOMBIE_H
|
||||
|
||||
#include "c_ai_basenpc.h"
|
||||
#include "props_shared.h"
|
||||
|
||||
//--------------------------------------------------------------------------------------------------------
|
||||
/**
|
||||
* The client-side implementation of the Halloween Zombie
|
||||
*/
|
||||
class C_Zombie : public C_NextBotCombatCharacter
|
||||
{
|
||||
public:
|
||||
DECLARE_CLASS( C_Zombie, C_NextBotCombatCharacter );
|
||||
DECLARE_CLIENTCLASS();
|
||||
|
||||
C_Zombie();
|
||||
|
||||
virtual bool IsNextBot() { return true; }
|
||||
|
||||
virtual bool ShouldCollide( int collisionGroup, int contentsMask ) const;
|
||||
|
||||
virtual void BuildTransformations( CStudioHdr *hdr, Vector *pos, Quaternion q[], const matrix3x4_t& cameraTransform, int boneMask, CBoneBitList &boneComputed ) OVERRIDE;
|
||||
|
||||
private:
|
||||
C_Zombie( const C_Zombie & ); // not defined, not accessible
|
||||
|
||||
float m_flHeadScale;
|
||||
};
|
||||
|
||||
#endif // C_EYEBALL_BOSS_H
|
||||
@@ -0,0 +1,920 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose: Draws CSPort's death notices
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================//
|
||||
#include "cbase.h"
|
||||
#include "hudelement.h"
|
||||
#include "hud_macros.h"
|
||||
#include "c_playerresource.h"
|
||||
#include "iclientmode.h"
|
||||
#include <vgui_controls/Controls.h>
|
||||
#include <vgui_controls/Panel.h>
|
||||
#include <vgui/ISurface.h>
|
||||
#include <vgui/ILocalize.h>
|
||||
#include <KeyValues.h>
|
||||
#include <game_controls/baseviewport.h>
|
||||
#include "clientmode_shared.h"
|
||||
#include "c_baseplayer.h"
|
||||
#include "c_team.h"
|
||||
#include "tf_shareddefs.h"
|
||||
#include "tf_shareddefs.h"
|
||||
#include "tf_gamerules.h"
|
||||
#include "tf_logic_player_destruction.h"
|
||||
|
||||
#include "hud_basedeathnotice.h"
|
||||
|
||||
// memdbgon must be the last include file in a .cpp file!!!
|
||||
#include "tier0/memdbgon.h"
|
||||
|
||||
static ConVar hud_deathnotice_time( "hud_deathnotice_time", "6", 0 );
|
||||
|
||||
|
||||
using namespace vgui;
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
CHudBaseDeathNotice::CHudBaseDeathNotice( const char *pElementName ) :
|
||||
CHudElement( pElementName ), BaseClass( NULL, "HudDeathNotice" )
|
||||
{
|
||||
vgui::Panel *pParent = g_pClientMode->GetViewport();
|
||||
SetParent( pParent );
|
||||
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void CHudBaseDeathNotice::ApplySchemeSettings( IScheme *scheme )
|
||||
{
|
||||
BaseClass::ApplySchemeSettings( scheme );
|
||||
SetPaintBackgroundEnabled( false );
|
||||
|
||||
CalcRoundedCorners();
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void CHudBaseDeathNotice::Init( void )
|
||||
{
|
||||
ListenForGameEvent( "player_death" );
|
||||
ListenForGameEvent( "object_destroyed" );
|
||||
ListenForGameEvent( "teamplay_point_captured" );
|
||||
ListenForGameEvent( "teamplay_capture_blocked" );
|
||||
ListenForGameEvent( "teamplay_flag_event" );
|
||||
ListenForGameEvent( "rd_robot_killed" );
|
||||
ListenForGameEvent( "special_score" );
|
||||
ListenForGameEvent( "team_leader_killed" );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void CHudBaseDeathNotice::VidInit( void )
|
||||
{
|
||||
m_DeathNotices.RemoveAll();
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Draw if we've got at least one death notice in the queue
|
||||
//-----------------------------------------------------------------------------
|
||||
bool CHudBaseDeathNotice::ShouldDraw( void )
|
||||
{
|
||||
return ( CHudElement::ShouldDraw() && ( m_DeathNotices.Count() ) );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
Color CHudBaseDeathNotice::GetTeamColor( int iTeamNumber, bool bLocalPlayerInvolved /* = false */ )
|
||||
{
|
||||
// By default, return the standard team color. Subclasses may override this.
|
||||
return g_PR->GetTeamColor( iTeamNumber );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
int CHudBaseDeathNotice::UseExistingNotice( IGameEvent *event )
|
||||
{
|
||||
if ( FStrEq( event->GetName(), "special_score" ) )
|
||||
{
|
||||
int iIndex = event->GetInt( "player" );
|
||||
|
||||
// Look for a matching pre-existing notice.
|
||||
for ( int i = 0; i < m_DeathNotices.Count(); ++i )
|
||||
{
|
||||
DeathNoticeItem &msg = m_DeathNotices[i];
|
||||
|
||||
if ( !msg.bSpecialScore )
|
||||
continue;
|
||||
|
||||
if ( msg.iKillerID != iIndex )
|
||||
continue;
|
||||
|
||||
return i;
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void CHudBaseDeathNotice::Paint()
|
||||
{
|
||||
// Retire any death notices that have expired
|
||||
RetireExpiredDeathNotices();
|
||||
|
||||
CBaseViewport *pViewport = dynamic_cast<CBaseViewport *>( GetClientModeNormal()->GetViewport() );
|
||||
int yStart = pViewport->GetDeathMessageStartHeight();
|
||||
|
||||
surface()->DrawSetTextFont( m_hTextFont );
|
||||
|
||||
int xMargin = XRES( 10 );
|
||||
int xSpacing = UTIL_ComputeStringWidth( m_hTextFont, L" " );
|
||||
|
||||
int iCount = m_DeathNotices.Count();
|
||||
for ( int i = 0; i < iCount; i++ )
|
||||
{
|
||||
DeathNoticeItem &msg = m_DeathNotices[i];
|
||||
|
||||
CHudTexture *icon = msg.iconDeath;
|
||||
CHudTexture *iconPostKillerName = msg.iconPostKillerName;
|
||||
CHudTexture *iconPreKillerName = msg.iconPreKillerName;
|
||||
CHudTexture *iconPostVictimName = msg.iconPostVictimName;
|
||||
|
||||
wchar_t victim[256]=L"";
|
||||
wchar_t killer[256]=L"";
|
||||
|
||||
// TEMP - print the death icon name if we don't have a material for it
|
||||
|
||||
g_pVGuiLocalize->ConvertANSIToUnicode( msg.Victim.szName, victim, sizeof( victim ) );
|
||||
g_pVGuiLocalize->ConvertANSIToUnicode( msg.Killer.szName, killer, sizeof( killer ) );
|
||||
|
||||
int iVictimTextWide = UTIL_ComputeStringWidth( m_hTextFont, victim ) + xSpacing;
|
||||
int iDeathInfoTextWide= msg.wzInfoText[0] ? UTIL_ComputeStringWidth( m_hTextFont, msg.wzInfoText ) + xSpacing : 0;
|
||||
int iDeathInfoEndTextWide= msg.wzInfoTextEnd[0] ? UTIL_ComputeStringWidth( m_hTextFont, msg.wzInfoTextEnd ) + xSpacing : 0;
|
||||
|
||||
int iKillerTextWide = killer[0] ? UTIL_ComputeStringWidth( m_hTextFont, killer ) + xSpacing : 0;
|
||||
int iLineTall = m_flLineHeight;
|
||||
int iTextTall = surface()->GetFontTall( m_hTextFont );
|
||||
int iconWide = 0, iconTall = 0, iDeathInfoOffset = 0, iVictimTextOffset = 0, iconActualWide = 0;
|
||||
|
||||
int iPreKillerTextWide = msg.wzPreKillerText[0] ? UTIL_ComputeStringWidth( m_hTextFont, msg.wzPreKillerText ) - xSpacing : 0;
|
||||
|
||||
int iconPrekillerWide = 0, iconPrekillerActualWide = 0, iconPrekillerTall = 0;
|
||||
int iconPostkillerWide = 0, iconPostkillerActualWide = 0, iconPostkillerTall = 0;
|
||||
|
||||
int iconPostVictimWide = 0, iconPostVictimActualWide = 0, iconPostVictimTall = 0;
|
||||
|
||||
// Get the local position for this notice
|
||||
if ( icon )
|
||||
{
|
||||
iconActualWide = icon->EffectiveWidth( 1.0f );
|
||||
iconWide = iconActualWide + xSpacing;
|
||||
iconTall = icon->EffectiveHeight( 1.0f );
|
||||
|
||||
int iconTallDesired = iLineTall-YRES(2);
|
||||
Assert( 0 != iconTallDesired );
|
||||
float flScale = (float) iconTallDesired / (float) iconTall;
|
||||
|
||||
iconActualWide *= flScale;
|
||||
iconTall *= flScale;
|
||||
iconWide *= flScale;
|
||||
}
|
||||
|
||||
if ( iconPreKillerName )
|
||||
{
|
||||
iconPrekillerActualWide = iconPreKillerName->EffectiveWidth( 1.0f );
|
||||
iconPrekillerWide = iconPrekillerActualWide;
|
||||
iconPrekillerTall = iconPreKillerName->EffectiveHeight( 1.0f );
|
||||
|
||||
int iconTallDesired = iLineTall - YRES( 2 );
|
||||
Assert( 0 != iconTallDesired );
|
||||
float flScale = (float)iconTallDesired / (float)iconPrekillerTall;
|
||||
|
||||
iconPrekillerActualWide *= flScale;
|
||||
iconPrekillerTall *= flScale;
|
||||
iconPrekillerWide *= flScale;
|
||||
}
|
||||
|
||||
if ( iconPostKillerName )
|
||||
{
|
||||
iconPostkillerActualWide = iconPostKillerName->EffectiveWidth( 1.0f );
|
||||
iconPostkillerWide = iconPostkillerActualWide;
|
||||
iconPostkillerTall = iconPostKillerName->EffectiveHeight( 1.0f );
|
||||
|
||||
int iconTallDesired = iLineTall-YRES(2);
|
||||
Assert( 0 != iconTallDesired );
|
||||
float flScale = (float) iconTallDesired / (float) iconPostkillerTall;
|
||||
|
||||
iconPostkillerActualWide *= flScale;
|
||||
iconPostkillerTall *= flScale;
|
||||
iconPostkillerWide *= flScale;
|
||||
}
|
||||
|
||||
if ( iconPostVictimName )
|
||||
{
|
||||
iconPostVictimActualWide = iconPostVictimName->EffectiveWidth( 1.0f );
|
||||
iconPostVictimWide = iconPostVictimActualWide;
|
||||
iconPostVictimTall = iconPostVictimName->EffectiveHeight( 1.0f );
|
||||
|
||||
int iconTallDesired = iLineTall - YRES( 2 );
|
||||
Assert( 0 != iconTallDesired );
|
||||
float flScale = (float)iconTallDesired / (float)iconPostVictimTall;
|
||||
|
||||
iconPostVictimActualWide *= flScale;
|
||||
iconPostVictimTall *= flScale;
|
||||
iconPostVictimWide *= flScale;
|
||||
}
|
||||
|
||||
int iTotalWide = iKillerTextWide + iconWide + iVictimTextWide + iDeathInfoTextWide + iDeathInfoEndTextWide + ( xMargin * 2 );
|
||||
iTotalWide += iconPrekillerWide + iconPostkillerWide + iPreKillerTextWide + iconPostVictimWide;
|
||||
|
||||
int y = yStart + ( ( iLineTall + m_flLineSpacing ) * i );
|
||||
int yText = y + ( ( iLineTall - iTextTall ) / 2 );
|
||||
int yIcon = y + ( ( iLineTall - iconTall ) / 2 );
|
||||
|
||||
int x=0;
|
||||
if ( m_bRightJustify )
|
||||
{
|
||||
x = GetWide() - iTotalWide;
|
||||
}
|
||||
|
||||
// draw a background panel for the message
|
||||
Vertex_t vert[NUM_BACKGROUND_COORD];
|
||||
GetBackgroundPolygonVerts( x, y+1, x+iTotalWide, y+iLineTall-1, ARRAYSIZE( vert ), vert );
|
||||
surface()->DrawSetTexture( -1 );
|
||||
surface()->DrawSetColor( GetBackgroundColor ( i ) );
|
||||
surface()->DrawTexturedPolygon( ARRAYSIZE( vert ), vert );
|
||||
|
||||
x += xMargin;
|
||||
|
||||
// prekiller icon
|
||||
if ( iconPreKillerName )
|
||||
{
|
||||
int yPreIconTall = y + ( ( iLineTall - iconPrekillerTall ) / 2 );
|
||||
iconPreKillerName->DrawSelf( x, yPreIconTall, iconPrekillerActualWide, iconPrekillerTall, m_clrIcon);
|
||||
x += iconPrekillerWide + xSpacing;
|
||||
}
|
||||
|
||||
if ( killer[0] )
|
||||
{
|
||||
// Draw killer's name
|
||||
DrawText( x, yText, m_hTextFont, GetTeamColor( msg.Killer.iTeam, msg.bLocalPlayerInvolved ), killer );
|
||||
x += iKillerTextWide;
|
||||
}
|
||||
|
||||
// prekiller text
|
||||
if ( msg.wzPreKillerText[0] )
|
||||
{
|
||||
x += xSpacing;
|
||||
DrawText( x + iDeathInfoOffset, yText, m_hTextFont, GetInfoTextColor( i ), msg.wzPreKillerText );
|
||||
x += iPreKillerTextWide;
|
||||
}
|
||||
|
||||
// postkiller icon
|
||||
if ( iconPostKillerName )
|
||||
{
|
||||
int yPreIconTall = y + ( ( iLineTall - iconPostkillerTall ) / 2 );
|
||||
iconPostKillerName->DrawSelf( x, yPreIconTall, iconPostkillerActualWide, iconPostkillerTall, m_clrIcon );
|
||||
x += iconPostkillerWide + xSpacing;
|
||||
}
|
||||
|
||||
// Draw glow behind weapon icon to show it was a crit death
|
||||
if ( msg.bCrit && msg.iconCritDeath )
|
||||
{
|
||||
msg.iconCritDeath->DrawSelf( x, yIcon, iconActualWide, iconTall, m_clrIcon );
|
||||
}
|
||||
|
||||
// Draw death icon
|
||||
if ( icon )
|
||||
{
|
||||
icon->DrawSelf( x, yIcon, iconActualWide, iconTall, m_clrIcon );
|
||||
x += iconWide;
|
||||
}
|
||||
|
||||
// Draw additional info text next to death icon
|
||||
if ( msg.wzInfoText[0] )
|
||||
{
|
||||
if ( msg.bSelfInflicted )
|
||||
{
|
||||
iDeathInfoOffset += iVictimTextWide;
|
||||
iVictimTextOffset -= iDeathInfoTextWide;
|
||||
}
|
||||
|
||||
DrawText( x + iDeathInfoOffset, yText, m_hTextFont, GetInfoTextColor( i ), msg.wzInfoText );
|
||||
x += iDeathInfoTextWide;
|
||||
}
|
||||
|
||||
// Draw victims name
|
||||
DrawText( x + iVictimTextOffset, yText, m_hTextFont, GetTeamColor( msg.Victim.iTeam, msg.bLocalPlayerInvolved ), victim );
|
||||
x += iVictimTextWide;
|
||||
|
||||
// postkiller icon
|
||||
if ( iconPostVictimName )
|
||||
{
|
||||
int yPreIconTall = y + ( ( iLineTall - iconPostVictimTall ) / 2 );
|
||||
iconPostVictimName->DrawSelf( x, yPreIconTall, iconPostVictimActualWide, iconPostVictimTall, m_clrIcon );
|
||||
x += iconPostkillerWide + xSpacing;
|
||||
}
|
||||
|
||||
// Draw Additional Text on the end of the victims name
|
||||
if ( msg.wzInfoTextEnd[0] )
|
||||
{
|
||||
DrawText( x , yText, m_hTextFont, GetInfoTextColor( i ), msg.wzInfoTextEnd );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: This message handler may be better off elsewhere
|
||||
//-----------------------------------------------------------------------------
|
||||
void CHudBaseDeathNotice::RetireExpiredDeathNotices()
|
||||
{
|
||||
// Remove any expired death notices. Loop backwards because we might remove one
|
||||
int iCount = m_DeathNotices.Count();
|
||||
for ( int i = iCount-1; i >= 0; i-- )
|
||||
{
|
||||
if ( gpGlobals->curtime > m_DeathNotices[i].GetExpiryTime() )
|
||||
{
|
||||
m_DeathNotices.Remove(i);
|
||||
}
|
||||
}
|
||||
|
||||
// Do we have too many death messages in the queue?
|
||||
if ( m_DeathNotices.Count() > 0 &&
|
||||
m_DeathNotices.Count() > (int)m_flMaxDeathNotices )
|
||||
{
|
||||
// First, remove any notices not involving the local player, since they are lower priority.
|
||||
iCount = m_DeathNotices.Count();
|
||||
int iNeedToRemove = iCount - (int)m_flMaxDeathNotices;
|
||||
// loop condition is iCount-1 because we won't remove the most recent death notice, otherwise
|
||||
// new non-local-player-involved messages would not appear if the queue was full of messages involving the local player
|
||||
for ( int i = 0; i < iCount-1 && iNeedToRemove > 0 ; i++ )
|
||||
{
|
||||
if ( !m_DeathNotices[i].bLocalPlayerInvolved )
|
||||
{
|
||||
m_DeathNotices.Remove( i );
|
||||
iCount--;
|
||||
iNeedToRemove--;
|
||||
}
|
||||
}
|
||||
|
||||
// Now that we've culled any non-local-player-involved messages up to the amount we needed to remove, see
|
||||
// if we've removed enough
|
||||
iCount = m_DeathNotices.Count();
|
||||
iNeedToRemove = iCount - (int)m_flMaxDeathNotices;
|
||||
if ( iNeedToRemove > 0 )
|
||||
{
|
||||
// if we still have too many messages, then just remove however many we need, oldest first
|
||||
for ( int i = 0; i < iNeedToRemove; i++ )
|
||||
{
|
||||
m_DeathNotices.Remove( 0 );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
bool CHudBaseDeathNotice::EventIsPlayerDeath( const char* eventName )
|
||||
{
|
||||
if ( FStrEq( eventName, "player_death" ) )
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Server's told us that someone's died
|
||||
//-----------------------------------------------------------------------------
|
||||
void CHudBaseDeathNotice::FireGameEvent( IGameEvent *event )
|
||||
{
|
||||
if ( !g_PR )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if ( hud_deathnotice_time.GetFloat() == 0 )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
int iLocalPlayerIndex = GetLocalPlayerIndex();
|
||||
const char *pszEventName = event->GetName();
|
||||
|
||||
bool bPlayerDeath = EventIsPlayerDeath( pszEventName );
|
||||
bool bObjectDeath = FStrEq( pszEventName, "object_destroyed" );
|
||||
bool bSpecialScore = FStrEq( pszEventName, "special_score" );
|
||||
bool bTeamLeaderKilled = false;
|
||||
|
||||
bool bIsFeignDeath = event->GetInt( "death_flags" ) & TF_DEATH_FEIGN_DEATH;
|
||||
if ( bPlayerDeath )
|
||||
{
|
||||
if ( !ShouldShowDeathNotice( event ) )
|
||||
return;
|
||||
|
||||
if ( bIsFeignDeath )
|
||||
{
|
||||
// Only display fake death messages to the enemy team.
|
||||
int victimid = event->GetInt( "userid" );
|
||||
int victim = engine->GetPlayerForUserID( victimid );
|
||||
CBasePlayer *pVictim = UTIL_PlayerByIndex( victim );
|
||||
CBasePlayer *pLocalPlayer = CBasePlayer::GetLocalPlayer();
|
||||
if ( pVictim && pLocalPlayer &&
|
||||
!BAreTeamsEnemies( pLocalPlayer->GetTeamNumber(), pVictim->GetTeamNumber() ) )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if ( iLocalPlayerIndex == victim )
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Add a new death message. Note we always look it up by index rather than create a reference or pointer to it;
|
||||
// additional messages may get added during this function that cause the underlying array to get realloced, so don't
|
||||
// ever keep a pointer to memory here.
|
||||
int iMsg = -1;
|
||||
if ( bPlayerDeath || bSpecialScore )
|
||||
{
|
||||
iMsg = UseExistingNotice( event );
|
||||
}
|
||||
if ( iMsg == -1 )
|
||||
{
|
||||
iMsg = AddDeathNoticeItem();
|
||||
}
|
||||
|
||||
if ( bPlayerDeath || bObjectDeath )
|
||||
{
|
||||
int victim = engine->GetPlayerForUserID( event->GetInt( "userid" ) );
|
||||
int killer = engine->GetPlayerForUserID( event->GetInt( "attacker" ) );
|
||||
const char *killedwith = event->GetString( "weapon" );
|
||||
const char *killedwithweaponlog = event->GetString( "weapon_logclassname" );
|
||||
|
||||
if ( bObjectDeath && victim == 0 )
|
||||
{
|
||||
// for now, no death notices of map placed objects
|
||||
m_DeathNotices.Remove( iMsg );
|
||||
return;
|
||||
}
|
||||
|
||||
// Get the names of the players
|
||||
const char *killer_name = ( killer > 0 ) ? g_PR->GetPlayerName( killer ) : "";
|
||||
const char *victim_name = g_PR->GetPlayerName( victim );
|
||||
if ( !killer_name )
|
||||
{
|
||||
killer_name = "";
|
||||
}
|
||||
|
||||
if ( !victim_name )
|
||||
{
|
||||
victim_name = "";
|
||||
}
|
||||
|
||||
// Make a new death notice
|
||||
bool bLocalPlayerInvolved = false;
|
||||
if ( iLocalPlayerIndex == killer || iLocalPlayerIndex == victim )
|
||||
{
|
||||
bLocalPlayerInvolved = true;
|
||||
}
|
||||
|
||||
if ( event->GetInt( "death_flags" ) & TF_DEATH_AUSTRALIUM )
|
||||
{
|
||||
m_DeathNotices[iMsg].bCrit= true;
|
||||
m_DeathNotices[iMsg].iconCritDeath = GetIcon( "d_australium", bLocalPlayerInvolved ? kDeathNoticeIcon_Inverted : kDeathNoticeIcon_Standard );
|
||||
}
|
||||
else if ( event->GetInt( "damagebits" ) & DMG_CRITICAL )
|
||||
{
|
||||
m_DeathNotices[iMsg].bCrit= true;
|
||||
m_DeathNotices[iMsg].iconCritDeath = GetIcon( "d_crit", bLocalPlayerInvolved ? kDeathNoticeIcon_Inverted : kDeathNoticeIcon_Standard );
|
||||
}
|
||||
else
|
||||
{
|
||||
m_DeathNotices[iMsg].bCrit= false;
|
||||
m_DeathNotices[iMsg].iconCritDeath = NULL;
|
||||
}
|
||||
|
||||
m_DeathNotices[iMsg].bLocalPlayerInvolved = bLocalPlayerInvolved;
|
||||
m_DeathNotices[iMsg].Killer.iTeam = ( killer > 0 ) ? g_PR->GetTeam( killer ) : 0;
|
||||
m_DeathNotices[iMsg].Victim.iTeam = g_PR->GetTeam( victim );
|
||||
Q_strncpy( m_DeathNotices[iMsg].Killer.szName, killer_name, ARRAYSIZE( m_DeathNotices[iMsg].Killer.szName ) );
|
||||
Q_strncpy( m_DeathNotices[iMsg].Victim.szName, victim_name, ARRAYSIZE( m_DeathNotices[iMsg].Victim.szName ) );
|
||||
if ( killedwith && *killedwith )
|
||||
{
|
||||
Q_snprintf( m_DeathNotices[iMsg].szIcon, sizeof(m_DeathNotices[iMsg].szIcon), "d_%s", killedwith );
|
||||
}
|
||||
if ( !killer || killer == victim )
|
||||
{
|
||||
m_DeathNotices[iMsg].bSelfInflicted = true;
|
||||
m_DeathNotices[iMsg].Killer.szName[0] = 0;
|
||||
|
||||
if ( event->GetInt( "death_flags" ) & TF_DEATH_PURGATORY )
|
||||
{
|
||||
// special case icon for dying in purgatory
|
||||
Q_strncpy( m_DeathNotices[iMsg].szIcon, "d_purgatory", ARRAYSIZE( m_DeathNotices[iMsg].szIcon ) );
|
||||
}
|
||||
else if ( event->GetInt( "damagebits" ) & DMG_FALL )
|
||||
{
|
||||
// special case text for falling death
|
||||
V_wcsncpy( m_DeathNotices[iMsg].wzInfoText, g_pVGuiLocalize->Find( "#DeathMsg_Fall" ), sizeof( m_DeathNotices[iMsg].wzInfoText ) );
|
||||
}
|
||||
else if ( ( event->GetInt( "damagebits" ) & DMG_VEHICLE ) || ( 0 == Q_stricmp( m_DeathNotices[iMsg].szIcon, "d_tracktrain" ) ) )
|
||||
{
|
||||
// special case icon for hit-by-vehicle death
|
||||
Q_strncpy( m_DeathNotices[iMsg].szIcon, "d_vehicle", ARRAYSIZE( m_DeathNotices[iMsg].szIcon ) );
|
||||
}
|
||||
}
|
||||
|
||||
m_DeathNotices[iMsg].iWeaponID = event->GetInt( "weaponid" );
|
||||
m_DeathNotices[iMsg].iKillerID = event->GetInt( "attacker" );
|
||||
m_DeathNotices[iMsg].iVictimID = event->GetInt( "userid" );
|
||||
|
||||
char sDeathMsg[512];
|
||||
|
||||
// Record the death notice in the console
|
||||
if ( m_DeathNotices[iMsg].bSelfInflicted )
|
||||
{
|
||||
if ( !strcmp( m_DeathNotices[iMsg].szIcon, "d_worldspawn" ) )
|
||||
{
|
||||
Q_snprintf( sDeathMsg, sizeof( sDeathMsg ), "%s died.", m_DeathNotices[iMsg].Victim.szName );
|
||||
}
|
||||
else // d_world
|
||||
{
|
||||
Q_snprintf( sDeathMsg, sizeof( sDeathMsg ), "%s suicided.", m_DeathNotices[iMsg].Victim.szName );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Q_snprintf( sDeathMsg, sizeof( sDeathMsg ), "%s killed %s", m_DeathNotices[iMsg].Killer.szName, m_DeathNotices[iMsg].Victim.szName );
|
||||
|
||||
if ( killedwithweaponlog && killedwithweaponlog[0] && ( killedwithweaponlog[0] > 13 ) )
|
||||
{
|
||||
Q_strncat( sDeathMsg, VarArgs( " with %s.", killedwithweaponlog ), sizeof( sDeathMsg ), COPY_ALL_CHARACTERS );
|
||||
}
|
||||
else if ( m_DeathNotices[iMsg].szIcon[0] && ( m_DeathNotices[iMsg].szIcon[0] > 13 ) )
|
||||
{
|
||||
Q_strncat( sDeathMsg, VarArgs( " with %s.", &m_DeathNotices[iMsg].szIcon[2] ), sizeof( sDeathMsg ), COPY_ALL_CHARACTERS );
|
||||
}
|
||||
}
|
||||
|
||||
if ( FStrEq( pszEventName, "player_death" ) )
|
||||
{
|
||||
if ( m_DeathNotices[iMsg].bCrit )
|
||||
{
|
||||
Msg( "%s (crit)\n", sDeathMsg );
|
||||
}
|
||||
else
|
||||
{
|
||||
Msg( "%s\n", sDeathMsg );
|
||||
}
|
||||
}
|
||||
}
|
||||
else if ( FStrEq( "teamplay_point_captured", pszEventName ) )
|
||||
{
|
||||
GetLocalizedControlPointName( event, m_DeathNotices[iMsg].Victim.szName, ARRAYSIZE( m_DeathNotices[iMsg].Victim.szName ) );
|
||||
|
||||
// Array of capper indices
|
||||
const char *cappers = event->GetString("cappers");
|
||||
|
||||
char szCappers[256];
|
||||
szCappers[0] = '\0';
|
||||
|
||||
int len = Q_strlen(cappers);
|
||||
for( int i=0;i<len;i++ )
|
||||
{
|
||||
int iPlayerIndex = (int)cappers[i];
|
||||
|
||||
Assert( iPlayerIndex > 0 && iPlayerIndex <= gpGlobals->maxClients );
|
||||
|
||||
const char *pPlayerName = g_PR->GetPlayerName( iPlayerIndex );
|
||||
|
||||
if ( i == 0 )
|
||||
{
|
||||
// use first player as the team
|
||||
m_DeathNotices[iMsg].Killer.iTeam = g_PR->GetTeam( iPlayerIndex );
|
||||
m_DeathNotices[iMsg].Victim.iTeam = TEAM_UNASSIGNED;
|
||||
}
|
||||
else
|
||||
{
|
||||
Q_strncat( szCappers, ", ", sizeof(szCappers), 2 );
|
||||
}
|
||||
|
||||
Q_strncat( szCappers, pPlayerName, sizeof(szCappers), COPY_ALL_CHARACTERS );
|
||||
if ( iLocalPlayerIndex == iPlayerIndex )
|
||||
m_DeathNotices[iMsg].bLocalPlayerInvolved = true;
|
||||
}
|
||||
|
||||
Q_strncpy( m_DeathNotices[iMsg].Killer.szName, szCappers, sizeof(m_DeathNotices[iMsg].Killer.szName) );
|
||||
V_wcsncpy( m_DeathNotices[iMsg].wzInfoText, g_pVGuiLocalize->Find( len > 1 ? "#Msg_Captured_Multiple" : "#Msg_Captured" ), sizeof( m_DeathNotices[iMsg].wzInfoText ) );
|
||||
|
||||
// print a log message
|
||||
Msg( "%s captured %s for team #%d\n", m_DeathNotices[iMsg].Killer.szName, m_DeathNotices[iMsg].Victim.szName, m_DeathNotices[iMsg].Killer.iTeam );
|
||||
}
|
||||
else if ( FStrEq( "teamplay_capture_blocked", pszEventName ) )
|
||||
{
|
||||
GetLocalizedControlPointName( event, m_DeathNotices[iMsg].Victim.szName, ARRAYSIZE( m_DeathNotices[iMsg].Victim.szName ) );
|
||||
V_wcsncpy( m_DeathNotices[iMsg].wzInfoText, g_pVGuiLocalize->Find( "#Msg_Defended" ), sizeof( m_DeathNotices[iMsg].wzInfoText ) );
|
||||
|
||||
int iPlayerIndex = event->GetInt( "blocker" );
|
||||
const char *blocker_name = g_PR->GetPlayerName( iPlayerIndex );
|
||||
Q_strncpy( m_DeathNotices[iMsg].Killer.szName, blocker_name, ARRAYSIZE( m_DeathNotices[iMsg].Killer.szName ) );
|
||||
m_DeathNotices[iMsg].Killer.iTeam = g_PR->GetTeam( iPlayerIndex );
|
||||
if ( iLocalPlayerIndex == iPlayerIndex )
|
||||
m_DeathNotices[iMsg].bLocalPlayerInvolved = true;
|
||||
|
||||
// print a log message
|
||||
Msg( "%s defended %s for team #%d\n", m_DeathNotices[iMsg].Killer.szName, m_DeathNotices[iMsg].Victim.szName, m_DeathNotices[iMsg].Killer.iTeam );
|
||||
}
|
||||
else if ( FStrEq( "teamplay_flag_event", pszEventName ) )
|
||||
{
|
||||
// don't handle any flag events for death notices while in player destruction mode
|
||||
if ( CTFPlayerDestructionLogic::GetRobotDestructionLogic() && CTFPlayerDestructionLogic::GetRobotDestructionLogic()->GetType() == CTFPlayerDestructionLogic::TYPE_PLAYER_DESTRUCTION )
|
||||
{
|
||||
// don't put anything up
|
||||
m_DeathNotices.Remove( iMsg );
|
||||
return;
|
||||
}
|
||||
|
||||
const char *pszMsgKey = NULL;
|
||||
int iEventType = event->GetInt( "eventtype" );
|
||||
|
||||
bool bIsMvM = TFGameRules() && TFGameRules()->IsMannVsMachineMode();
|
||||
if ( bIsMvM )
|
||||
{
|
||||
// MvM only cares about Defend notifications
|
||||
if ( iEventType != TF_FLAGEVENT_DEFEND )
|
||||
{
|
||||
// unsupported, don't put anything up
|
||||
m_DeathNotices.Remove( iMsg );
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
bool bIsHalloween2014 = TFGameRules() && TFGameRules()->IsHalloweenScenario( CTFGameRules::HALLOWEEN_SCENARIO_DOOMSDAY );
|
||||
|
||||
switch ( iEventType )
|
||||
{
|
||||
case TF_FLAGEVENT_PICKUP:
|
||||
pszMsgKey = bIsHalloween2014 ? "#Msg_PickedUpFlagHalloween2014" : "#Msg_PickedUpFlag";
|
||||
break;
|
||||
case TF_FLAGEVENT_CAPTURE:
|
||||
pszMsgKey = bIsHalloween2014 ? "#Msg_CapturedFlagHalloween2014" : "#Msg_CapturedFlag";
|
||||
break;
|
||||
case TF_FLAGEVENT_DEFEND:
|
||||
if ( bIsMvM )
|
||||
{
|
||||
pszMsgKey = "#Msg_DefendedBomb";
|
||||
}
|
||||
else
|
||||
{
|
||||
pszMsgKey = bIsHalloween2014 ? "#Msg_DefendedFlagHalloween2014" : "#Msg_DefendedFlag";
|
||||
}
|
||||
|
||||
|
||||
break;
|
||||
|
||||
// Add this when we can get localization for it
|
||||
//case TF_FLAGEVENT_DROPPED:
|
||||
// pszMsgKey = "#Msg_DroppedFlag";
|
||||
// break;
|
||||
|
||||
default:
|
||||
// unsupported, don't put anything up
|
||||
m_DeathNotices.Remove( iMsg );
|
||||
return;
|
||||
}
|
||||
|
||||
wchar_t *pwzEventText = g_pVGuiLocalize->Find( pszMsgKey );
|
||||
Assert( pwzEventText );
|
||||
if ( pwzEventText )
|
||||
{
|
||||
V_wcsncpy( m_DeathNotices[iMsg].wzInfoText, pwzEventText, sizeof( m_DeathNotices[iMsg].wzInfoText ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
V_memset( m_DeathNotices[iMsg].wzInfoText, 0, sizeof( m_DeathNotices[iMsg].wzInfoText ) );
|
||||
}
|
||||
|
||||
int iPlayerIndex = event->GetInt( "player" );
|
||||
const char *szPlayerName = g_PR->GetPlayerName( iPlayerIndex );
|
||||
Q_strncpy( m_DeathNotices[iMsg].Killer.szName, szPlayerName, ARRAYSIZE( m_DeathNotices[iMsg].Killer.szName ) );
|
||||
m_DeathNotices[iMsg].Killer.iTeam = g_PR->GetTeam( iPlayerIndex );
|
||||
if ( iLocalPlayerIndex == iPlayerIndex )
|
||||
m_DeathNotices[iMsg].bLocalPlayerInvolved = true;
|
||||
}
|
||||
else if ( bSpecialScore )
|
||||
{
|
||||
DeathNoticeItem &msg = m_DeathNotices[iMsg];
|
||||
|
||||
int iScorer = event->GetInt( "player" );
|
||||
const char *pszScorer = ( iScorer > 0 ) ? g_PR->GetPlayerName( iScorer ) : "";
|
||||
if ( !pszScorer )
|
||||
{
|
||||
pszScorer = "";
|
||||
}
|
||||
Q_strncpy( msg.Killer.szName, pszScorer, ARRAYSIZE( msg.Killer.szName ) );
|
||||
|
||||
m_DeathNotices[iMsg].Killer.iTeam = ( iScorer > 0 ) ? g_PR->GetTeam( iScorer ) : 0;
|
||||
msg.bLocalPlayerInvolved = ( iScorer == GetLocalPlayerIndex() );
|
||||
msg.iKillerID = iScorer;
|
||||
msg.bCrit = false;
|
||||
msg.iconCritDeath = NULL;
|
||||
msg.bSpecialScore = true;
|
||||
|
||||
wchar_t wzCount[10];
|
||||
_snwprintf( wzCount, ARRAYSIZE( wzCount ), L"%d", ++msg.iCount );
|
||||
g_pVGuiLocalize->ConstructString_safe( msg.wzInfoText, g_pVGuiLocalize->Find( "#SpecialScore_Count" ), 1, wzCount );
|
||||
}
|
||||
else if ( FStrEq( "team_leader_killed", pszEventName ) )
|
||||
{
|
||||
DeathNoticeItem &msg = m_DeathNotices[iMsg];
|
||||
|
||||
int iKiller = event->GetInt( "killer" );
|
||||
const char *pszKiller = ( iKiller > 0 ) ? g_PR->GetPlayerName( iKiller ) : "";
|
||||
if ( !pszKiller )
|
||||
{
|
||||
pszKiller = "";
|
||||
}
|
||||
Q_strncpy( msg.Killer.szName, pszKiller, ARRAYSIZE( msg.Killer.szName ) );
|
||||
m_DeathNotices[iMsg].Killer.iTeam = ( iKiller > 0 ) ? g_PR->GetTeam( iKiller ) : 0;
|
||||
|
||||
int iVictim = event->GetInt( "victim" );
|
||||
const char *pszVictim = ( iVictim > 0 ) ? g_PR->GetPlayerName( iVictim ) : "";
|
||||
if ( !pszVictim )
|
||||
{
|
||||
pszVictim = "";
|
||||
}
|
||||
Q_strncpy( msg.Victim.szName, pszVictim, ARRAYSIZE( msg.Victim.szName ) );
|
||||
m_DeathNotices[iMsg].Victim.iTeam = ( iVictim > 0 ) ? g_PR->GetTeam( iVictim ) : 0;
|
||||
|
||||
msg.bLocalPlayerInvolved = ( ( iKiller == GetLocalPlayerIndex() ) || ( iVictim == GetLocalPlayerIndex() ) );
|
||||
msg.iKillerID = iKiller;
|
||||
msg.iVictimID = iVictim;
|
||||
msg.bCrit = false;
|
||||
msg.iconCritDeath = NULL;
|
||||
|
||||
wchar_t *pwzEventText = g_pVGuiLocalize->Find( "#TeamLeader_Kill" );
|
||||
Assert( pwzEventText );
|
||||
if ( pwzEventText )
|
||||
{
|
||||
V_wcsncpy( m_DeathNotices[iMsg].wzInfoText, pwzEventText, sizeof( m_DeathNotices[iMsg].wzInfoText ) );
|
||||
}
|
||||
|
||||
bTeamLeaderKilled = true;
|
||||
}
|
||||
|
||||
OnGameEvent( event, iMsg );
|
||||
|
||||
if ( !bSpecialScore && !bTeamLeaderKilled )
|
||||
{
|
||||
if ( !m_DeathNotices[iMsg].iconDeath && m_DeathNotices[iMsg].szIcon )
|
||||
{
|
||||
// Try and find the death identifier in the icon list
|
||||
// On consoles, we flip usage of the inverted icon to make it more visible
|
||||
bool bInverted = m_DeathNotices[iMsg].bLocalPlayerInvolved;
|
||||
if ( IsConsole() )
|
||||
{
|
||||
bInverted = !bInverted;
|
||||
}
|
||||
m_DeathNotices[iMsg].iconDeath = GetIcon( m_DeathNotices[iMsg].szIcon, bInverted ? kDeathNoticeIcon_Inverted : kDeathNoticeIcon_Standard );
|
||||
if ( !m_DeathNotices[iMsg].iconDeath )
|
||||
{
|
||||
// Can't find it, so use the default skull & crossbones icon
|
||||
m_DeathNotices[iMsg].iconDeath = GetIcon( "d_skull_tf", m_DeathNotices[iMsg].bLocalPlayerInvolved ? kDeathNoticeIcon_Inverted : kDeathNoticeIcon_Standard );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Gets the localized name of the control point sent in the event
|
||||
//-----------------------------------------------------------------------------
|
||||
void CHudBaseDeathNotice::GetLocalizedControlPointName( IGameEvent *event, char *namebuf, int namelen )
|
||||
{
|
||||
// Cap point name ( MATTTODO: can't we find this from the point index ? )
|
||||
const char *pName = event->GetString( "cpname", "Unnamed Control Point" );
|
||||
const wchar_t *pLocalizedName = g_pVGuiLocalize->Find( pName );
|
||||
|
||||
if ( pLocalizedName )
|
||||
{
|
||||
g_pVGuiLocalize->ConvertUnicodeToANSI( pLocalizedName, namebuf, namelen );
|
||||
}
|
||||
else
|
||||
{
|
||||
Q_strncpy( namebuf, pName, namelen );
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Adds a new death notice to the queue
|
||||
//-----------------------------------------------------------------------------
|
||||
int CHudBaseDeathNotice::AddDeathNoticeItem()
|
||||
{
|
||||
int iMsg = m_DeathNotices.AddToTail();
|
||||
DeathNoticeItem &msg = m_DeathNotices[iMsg];
|
||||
msg.flCreationTime = gpGlobals->curtime;
|
||||
return iMsg;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: draw text helper
|
||||
//-----------------------------------------------------------------------------
|
||||
void CHudBaseDeathNotice::DrawText( int x, int y, HFont hFont, Color clr, const wchar_t *szText )
|
||||
{
|
||||
surface()->DrawSetTextPos( x, y );
|
||||
surface()->DrawSetTextColor( clr );
|
||||
surface()->DrawSetTextFont( hFont ); //reset the font, draw icon can change it
|
||||
surface()->DrawUnicodeString( szText, vgui::FONT_DRAW_NONADDITIVE );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Creates a rounded-corner polygon that fits in the specified bounds
|
||||
//-----------------------------------------------------------------------------
|
||||
void CHudBaseDeathNotice::GetBackgroundPolygonVerts( int x0, int y0, int x1, int y1, int iVerts, vgui::Vertex_t vert[] )
|
||||
{
|
||||
Assert( iVerts == NUM_BACKGROUND_COORD );
|
||||
// use the offsets we generated for one corner and apply those to the passed-in dimensions to create verts for the poly
|
||||
for ( int i = 0; i < NUM_CORNER_COORD; i++ )
|
||||
{
|
||||
int j = ( NUM_CORNER_COORD-1 ) - i;
|
||||
// upper left corner
|
||||
vert[i].Init( Vector2D( x0 + m_CornerCoord[i].x, y0 + m_CornerCoord[i].y ) );
|
||||
// upper right corner
|
||||
vert[i+NUM_CORNER_COORD].Init( Vector2D( x1 - m_CornerCoord[j].x, y0 + m_CornerCoord[j].y ) );
|
||||
// lower right corner
|
||||
vert[i+(NUM_CORNER_COORD*2)].Init( Vector2D( x1 - m_CornerCoord[i].x, y1 - m_CornerCoord[i].y ) );
|
||||
// lower left corner
|
||||
vert[i+(NUM_CORNER_COORD*3)].Init( Vector2D( x0 + m_CornerCoord[j].x, y1 - m_CornerCoord[j].y) );
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Creates the offsets for rounded corners based on current screen res
|
||||
//-----------------------------------------------------------------------------
|
||||
void CHudBaseDeathNotice::CalcRoundedCorners()
|
||||
{
|
||||
// generate the offset geometry for upper left corner
|
||||
int iMax = ARRAYSIZE( m_CornerCoord );
|
||||
for ( int i = 0; i < iMax; i++ )
|
||||
{
|
||||
m_CornerCoord[i].x = m_flCornerRadius * ( 1 - cos( ( (float) i / (float) (iMax - 1 ) ) * ( M_PI / 2 ) ) );
|
||||
m_CornerCoord[i].y = m_flCornerRadius * ( 1 - sin( ( (float) i / (float) (iMax - 1 ) ) * ( M_PI / 2 ) ) );
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Gets specified icon
|
||||
//-----------------------------------------------------------------------------
|
||||
CHudTexture *CHudBaseDeathNotice::GetIcon( const char *szIcon, EDeathNoticeIconFormat eIconFormat )
|
||||
{
|
||||
// adjust the style (prefix) of the icon if requested
|
||||
if ( eIconFormat != kDeathNoticeIcon_Standard && V_strncmp( "d_", szIcon, 2 ) == 0 )
|
||||
{
|
||||
Assert( eIconFormat == kDeathNoticeIcon_Inverted );
|
||||
|
||||
const char *cszNewPrefix = "dneg_";
|
||||
unsigned int iNewPrefixLen = V_strlen( cszNewPrefix );
|
||||
|
||||
// generate new string with correct prefix
|
||||
enum { kIconTempStringLen = 256 };
|
||||
|
||||
char szIconTmp[kIconTempStringLen];
|
||||
V_strncpy( szIconTmp, cszNewPrefix, kIconTempStringLen );
|
||||
V_strncat( szIconTmp, szIcon + 2, kIconTempStringLen - iNewPrefixLen );
|
||||
|
||||
CHudTexture *pIcon = gHUD.GetIcon( szIconTmp );
|
||||
|
||||
// return inverted version if found
|
||||
if ( pIcon )
|
||||
return pIcon;
|
||||
}
|
||||
|
||||
// we either requested the default style or we requested an alternate style but
|
||||
// didn't have the art for it; either way, we can't, so fall back to our default
|
||||
return gHUD.GetIcon( szIcon );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Gets the expiry time for this death notice item
|
||||
//-----------------------------------------------------------------------------
|
||||
float DeathNoticeItem::GetExpiryTime()
|
||||
{
|
||||
float flDuration = hud_deathnotice_time.GetFloat();
|
||||
if ( bLocalPlayerInvolved )
|
||||
{
|
||||
// if the local player is involved, make the message last longer
|
||||
flDuration *= 2;
|
||||
}
|
||||
return flCreationTime + flDuration;
|
||||
}
|
||||
@@ -0,0 +1,145 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================//
|
||||
|
||||
#ifndef HUD_BASEDEATHNOTICE_H
|
||||
#define HUD_BASEDEATHNOTICE_H
|
||||
#ifdef _WIN32
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
// Player entries in a death notice
|
||||
struct DeathNoticePlayer
|
||||
{
|
||||
DeathNoticePlayer()
|
||||
{
|
||||
szName[0] = 0;
|
||||
iTeam = TEAM_UNASSIGNED;
|
||||
}
|
||||
char szName[MAX_PLAYER_NAME_LENGTH*2]; // big enough for player name and additional information
|
||||
int iTeam; // team #
|
||||
};
|
||||
|
||||
// Contents of each entry in our list of death notices
|
||||
struct DeathNoticeItem
|
||||
{
|
||||
DeathNoticeItem()
|
||||
{
|
||||
szIcon[0]=0;
|
||||
wzInfoText[0]=0;
|
||||
wzInfoTextEnd[0]=0;
|
||||
iconDeath = NULL;
|
||||
iconCritDeath = NULL;
|
||||
bSelfInflicted = false;
|
||||
bLocalPlayerInvolved = false;
|
||||
bCrit = false;
|
||||
flCreationTime = 0;
|
||||
iCount = 0;
|
||||
iWeaponID = -1;
|
||||
iKillerID = -1;
|
||||
iVictimID = -1;
|
||||
|
||||
iconPreKillerName = NULL;
|
||||
iconPostKillerName = NULL;
|
||||
wzPreKillerText[0] = 0;
|
||||
iconPostVictimName = NULL;
|
||||
|
||||
bSpecialScore = false;
|
||||
}
|
||||
|
||||
float GetExpiryTime();
|
||||
|
||||
DeathNoticePlayer Killer;
|
||||
DeathNoticePlayer Victim;
|
||||
char szIcon[32]; // name of icon to display
|
||||
wchar_t wzInfoText[32]; // any additional text to display next to icon
|
||||
wchar_t wzInfoTextEnd[32]; // any additional text to display next to victim name
|
||||
CHudTexture *iconDeath;
|
||||
CHudTexture *iconCritDeath; // crit background icon
|
||||
|
||||
CHudTexture *iconPreKillerName;
|
||||
|
||||
CHudTexture *iconPostKillerName;
|
||||
wchar_t wzPreKillerText[32];
|
||||
|
||||
CHudTexture *iconPostVictimName;
|
||||
|
||||
bool bSelfInflicted;
|
||||
bool bLocalPlayerInvolved;
|
||||
bool bCrit;
|
||||
float flCreationTime;
|
||||
int iWeaponID;
|
||||
int iKillerID;
|
||||
int iVictimID;
|
||||
int iCount;
|
||||
|
||||
bool bSpecialScore;
|
||||
};
|
||||
|
||||
#define NUM_CORNER_COORD 10
|
||||
#define NUM_BACKGROUND_COORD NUM_CORNER_COORD*4
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
class CHudBaseDeathNotice : public CHudElement, public vgui::Panel
|
||||
{
|
||||
DECLARE_CLASS_SIMPLE( CHudBaseDeathNotice, vgui::Panel );
|
||||
public:
|
||||
CHudBaseDeathNotice( const char *pElementName );
|
||||
|
||||
void VidInit( void );
|
||||
virtual void Init( void );
|
||||
virtual bool ShouldDraw( void );
|
||||
virtual void Paint( void );
|
||||
virtual void ApplySchemeSettings( vgui::IScheme *scheme );
|
||||
|
||||
void RetireExpiredDeathNotices( void );
|
||||
|
||||
virtual void FireGameEvent( IGameEvent *event );
|
||||
virtual bool ShouldShowDeathNotice( IGameEvent *event ){ return true; }
|
||||
|
||||
protected:
|
||||
virtual Color GetTeamColor( int iTeamNumber, bool bLocalPlayerInvolved = false );
|
||||
virtual void OnGameEvent( IGameEvent *event, int iDeathNoticeMsg ) {};
|
||||
void DrawText( int x, int y, vgui::HFont hFont, Color clr, const wchar_t *szText );
|
||||
int AddDeathNoticeItem();
|
||||
void GetBackgroundPolygonVerts( int x0, int y0, int x1, int y1, int iVerts, vgui::Vertex_t vert[] );
|
||||
void CalcRoundedCorners();
|
||||
|
||||
enum EDeathNoticeIconFormat
|
||||
{
|
||||
kDeathNoticeIcon_Standard,
|
||||
kDeathNoticeIcon_Inverted, // used for display on lighter background when kill involved the local player
|
||||
};
|
||||
|
||||
CHudTexture *GetIcon( const char *szIcon, EDeathNoticeIconFormat eIconFormat );
|
||||
|
||||
virtual bool EventIsPlayerDeath( const char *eventName );
|
||||
|
||||
virtual int UseExistingNotice( IGameEvent *event );
|
||||
|
||||
void GetLocalizedControlPointName( IGameEvent *event, char *namebuf, int namelen );
|
||||
virtual Color GetInfoTextColor( int iDeathNoticeMsg ){ return Color( 255, 255, 255, 255 ); }
|
||||
virtual Color GetBackgroundColor ( int iDeathNoticeMsg ) { return m_DeathNotices[iDeathNoticeMsg].bLocalPlayerInvolved ? m_clrLocalBGColor : m_clrBaseBGColor; }
|
||||
|
||||
CPanelAnimationVarAliasType( float, m_flLineHeight, "LineHeight", "16", "proportional_float" );
|
||||
CPanelAnimationVarAliasType( float, m_flLineSpacing, "LineSpacing", "4", "proportional_float" );
|
||||
CPanelAnimationVarAliasType( float, m_flCornerRadius, "CornerRadius", "3", "proportional_float" );
|
||||
CPanelAnimationVar( float, m_flMaxDeathNotices, "MaxDeathNotices", "4" );
|
||||
CPanelAnimationVar( bool, m_bRightJustify, "RightJustify", "1" );
|
||||
CPanelAnimationVar( vgui::HFont, m_hTextFont, "TextFont", "Default" );
|
||||
CPanelAnimationVar( Color, m_clrIcon, "IconColor", "255 80 0 255" );
|
||||
CPanelAnimationVar( Color, m_clrBaseBGColor, "BaseBackgroundColor", "46 43 42 220" );
|
||||
CPanelAnimationVar( Color, m_clrLocalBGColor, "LocalBackgroundColor", "245 229 196 200" );
|
||||
CPanelAnimationVar( Color, m_clrKillStreakBg, "KillStreakBackgroundColor", "224 223 219 200" );
|
||||
|
||||
CUtlVector<DeathNoticeItem> m_DeathNotices;
|
||||
|
||||
Vector2D m_CornerCoord[NUM_CORNER_COORD];
|
||||
};
|
||||
|
||||
#endif // HUD_BASEDEATHNOTICE_H
|
||||
@@ -0,0 +1,85 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
// c_boss_alpha.cpp
|
||||
|
||||
#include "cbase.h"
|
||||
#include "NextBot/C_NextBot.h"
|
||||
#include "c_boss_alpha.h"
|
||||
|
||||
// memdbgon must be the last include file in a .cpp file!!!
|
||||
#include "tier0/memdbgon.h"
|
||||
|
||||
#undef NextBot
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
IMPLEMENT_CLIENTCLASS_DT( C_BossAlpha, DT_BossAlpha, CBossAlpha )
|
||||
|
||||
RecvPropBool( RECVINFO( m_isNuking ) ),
|
||||
|
||||
END_RECV_TABLE()
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
C_BossAlpha::C_BossAlpha()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
C_BossAlpha::~C_BossAlpha()
|
||||
{
|
||||
if ( m_nukeEffect )
|
||||
{
|
||||
ParticleProp()->StopEmissionAndDestroyImmediately( m_nukeEffect );
|
||||
m_nukeEffect = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
void C_BossAlpha::Spawn( void )
|
||||
{
|
||||
BaseClass::Spawn();
|
||||
|
||||
m_vecViewOffset = Vector( 0, 0, 180.0f );
|
||||
|
||||
SetNextClientThink( CLIENT_THINK_ALWAYS );
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
void C_BossAlpha::ClientThink( void )
|
||||
{
|
||||
if ( m_isNuking )
|
||||
{
|
||||
if ( !m_nukeEffect )
|
||||
{
|
||||
m_nukeEffect = ParticleProp()->Create( "charge_up", PATTACH_POINT_FOLLOW, LookupAttachment( "head" ) );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( m_nukeEffect )
|
||||
{
|
||||
ParticleProp()->StopEmissionAndDestroyImmediately( m_nukeEffect );
|
||||
m_nukeEffect = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Return the origin for player observers tracking this target
|
||||
Vector C_BossAlpha::GetObserverCamOrigin( void )
|
||||
{
|
||||
return EyePosition();
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
void C_BossAlpha::FireEvent( const Vector& origin, const QAngle& angles, int event, const char *options )
|
||||
{
|
||||
if ( event == 7001 )
|
||||
{
|
||||
EmitSound( "RobotBoss.Footstep" );
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
#ifndef C_BOSS_ALPHA_H
|
||||
#define C_BOSS_ALPHA_H
|
||||
|
||||
#include "c_ai_basenpc.h"
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------------
|
||||
/**
|
||||
* The client-side implementation of Boss Alpha
|
||||
*/
|
||||
class C_BossAlpha : public C_NextBotCombatCharacter
|
||||
{
|
||||
public:
|
||||
DECLARE_CLASS( C_BossAlpha, C_NextBotCombatCharacter );
|
||||
DECLARE_CLIENTCLASS();
|
||||
|
||||
C_BossAlpha();
|
||||
virtual ~C_BossAlpha();
|
||||
|
||||
public:
|
||||
virtual void Spawn( void );
|
||||
virtual bool IsNextBot() { return true; }
|
||||
|
||||
virtual Vector GetObserverCamOrigin( void ); // Return the origin for player observers tracking this target
|
||||
|
||||
virtual void FireEvent( const Vector& origin, const QAngle& angles, int event, const char *options );
|
||||
|
||||
virtual void ClientThink();
|
||||
|
||||
private:
|
||||
C_BossAlpha( const C_BossAlpha & ); // not defined, not accessible
|
||||
|
||||
CNetworkVar( bool, m_isNuking );
|
||||
HPARTICLEFFECT m_nukeEffect;
|
||||
};
|
||||
|
||||
|
||||
#endif // C_BOSS_ALPHA_H
|
||||
@@ -0,0 +1,25 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
#include "cbase.h"
|
||||
|
||||
#include "c_tf_tank_boss.h"
|
||||
#include "tf_hud_boss_health.h"
|
||||
#include "tf_gamerules.h"
|
||||
|
||||
|
||||
IMPLEMENT_CLIENTCLASS_DT(C_TFBaseBoss, DT_TFBaseBoss, CTFBaseBoss)
|
||||
RecvPropFloat( RECVINFO( m_lastHealthPercentage ) ),
|
||||
END_RECV_TABLE()
|
||||
|
||||
|
||||
LINK_ENTITY_TO_CLASS( base_boss, C_TFBaseBoss );
|
||||
|
||||
ShadowType_t C_TFBaseBoss::ShadowCastType( void )
|
||||
{
|
||||
if ( !IsVisible() )
|
||||
return SHADOWS_NONE;
|
||||
|
||||
if ( IsEffectActive(EF_NODRAW | EF_NOSHADOW) )
|
||||
return SHADOWS_NONE;
|
||||
|
||||
return SHADOWS_RENDER_TO_TEXTURE_DYNAMIC;
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
#ifndef C_TF_BASE_BOSS_H
|
||||
#define C_TF_BASE_BOSS_H
|
||||
|
||||
#include "NextBot/C_NextBot.h"
|
||||
#include "c_tf_mvm_boss_progress_user.h"
|
||||
|
||||
class C_TFBaseBoss : public C_NextBotCombatCharacter, public C_TFMvMBossProgressUser
|
||||
{
|
||||
public:
|
||||
DECLARE_CLASS( C_TFBaseBoss, C_NextBotCombatCharacter );
|
||||
DECLARE_CLIENTCLASS();
|
||||
|
||||
virtual ~C_TFBaseBoss() {}
|
||||
|
||||
ShadowType_t ShadowCastType( void );
|
||||
|
||||
// ITFMvMBossProgressUser
|
||||
virtual float GetBossStatusProgress() const OVERRIDE { return m_lastHealthPercentage; }
|
||||
|
||||
private:
|
||||
|
||||
float m_lastHealthPercentage;
|
||||
};
|
||||
|
||||
#endif // C_TF_BASE_BOSS_H
|
||||
@@ -0,0 +1,24 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
#include "cbase.h"
|
||||
|
||||
#include "c_tf_tank_boss.h"
|
||||
|
||||
#include "teamplayroundbased_gamerules.h"
|
||||
|
||||
|
||||
IMPLEMENT_CLIENTCLASS_DT(C_TFTankBoss, DT_TFTankBoss, CTFTankBoss)
|
||||
//RecvPropVector(RECVINFO(m_shadowDirection)),
|
||||
END_RECV_TABLE()
|
||||
|
||||
LINK_ENTITY_TO_CLASS( tank_boss, C_TFTankBoss );
|
||||
|
||||
|
||||
C_TFTankBoss::C_TFTankBoss()
|
||||
{
|
||||
}
|
||||
|
||||
void C_TFTankBoss::GetGlowEffectColor( float *r, float *g, float *b )
|
||||
{
|
||||
TeamplayRoundBasedRules()->GetTeamGlowColor( GetTeamNumber(), *r, *g, *b );
|
||||
}
|
||||
|
||||
@@ -0,0 +1,22 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
#ifndef C_TF_TANK_BOSS_H
|
||||
#define C_TF_TANK_BOSS_H
|
||||
|
||||
#include "c_tf_base_boss.h"
|
||||
#include "NextBot/C_NextBot.h"
|
||||
|
||||
class C_TFTankBoss : public C_TFBaseBoss
|
||||
{
|
||||
public:
|
||||
DECLARE_CLASS( C_TFTankBoss, C_TFBaseBoss );
|
||||
DECLARE_CLIENTCLASS();
|
||||
|
||||
C_TFTankBoss();
|
||||
|
||||
virtual void GetGlowEffectColor( float *r, float *g, float *b );
|
||||
|
||||
// ITFMvMBossProgressUser
|
||||
virtual const char* GetBossProgressImageName() const OVERRIDE { return "tank"; }
|
||||
};
|
||||
|
||||
#endif // C_TF_TANK_BOSS_H
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,267 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose: Load item upgrade data from KeyValues
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================
|
||||
|
||||
#ifndef C_TF_UPGRADES_H
|
||||
#define C_TF_UPGRADES_H
|
||||
|
||||
|
||||
#include "c_baseentity.h"
|
||||
#include "networkvar.h"
|
||||
#include "econ_item_constants.h"
|
||||
#include "tf_shareddefs.h"
|
||||
#include "c_tf_player.h"
|
||||
#include "hudelement.h"
|
||||
#include "vgui_controls/EditablePanel.h"
|
||||
#include "tf_controls.h"
|
||||
|
||||
#define MAX_ITEM_SLOT_BUY_PANELS 6
|
||||
|
||||
class CItemModelPanel;
|
||||
class CImageButton;
|
||||
|
||||
namespace vgui
|
||||
{
|
||||
class ImagePanel;
|
||||
class Button;
|
||||
}
|
||||
|
||||
enum costlabel_chache_t
|
||||
{
|
||||
CLCACHE_DIRTY,
|
||||
CLCACHE_NOT_AFFORDABLE_1,
|
||||
CLCACHE_NOT_AFFORDABLE_2,
|
||||
CLCACHE_NOT_AFFORDABLE_3,
|
||||
CLCACHE_NOT_AFFORDABLE_4,
|
||||
CLCACHE_NOT_AFFORDABLE_5,
|
||||
CLCACHE_NOT_AFFORDABLE_6,
|
||||
CLCACHE_NOT_AFFORDABLE_7,
|
||||
CLCACHE_NOT_AFFORDABLE_8,
|
||||
CLCACHE_NOT_AFFORDABLE_9,
|
||||
CLCACHE_AFFORDABLE,
|
||||
};
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: HUD Element that provides the interface to the upgrade options
|
||||
//-----------------------------------------------------------------------------
|
||||
class CUpgradeBuyPanel : public vgui::EditablePanel
|
||||
{
|
||||
DECLARE_CLASS_SIMPLE( CUpgradeBuyPanel, vgui::EditablePanel );
|
||||
|
||||
public:
|
||||
|
||||
enum ColorSet
|
||||
{
|
||||
COLOR_SET_DEFAULT,
|
||||
COLOR_SET_OWNED,
|
||||
COLOR_SET_PURCHASED,
|
||||
COLOR_SET_DISABLED,
|
||||
};
|
||||
|
||||
public:
|
||||
CUpgradeBuyPanel( Panel *parent, const char *panelName );
|
||||
virtual ~CUpgradeBuyPanel();
|
||||
|
||||
virtual void ApplySchemeSettings( vgui::IScheme *pScheme );
|
||||
virtual void ApplySettings( KeyValues *inResourceData );
|
||||
virtual void PerformLayout( void );
|
||||
virtual void OnCommand( const char *command );
|
||||
|
||||
bool ValidateUpgradeStepData( void );
|
||||
|
||||
void SetNumLevelImages( int nValues );
|
||||
void SetSkillTreeButtonColors( int nButton, ColorSet nColorSet );
|
||||
void SetInspectMode( bool bValue ) { m_bInspectMode = bValue; }
|
||||
void SetPlayer( C_TFPlayer *pPlayer ) { m_hPlayer = pPlayer; }
|
||||
|
||||
void UpdateImages( int nCurrentMoney );
|
||||
|
||||
public:
|
||||
|
||||
KeyValues *m_pSkillTreeButtonKVs;
|
||||
|
||||
vgui::ImagePanel *m_pIcon;
|
||||
vgui::Label *m_pPriceLabel;
|
||||
vgui::Label *m_pShortDescriptionLabel;
|
||||
CImageButton *m_pIncrementButton;
|
||||
CImageButton *m_pDecrementButton;
|
||||
CUtlVector< vgui::ImagePanel* > m_SkillTreeImages;
|
||||
|
||||
int m_nWeaponSlot;
|
||||
int m_nUpgradeIndex;
|
||||
int m_nPrice;
|
||||
|
||||
int m_nGridPositionX;
|
||||
int m_nGridPositionY;
|
||||
|
||||
int m_nCurrentStep;
|
||||
int m_nPurchases;
|
||||
|
||||
bool m_bOverCap;
|
||||
char m_szAttribName[MAX_ATTRIBUTE_DESCRIPTION_LENGTH];
|
||||
|
||||
bool m_bInspectMode;
|
||||
|
||||
CPanelAnimationVarAliasType( int, m_iUpgradeButtonXPos, "upgradebutton_xpos", "0", "proportional_int" );
|
||||
CPanelAnimationVarAliasType( int, m_iUpgradeButtonYPos, "upgradebutton_ypos", "0", "proportional_int" );
|
||||
|
||||
static Color m_rgbaDefaultFG;
|
||||
static Color m_rgbaDefaultBG;
|
||||
static Color m_rgbaArmedFG;
|
||||
static Color m_rgbaArmedBG;
|
||||
static Color m_rgbaDepressedFG;
|
||||
static Color m_rgbaDepressedBG;
|
||||
static Color m_rgbaSelectedFG;
|
||||
static Color m_rgbaSelectedBG;
|
||||
static Color m_rgbaDisabledFG;
|
||||
static Color m_rgbaDisabledBG;
|
||||
|
||||
private:
|
||||
CHandle< C_TFPlayer > m_hPlayer;
|
||||
};
|
||||
|
||||
|
||||
struct ItemSlotBuyPanels
|
||||
{
|
||||
static const int CHARACTER_UPGRADE = -1;
|
||||
static const int INVALID_SLOT = -2;
|
||||
|
||||
typedef CUpgradeBuyPanel *UPGRADEPTR;
|
||||
class CUpgradeBuyPanelLess
|
||||
{
|
||||
public:
|
||||
bool Less( const UPGRADEPTR &src1, const UPGRADEPTR &src2, void *pCtx )
|
||||
{
|
||||
if ( src1->m_nPrice > src2->m_nPrice )
|
||||
return true;
|
||||
|
||||
if ( src1->m_nPrice == src2->m_nPrice && src1->m_nUpgradeIndex < src2->m_nUpgradeIndex )
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
ItemSlotBuyPanels()
|
||||
{
|
||||
nSlot = INVALID_SLOT;
|
||||
m_iItemID = INVALID_ITEM_ID;
|
||||
}
|
||||
|
||||
void SetItemID( int iIndex ) { m_iItemID = iIndex; }
|
||||
itemid_t GetItemID( void ) { return m_iItemID; }
|
||||
|
||||
int nSlot;
|
||||
CUtlSortVector< CUpgradeBuyPanel*, CUpgradeBuyPanelLess > upgradeBuyPanels;
|
||||
itemid_t m_iItemID;
|
||||
};
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: HUD Element that provides the interface to the upgrade options
|
||||
//-----------------------------------------------------------------------------
|
||||
class CHudUpgradePanel : public CHudElement, public vgui::EditablePanel
|
||||
{
|
||||
DECLARE_CLASS_SIMPLE( CHudUpgradePanel, vgui::EditablePanel );
|
||||
|
||||
public:
|
||||
CHudUpgradePanel( const char *pElementName );
|
||||
virtual ~CHudUpgradePanel();
|
||||
|
||||
virtual void ApplySchemeSettings( vgui::IScheme *scheme );
|
||||
virtual void ApplySettings( KeyValues *inResourceData );
|
||||
virtual void PerformLayout( void );
|
||||
virtual bool ShouldDraw( void );
|
||||
virtual void SetVisible( bool bVisible );
|
||||
virtual void SetActive( bool bActive );
|
||||
virtual int GetRenderGroupPriority( void ) { return 35; } // less than statpanel
|
||||
virtual void OnCommand( const char *command );
|
||||
virtual void OnTick( void );
|
||||
virtual void FireGameEvent( IGameEvent *event );
|
||||
void InspectUpgradesForPlayer( C_TFPlayer *pPlayer ) { m_hPlayer = pPlayer; m_bInspectMode = true; m_bShowUpgradeMenu = true; }
|
||||
C_TFPlayer *GetPlayer( void ) { return m_hPlayer; }
|
||||
void PlayerInventoryChanged( C_TFPlayer *pPlayer );
|
||||
|
||||
MESSAGE_FUNC_PTR( OnItemPanelEntered, "ItemPanelEntered", panel );
|
||||
MESSAGE_FUNC_PTR( OnItemPanelExited, "ItemPanelExited", panel );
|
||||
MESSAGE_FUNC_PTR( OnItemPanelMousePressed, "ItemPanelMousePressed", panel );
|
||||
|
||||
virtual GameActionSet_t GetPreferredActionSet() { return GAME_ACTION_SET_MENUCONTROLS; }
|
||||
|
||||
protected:
|
||||
void CreateItemModelPanel( int iLoadoutSlot );
|
||||
void UpdateModelPanels( void );
|
||||
virtual void SetBorderForItem( CItemModelPanel *pItemPanel, bool bMouseOver );
|
||||
void UpgradeItemInSlot( int iSlot );
|
||||
void UpdateUpgradeButtons( void );
|
||||
void UpdateButtonStates( int nCurrentCurrency, int nUpgrade = 0, int nNumPurchased = 0 );
|
||||
void UpdateJoystickControls( void );
|
||||
void UpdateHighlights( void );
|
||||
void UpdateMouseOverHighlight( void );
|
||||
|
||||
void UpdateItemStatsLabel( void );
|
||||
void CancelUpgrades( void );
|
||||
void AddItemStatText( const locchar_t *loc_AttrDescText, attrib_colors_t eColor, wchar_t *out_wszAttribDesc, int iAttribDescSize );
|
||||
CEconItemView* GetLocalPlayerBottleFromInventory( void );
|
||||
bool QuickEquipBottle( void );
|
||||
|
||||
protected:
|
||||
vgui::EditablePanel *m_pTipPanel;
|
||||
vgui::EditablePanel *m_pSelectWeaponPanel;
|
||||
CExLabel *m_pUpgradeItemStatsLabel;
|
||||
|
||||
vgui::Panel *m_pPlayerUpgradeButton;
|
||||
vgui::Panel *m_pActiveTabPanel;
|
||||
vgui::Panel *m_pMouseOverTabPanel;
|
||||
vgui::Panel *m_pMouseOverUpgradePanel;
|
||||
CUpgradeBuyPanel *m_pActiveUpgradeBuyPanel;
|
||||
vgui::Panel *m_pPlayerRespecButton;
|
||||
|
||||
CUtlVector< CItemModelPanel* > m_pItemPanels;
|
||||
KeyValues *m_pItemModelPanelKVs;
|
||||
int m_iVisibleItemPanels;
|
||||
|
||||
int m_iWeaponSlotBeingUpgraded;
|
||||
bool m_bShowUpgradeMenu;
|
||||
bool m_bCancelUpgrades;
|
||||
bool m_bOpenLoadout;
|
||||
bool m_bWasInZone;
|
||||
bool m_bHighlightedTab;
|
||||
bool m_bInspectMode;
|
||||
|
||||
int m_nCurrency;
|
||||
int m_nUpgradeActivity;
|
||||
|
||||
bool m_bAwardMaxSlotAchievement;
|
||||
bool m_bAwardMaxResistAchievement;
|
||||
|
||||
ItemSlotBuyPanels m_ItemSlotBuyPanels[ MAX_ITEM_SLOT_BUY_PANELS ];
|
||||
|
||||
CPanelAnimationVarAliasType( int, m_iItemPanelXPos, "itempanel_xpos", "0", "proportional_int" );
|
||||
CPanelAnimationVarAliasType( int, m_iItemPanelYPos, "itempanel_ypos", "0", "proportional_int" );
|
||||
CPanelAnimationVarAliasType( int, m_iItemPanelXDelta, "itempanel_xdelta", "0", "proportional_int" );
|
||||
CPanelAnimationVarAliasType( int, m_iItemPanelYDelta, "itempanel_ydelta", "0", "proportional_int" );
|
||||
|
||||
CPanelAnimationVarAliasType( int, m_iUpgradeBuyPanelXPos, "upgradebuypanel_xpos", "0", "proportional_int" );
|
||||
CPanelAnimationVarAliasType( int, m_iUpgradeBuyPanelYPos, "upgradebuypanel_ypos", "0", "proportional_int" );
|
||||
CPanelAnimationVarAliasType( int, m_iUpgradeBuyPanelDelta, "upgradebuypanel_delta", "0", "proportional_int" );
|
||||
|
||||
bool m_bNavUpDownPressed;
|
||||
bool m_bNavLeftRightPressed;
|
||||
bool m_bNavButtonPressed;
|
||||
bool m_bUsingController;
|
||||
|
||||
private:
|
||||
void UpdateTip();
|
||||
CHandle< C_TFPlayer > m_hPlayer;
|
||||
};
|
||||
|
||||
|
||||
extern bool MannVsMachine_GetUpgradeInfo( int iAttribute, int iQuality, float &flValue );
|
||||
|
||||
|
||||
#endif // C_TF_UPGRADES_H
|
||||
@@ -0,0 +1,87 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
//=============================================================================
|
||||
#include "cbase.h"
|
||||
#include "proxyentity.h"
|
||||
#include "materialsystem/imaterial.h"
|
||||
#include "materialsystem/imaterialvar.h"
|
||||
#include "c_team.h"
|
||||
#include "tf_shareddefs.h"
|
||||
|
||||
// memdbgon must be the last include file in a .cpp file!!!
|
||||
#include "tier0/memdbgon.h"
|
||||
|
||||
//=============================================================================
|
||||
//
|
||||
// Team Material Proxy
|
||||
//
|
||||
// Handles changing team color (skins).
|
||||
//
|
||||
class CTeamMaterialProxy : public CEntityMaterialProxy
|
||||
{
|
||||
public:
|
||||
|
||||
CTeamMaterialProxy();
|
||||
virtual ~CTeamMaterialProxy();
|
||||
virtual bool Init( IMaterial *pMaterial, KeyValues* pKeyValues );
|
||||
virtual void OnBind( C_BaseEntity *pEnt );
|
||||
virtual IMaterial *GetMaterial();
|
||||
|
||||
private:
|
||||
|
||||
IMaterialVar* m_FrameVar;
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Constructor.
|
||||
//-----------------------------------------------------------------------------
|
||||
CTeamMaterialProxy::CTeamMaterialProxy()
|
||||
{
|
||||
m_FrameVar = 0;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Destructor.
|
||||
//-----------------------------------------------------------------------------
|
||||
CTeamMaterialProxy::~CTeamMaterialProxy()
|
||||
{
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Initialization.
|
||||
//-----------------------------------------------------------------------------
|
||||
bool CTeamMaterialProxy::Init( IMaterial *pMaterial, KeyValues* pKeyValues )
|
||||
{
|
||||
bool foundVar;
|
||||
m_FrameVar = pMaterial->FindVar( "$frame", &foundVar, false );
|
||||
if( !foundVar )
|
||||
{
|
||||
m_FrameVar = 0;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Set the appropriate texture (in the animated texture).
|
||||
//-----------------------------------------------------------------------------
|
||||
void CTeamMaterialProxy::OnBind( C_BaseEntity *pEnt )
|
||||
{
|
||||
if( !m_FrameVar )
|
||||
return;
|
||||
|
||||
int team = pEnt->GetRenderTeamNumber();
|
||||
team -= 2;
|
||||
|
||||
// Use that as an animated frame number
|
||||
m_FrameVar->SetIntValue( team );
|
||||
}
|
||||
|
||||
IMaterial *CTeamMaterialProxy::GetMaterial()
|
||||
{
|
||||
if ( !m_FrameVar )
|
||||
return NULL;
|
||||
|
||||
return m_FrameVar->GetOwningMaterial();
|
||||
}
|
||||
|
||||
EXPOSE_INTERFACE( CTeamMaterialProxy, IMaterialProxy, "TeamTexture" IMATERIAL_PROXY_INTERFACE_VERSION );
|
||||
@@ -0,0 +1,116 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose: Generic in-game abuse reporting
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================//
|
||||
|
||||
#include "cbase.h"
|
||||
#include "tf_abuse_report.h"
|
||||
#include "abuse_report_ui.h"
|
||||
#include "game/client/iviewport.h"
|
||||
#include "tf_shareddefs.h"
|
||||
#include "tf_hud_mainmenuoverride.h"
|
||||
#include "tf_gcmessages.h"
|
||||
#include "c_tf_player.h"
|
||||
#include "tf_quickplay_shared.h"
|
||||
#include "tf_gc_client.h"
|
||||
|
||||
// memdbgon must be the last include file in a .cpp file!!!
|
||||
#include "tier0/memdbgon.h"
|
||||
|
||||
|
||||
/// Declare singleton object
|
||||
CTFAbuseReportManager theAbuseReportManager;
|
||||
|
||||
CTFAbuseReportManager::CTFAbuseReportManager() {}
|
||||
CTFAbuseReportManager::~CTFAbuseReportManager() {}
|
||||
|
||||
bool CTFAbuseReportManager::CreateAndPopulateIncident()
|
||||
{
|
||||
if ( !CAbuseReportManager::CreateAndPopulateIncident() )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if ( m_bTestReport )
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
for ( int iPlayer = 0 ; iPlayer < m_pIncidentData->m_vecPlayers.Count() ; ++iPlayer )
|
||||
{
|
||||
|
||||
AbuseIncidentData_t::PlayerData_t *p = &m_pIncidentData->m_vecPlayers[iPlayer];
|
||||
|
||||
CPlayerInventory *pInv = InventoryManager()->GetInventoryForAccount( p->m_steamID.GetAccountID() );
|
||||
//C_TFPlayer *pTFPlayer = dynamic_cast<C_TFPlayer *> ( UTIL_PlayerByIndex( p->m_iClientIndex ) );
|
||||
//if ( pTFPlayer == NULL )
|
||||
//{
|
||||
// Assert( !p->m_bHasEntity );
|
||||
// continue;
|
||||
//}
|
||||
//CTFPlayerInventory *pInv = pTFPlayer->Inventory();
|
||||
if ( pInv == NULL )
|
||||
{
|
||||
Warning( "No inventory data for player '%s'; we won't be able to report this person for inappropriate custom images\n", p->m_sPersona.String() );
|
||||
continue;
|
||||
}
|
||||
|
||||
for ( int i = 0 ; i < pInv->GetItemCount() ; ++i)
|
||||
{
|
||||
CEconItemView *pItem = pInv->GetItem( i );
|
||||
|
||||
// Get custom texture ID, if any
|
||||
uint64 hCustomtextureID = pItem->GetCustomUserTextureID();
|
||||
|
||||
// Most items won't have a custom texture
|
||||
if ( hCustomtextureID == 0 )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
// Discard duplicates, as it makes the UI confusing
|
||||
bool bDup = false;
|
||||
for ( int j = 0 ; j < p->m_vecImages.Count() ; ++j )
|
||||
{
|
||||
if ( p->m_vecImages[ j ].m_hUGCHandle == hCustomtextureID )
|
||||
{
|
||||
bDup = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if ( bDup )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
AbuseIncidentData_t::PlayerImage_t img;
|
||||
img.m_eType = AbuseIncidentData_t::k_PlayerImageType_UGC;
|
||||
img.m_hUGCHandle = hCustomtextureID;
|
||||
p->m_vecImages.AddToTail( img );
|
||||
}
|
||||
}
|
||||
|
||||
// Check if we can report abuse against the game server.
|
||||
if (m_pIncidentData->m_adrGameServer.IsValid() &&
|
||||
!GTFGCClientSystem()->BIsIPRecentMatchServer( m_pIncidentData->m_adrGameServer ) )
|
||||
{
|
||||
m_pIncidentData->m_bCanReportGameServer = true;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void CTFAbuseReportManager::ActivateSubmitReportUI()
|
||||
{
|
||||
Assert( g_AbuseReportDlg.Get() == NULL );
|
||||
Assert( m_pIncidentData != NULL );
|
||||
|
||||
IViewPortPanel *pMMOverride = ( gViewPortInterface->FindPanelByName( PANEL_MAINMENUOVERRIDE ) );
|
||||
engine->ExecuteClientCmd("gameui_activate");
|
||||
vgui::SETUP_PANEL( new CAbuseReportDlg( (CHudMainMenuOverride*)pMMOverride, m_pIncidentData ) );
|
||||
Assert( g_AbuseReportDlg.Get() != NULL );
|
||||
g_AbuseReportDlg->MakeModal();
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user