1
0
mirror of https://github.com/alliedmodders/hl2sdk.git synced 2026-10-10 03:43:06 +08:00

Merge branch 'tf2' into css

This commit is contained in:
Nicholas Hastings
2026-09-19 13:34:35 -04:00
247 changed files with 15847 additions and 1944 deletions
+70
View File
@@ -0,0 +1,70 @@
name: Compilation
on:
push:
pull_request:
jobs:
build:
strategy:
matrix:
include:
- os: ubuntu-22.04
cc: clang-22
cxx: clang++-22
container_image: ghcr.io/alliedmodders/build-containers/debian11-clang22:latest
- os: windows-2022
cc: msvc
fail-fast: false
name: ${{ matrix.os }} - ${{ matrix.cc }}
runs-on: ${{ matrix.os }}
container:
image: ${{ matrix.container_image }}
steps:
- uses: actions/checkout@v7
name: Repository checkout
with:
fetch-depth: 0
submodules: recursive
path: repository
- uses: actions/checkout@v7
name: AMBuild checkout
if: startsWith(runner.os, 'Windows')
with:
repository: alliedmodders/ambuild
ref: fe8c99ccd24fa926bf6ac6b9935a5fc03df06a72
fetch-depth: 0
submodules: recursive
path: ambuild
- name: Setup AMBuild
if: startsWith(runner.os, 'Windows')
shell: bash
run: |
python3 -m pip install ./ambuild
- name: Select clang compiler
if: startsWith(runner.os, 'Linux')
run: |
echo "CC=${{ matrix.cc }}" >> $GITHUB_ENV
echo "CXX=${{ matrix.cxx }}" >> $GITHUB_ENV
${{ matrix.cc }} --version
${{ matrix.cxx }} --version
- name: Build
shell: bash
working-directory: repository
run: |
mkdir build
cd build
python3 ../configure.py
ambuild
- name: Upload artifact
uses: actions/upload-artifact@v4
with:
name: libs_${{ runner.os }}
path: repository/build/lib
+2
View File
@@ -93,6 +93,8 @@ class SDKConfig(object):
'-Wno-tautological-overlap-compare',
'-Wno-tautological-constant-out-of-range-compare',
'-Wno-undefined-bool-conversion',
'-Wno-nontrivial-memcall',
'-Wno-sync-alignment',
'-msse',
'-fPIC'
]
@@ -43,7 +43,7 @@ void CBlacklistedServerManager::Reset( void )
//-----------------------------------------------------------------------------
int CBlacklistedServerManager::LoadServersFromFile( const char *pszFilename, bool bResetTimes )
{
KeyValues *pKV = new KeyValues( "serverblacklist" );
KeyValuesAD pKV( "serverblacklist" );
if ( !pKV->LoadFromFile( g_pFullFileSystem, pszFilename, "MOD" ) )
return 0;
@@ -75,8 +75,6 @@ int CBlacklistedServerManager::LoadServersFromFile( const char *pszFilename, boo
}
}
pKV->deleteThis();
return count;
}
Binary file not shown.
Binary file not shown.
Binary file not shown.
+2 -1
View File
@@ -457,6 +457,7 @@ BEGIN_RECV_TABLE_NOBASE(C_BaseEntity, DT_BaseEntity)
RecvPropInt(RECVINFO(m_clrRender)),
RecvPropInt(RECVINFO(m_iTeamNum)),
RecvPropInt(RECVINFO(m_CollisionGroup)),
RecvPropFloat(RECVINFO(m_flGravity)),
RecvPropFloat(RECVINFO(m_flElasticity)),
RecvPropFloat(RECVINFO(m_flShadowCastDistance)),
RecvPropEHandle( RECVINFO(m_hOwnerEntity) ),
@@ -539,7 +540,7 @@ BEGIN_PREDICTION_DATA_NO_BASE( C_BaseEntity )
// DEFINE_FIELD( m_flLastMessageTime, FIELD_FLOAT ),
DEFINE_FIELD( m_vecBaseVelocity, FIELD_VECTOR ),
DEFINE_FIELD( m_iEFlags, FIELD_INTEGER ),
DEFINE_FIELD( m_flGravity, FIELD_FLOAT ),
DEFINE_PRED_FIELD( m_flGravity, FIELD_FLOAT, FTYPEDESC_INSENDTABLE | FTYPEDESC_NOERRORCHECK ),
// DEFINE_FIELD( m_ModelInstance, FIELD_SHORT ),
DEFINE_FIELD( m_flProxyRandomValue, FIELD_FLOAT ),
+3
View File
@@ -418,6 +418,9 @@ LINK_ENTITY_TO_CLASS( player, C_BasePlayer );
C_BasePlayer::C_BasePlayer() : m_iv_vecViewOffset( "C_BasePlayer::m_iv_vecViewOffset" )
{
AddVar( &m_vecViewOffset, &m_iv_vecViewOffset, LATCH_SIMULATION_VAR );
AddVar( &m_Local.m_vecPunchAngle, &m_Local.m_iv_vecPunchAngle, LATCH_SIMULATION_VAR );
AddVar( &m_Local.m_vecPunchAngleVel, &m_Local.m_iv_vecPunchAngleVel, LATCH_SIMULATION_VAR );
#ifdef _DEBUG
m_vecLadderNormal.Init();
+18 -1
View File
@@ -19,6 +19,7 @@
#include <KeyValues.h>
#include "hltvcamera.h"
#ifdef TF_CLIENT_DLL
#include "c_tf_player.h"
#include "tf_weaponbase.h"
#endif
@@ -91,6 +92,22 @@ void FormatViewModelAttachment( Vector &vOrigin, bool bInverse )
vOrigin = pViewSetup->origin + vOut;
}
#ifdef TF_CLIENT_DLL
bool TeamFortress_ShouldFlipClientViewModel( void )
{
if ( IsLocalPlayerSpectator() )
{
// Use spectated client's handedness preference
C_TFPlayer *pSpecTarget = ToTFPlayer( UTIL_PlayerByIndex( GetSpectatorTarget() ) );
if ( pSpecTarget )
{
return pSpecTarget->m_bFlipViewModels;
}
}
return cl_flipviewmodels.GetBool();
}
#endif //TF_CLIENT_DLL
void C_BaseViewModel::FormatViewModelAttachment( int nAttachment, matrix3x4_t &attachmentToWorld )
{
@@ -211,7 +228,7 @@ bool C_BaseViewModel::ShouldFlipViewModel()
CBaseCombatWeapon *pWeapon = m_hWeapon.Get();
if ( pWeapon )
{
return pWeapon->m_bFlipViewModel != cl_flipviewmodels.GetBool();
return pWeapon->m_bFlipViewModel != TeamFortress_ShouldFlipClientViewModel();
}
#endif
+4
View File
@@ -16,4 +16,8 @@
#include "utlvector.h"
#include "baseviewmodel_shared.h"
#ifdef TF_CLIENT_DLL
bool TeamFortress_ShouldFlipClientViewModel( void );
#endif //TF_CLIENT_DLL
#endif // C_BASEVIEWMODEL_H
+2 -2
View File
@@ -441,10 +441,10 @@ void CHudCommentary::Paint()
// Draw the speaker names
// Get our scheme and font information
vgui::HScheme scheme = vgui::scheme()->GetScheme( "ClientScheme" );
vgui::HFont hFont = vgui::scheme()->GetIScheme(scheme)->GetFont( "CommentaryDefault" );
vgui::HFont hFont = vgui::scheme()->GetIScheme(scheme)->GetFont( "CommentaryDefault", true );
if ( !hFont )
{
hFont = vgui::scheme()->GetIScheme(scheme)->GetFont( "Default" );
hFont = vgui::scheme()->GetIScheme(scheme)->GetFont( "Default", true );
}
vgui::surface()->DrawSetTextFont( hFont );
vgui::surface()->DrawSetTextColor( clr );
+1 -1
View File
@@ -267,7 +267,7 @@ void C_SlideshowDisplay::BuildSlideShowImagesList( void )
char szFullFileName[_MAX_PATH];
Q_snprintf( szFullFileName, sizeof( szFullFileName ), "materials/vgui/%s/%s", m_szSlideshowDirectory, szMatFileName );
KeyValues *pMaterialKeys = new KeyValues( "material" );
KeyValuesAD pMaterialKeys( "material" );
bool bLoaded = pMaterialKeys->LoadFromFile( g_pFullFileSystem, szFullFileName, NULL );
if ( bLoaded )
+1 -1
View File
@@ -121,7 +121,7 @@ inline ClientThinkHandle_t CClientThinkList::GetInvalidThinkHandle()
inline CClientThinkList::ThinkEntry_t* CClientThinkList::GetThinkEntry( ClientThinkHandle_t hThink )
{
return &m_ThinkEntries[ (unsigned long)hThink ];
return &m_ThinkEntries[ (uintp)hThink ];
}
+15 -12
View File
@@ -837,23 +837,26 @@ void ClientModeShared::StartMessageMode( int iMessageModeType )
}
#if defined( TF_CLIENT_DLL )
bool bSuspensionInMatch = GTFGCClientSystem() && GTFGCClientSystem()->BHaveChatSuspensionInCurrentMatch();
if ( !cl_enable_text_chat.GetBool() || bSuspensionInMatch )
if ( iMessageModeType == MM_SAY || iMessageModeType == MM_SAY_TEAM )
{
CBaseHudChat *pHUDChat = ( CBaseHudChat * ) GET_HUDELEMENT( CHudChat );
if ( pHUDChat )
bool bSuspensionInMatch = GTFGCClientSystem() && GTFGCClientSystem()->BHaveChatSuspensionInCurrentMatch();
if ( !cl_enable_text_chat.GetBool() || bSuspensionInMatch )
{
const char *pszReason = "#TF_Chat_Disabled";
if ( bSuspensionInMatch )
CBaseHudChat *pHUDChat = ( CBaseHudChat * ) GET_HUDELEMENT( CHudChat );
if ( pHUDChat )
{
pszReason = "#TF_Chat_Unavailable";
}
const char *pszReason = "#TF_Chat_Disabled";
if ( bSuspensionInMatch )
{
pszReason = "#TF_Chat_Unavailable";
}
char szLocalized[100];
g_pVGuiLocalize->ConvertUnicodeToANSI( g_pVGuiLocalize->Find( pszReason ), szLocalized, sizeof( szLocalized ) );
pHUDChat->ChatPrintf( 0, CHAT_FILTER_NONE, "%s ", szLocalized );
char szLocalized[100];
g_pVGuiLocalize->ConvertUnicodeToANSI( g_pVGuiLocalize->Find( pszReason ), szLocalized, sizeof( szLocalized ) );
pHUDChat->ChatPrintf( 0, CHAT_FILTER_NONE, "%s ", szLocalized );
}
return;
}
return;
}
#endif // TF_CLIENT_DLL
+7 -4
View File
@@ -19,6 +19,7 @@
#include "vgui_controls/ComboBox.h"
#include "vgui/IInput.h"
#include "econ_ui.h"
#include "c_tf_player.h"
// memdbgon must be the last include file in a .cpp file!!!
#include <tier0/memdbgon.h>
@@ -265,8 +266,9 @@ void CBaseLoadoutPanel::ShowPanel( int iClass, bool bBackpack, bool bReturningFr
UpdateModelPanels();
// make the first slot be selected so controller input will work
static ConVarRef joystick( "joystick" );
if( joystick.IsValid() && joystick.GetBool() && m_pItemModelPanels.Count() && m_pItemModelPanels[0] )
//static ConVarRef joystick( "joystick" );
bool bSteamController = ::input->IsSteamControllerActive();
if( bSteamController && m_pItemModelPanels.Count() && m_pItemModelPanels[0] )
{
m_pItemModelPanels[0]->SetSelected( true );
m_pItemModelPanels[0]->RequestFocus();
@@ -678,6 +680,7 @@ bool CBaseLoadoutPanel::HandleItemSelectionKeyPressed( vgui::KeyCode code )
if ( nButtonCode == KEY_XBUTTON_UP ||
nButtonCode == KEY_XSTICK1_UP ||
nButtonCode == KEY_XSTICK2_UP ||
nButtonCode == STEAMCONTROLLER_DPAD_UP ||
nButtonCode == KEY_UP )
{
SelectAdjacentItem( 0, -1 );
@@ -730,7 +733,7 @@ bool CBaseLoadoutPanel::HandleItemSelectionKeyPressed( vgui::KeyCode code )
}
return true;
}
else if ( nButtonCode == KEY_XBUTTON_Y )
else if ( nButtonCode == KEY_XBUTTON_Y || nButtonCode == STEAMCONTROLLER_Y )
{
m_bTooltipKeyPressed = true;
CItemModelPanel *pSelection = GetFirstSelectedItemModelPanel( false );
@@ -754,7 +757,7 @@ bool CBaseLoadoutPanel::HandleItemSelectionKeyPressed( vgui::KeyCode code )
bool CBaseLoadoutPanel::HandleItemSelectionKeyReleased( vgui::KeyCode code )
{
ButtonCode_t nButtonCode = GetBaseButtonCode( code );
if( nButtonCode == KEY_XBUTTON_Y )
if( nButtonCode == KEY_XBUTTON_Y || nButtonCode == STEAMCONTROLLER_Y )
{
m_bTooltipKeyPressed = false;
m_pMouseOverTooltip->HideTooltip();
+3 -1
View File
@@ -1910,7 +1910,7 @@ void CExplanationPopup::OnKeyCodePressed( vgui::KeyCode code )
ButtonCode_t nButtonCode = GetBaseButtonCode( code );
// swallow all keys
if ( nButtonCode == KEY_XBUTTON_B )
if ( nButtonCode == KEY_XBUTTON_B || nButtonCode == STEAMCONTROLLER_B )
{
OnCommand( "close" );
return;
@@ -1918,6 +1918,7 @@ void CExplanationPopup::OnKeyCodePressed( vgui::KeyCode code )
else if ( nButtonCode == KEY_XBUTTON_LEFT ||
nButtonCode == KEY_XSTICK1_LEFT ||
nButtonCode == KEY_XSTICK2_LEFT ||
nButtonCode == STEAMCONTROLLER_DPAD_LEFT ||
code == KEY_LEFT )
{
OnCommand( "prevexplanation" );
@@ -1926,6 +1927,7 @@ void CExplanationPopup::OnKeyCodePressed( vgui::KeyCode code )
else if ( nButtonCode == KEY_XBUTTON_RIGHT ||
nButtonCode == KEY_XSTICK1_RIGHT ||
nButtonCode == KEY_XSTICK2_RIGHT ||
nButtonCode == STEAMCONTROLLER_DPAD_RIGHT ||
code == KEY_RIGHT )
{
OnCommand( "nextexplanation" );
+3 -1
View File
@@ -473,6 +473,7 @@ void CItemPickupPanel::OnKeyCodePressed( vgui::KeyCode code )
else if ( nButtonCode == KEY_XBUTTON_RIGHT ||
nButtonCode == KEY_XSTICK1_RIGHT ||
nButtonCode == KEY_XSTICK2_RIGHT ||
nButtonCode == STEAMCONTROLLER_DPAD_RIGHT ||
nButtonCode == KEY_RIGHT )
{
OnCommand( "nextitem" );
@@ -480,6 +481,7 @@ void CItemPickupPanel::OnKeyCodePressed( vgui::KeyCode code )
else if ( nButtonCode == KEY_XBUTTON_LEFT ||
nButtonCode == KEY_XSTICK1_LEFT ||
nButtonCode == KEY_XSTICK2_LEFT ||
nButtonCode == STEAMCONTROLLER_DPAD_LEFT ||
nButtonCode == KEY_LEFT )
{
OnCommand( "previtem" );
@@ -848,7 +850,7 @@ void CItemDiscardPanel::OnKeyCodePressed( vgui::KeyCode code )
{
ButtonCode_t nButtonCode = GetBaseButtonCode( code );
if( nButtonCode == KEY_XBUTTON_B )
if( nButtonCode == KEY_XBUTTON_B || nButtonCode == STEAMCONTROLLER_B )
{
OnCommand( "vguicancel" );
}
+7 -5
View File
@@ -378,9 +378,10 @@ void CItemSelectionPanel::OnKeyCodePressed( vgui::KeyCode code )
NotifySelectionReturned( pItemPanel );
}
}
else if( nButtonCode == KEY_XBUTTON_B )
else if( nButtonCode == KEY_XBUTTON_B || nButtonCode == STEAMCONTROLLER_B )
{
PostMessageSelectionReturned( INVALID_ITEM_ID );
//match the same behaviour as pressing ESC
PostMessageSelectionReturned( 0 );
OnClose();
}
else
@@ -1085,8 +1086,9 @@ void CEquipSlotItemSelectionPanel::UpdateModelPanelsForSelection( void )
int nPageStart = GetCurrentPage() * GetNumSlotsPerPage();
nOldSelection += nPageStart;
static ConVarRef joystick( "joystick" );
if ( joystick.IsValid() && joystick.GetBool() )
//static ConVarRef joystick( "joystick" );
bool bSteamController = ::input->IsSteamControllerActive();
if ( bSteamController )
{
if( nOldSelection == -1 || nOldSelection >= vecDisplayItems.Count() )
nOldSelection = nPageStart;
@@ -1102,7 +1104,7 @@ void CEquipSlotItemSelectionPanel::UpdateModelPanelsForSelection( void )
m_pItemModelPanels[i]->SetShowGreyedOutTooltip( true );
m_pItemModelPanels[i]->SetGreyedOut( NULL );
m_pItemModelPanels[i]->SetNoItemText( "#SelectNoItemSlot" );
bool bSelected = joystick.IsValid() && joystick.GetBool() && iItemIndex == nOldSelection;
bool bSelected = bSteamController && iItemIndex == nOldSelection;
m_pItemModelPanels[i]->SetSelected( bSelected );
m_pItemModelPanels[i]->SetShowQuantity( true );
m_pItemModelPanels[i]->SetForceShowEquipped( false );
-3
View File
@@ -76,9 +76,6 @@ static ConCommand dropprimary("dropprimary", CC_DropPrimary, "dropprimary: Drops
//-----------------------------------------------------------------------------
C_BaseHLPlayer::C_BaseHLPlayer()
{
AddVar( &m_Local.m_vecPunchAngle, &m_Local.m_iv_vecPunchAngle, LATCH_SIMULATION_VAR );
AddVar( &m_Local.m_vecPunchAngleVel, &m_Local.m_iv_vecPunchAngleVel, LATCH_SIMULATION_VAR );
m_flZoomStart = 0.0f;
m_flZoomEnd = 0.0f;
m_flZoomRate = 0.0f;
+1 -1
View File
@@ -1186,7 +1186,7 @@ void CBaseHudChat::StartMessageMode( int iMessageModeType )
{
case MM_SAY: pszPrompt = g_pVGuiLocalize->Find( "#chat_say" ); break;
case MM_SAY_TEAM: pszPrompt = g_pVGuiLocalize->Find( "#chat_say_team" ); break;
case MM_SAY_PARTY: pszPrompt = g_pVGuiLocalize->Find( "#chat_party" ); break;
case MM_SAY_PARTY: pszPrompt = g_pVGuiLocalize->Find( "#chat_say_party" ); break;
}
if ( pszPrompt )
+1 -1
View File
@@ -1596,7 +1596,7 @@ void CHudCloseCaption::CreateFonts( void )
{
vgui::IScheme *pScheme = vgui::scheme()->GetIScheme( GetScheme() );
m_hFonts[CCFONT_NORMAL] = pScheme->GetFont( "CloseCaption_Normal", true );
m_hFonts[CCFONT_NORMAL] = pScheme->GetFont( "CloseCaption", true );
if ( IsPC() )
{
+1 -1
View File
@@ -683,7 +683,7 @@ void CInput::CAM_ToThirdPerson(void)
{
m_fCameraInThirdPerson = true;
g_ThirdPersonManager.SetCameraOffsetAngles( Vector( viewangles[ YAW ], viewangles[ PITCH ], CAM_MIN_DIST ) );
g_ThirdPersonManager.SetCameraOffsetAngles( Vector( viewangles[ PITCH ], viewangles[ YAW ], CAM_MIN_DIST ) );
}
cam_command.SetValue( 0 );
+6 -6
View File
@@ -191,12 +191,12 @@ void CMoveHelperClient::ProcessImpacts( void )
}
// misyl: Debug
if ( vOldLocalVel != vOldAbsVel )
{
Msg( "%d\n", gpGlobals->tickcount );
Msg( "vOldLocalVel: %f %f %f\n", vOldLocalVel.x, vOldLocalVel.y, vOldLocalVel.z );
Msg( "vOldAbsVel: %f %f %f\n", vOldAbsVel.x, vOldAbsVel.y, vOldAbsVel.z );
}
// if ( vOldLocalVel != vOldAbsVel )
// {
// Msg( "%d\n", gpGlobals->tickcount );
// Msg( "vOldLocalVel: %f %f %f\n", vOldLocalVel.x, vOldLocalVel.y, vOldLocalVel.z );
// Msg( "vOldAbsVel: %f %f %f\n", vOldAbsVel.x, vOldAbsVel.y, vOldAbsVel.z );
// }
// Restore the velocity
m_pHost->SetAbsVelocity( vOldAbsVel );
//m_pHost->SetLocalVelocity( vOldLocalVel );
+1
View File
@@ -146,6 +146,7 @@ CParticleEffectBinding::CParticleEffectBinding()
m_LastMin = m_Min;
m_LastMax = m_Max;
m_flParticleCullRadius = -1.f; // dummy value, is overwritten below
SetParticleCullRadius( 0.0f );
m_nActiveParticles = 0;
+1 -3
View File
@@ -269,7 +269,7 @@ bool CEngineSprite::Init( const char *pName )
Q_strncpy( pMaterialPath, pMaterialName, sizeof(pMaterialPath) );
Q_SetExtension( pMaterialPath, ".vmt", sizeof(pMaterialPath) );
KeyValues *kv = new KeyValues( "vmt" );
KeyValuesAD kv( "vmt" );
if ( !kv->LoadFromFile( g_pFullFileSystem, pMaterialPath, "GAME" ) )
{
Warning( "Unable to load sprite material %s!\n", pMaterialPath );
@@ -291,8 +291,6 @@ bool CEngineSprite::Init( const char *pName )
m_material[ i ]->IncrementReferenceCount();
}
kv->deleteThis();
m_width = m_material[0]->GetMappingWidth();
m_height = m_material[0]->GetMappingHeight();
m_numFrames = m_material[0]->GetNumAnimationFrames();
+6 -3
View File
@@ -420,15 +420,18 @@ void C_BaseObject::Simulate( void )
}
else if ( !IsPlacing() && !IsCarried() && m_iLastPlacementPosValid == 0 )
{
// HACK HACK: This sentry has been placed, but was placed on the server before the client updated
float flPlaybackRate = GetPlaybackRate();
// HACK HACK: This object has been placed, but was placed on the server before the client updated
// from the carry position to see that was a valid placement.
// It missed its chance to set the correct activity, so we're doing it now.
SetActivity( ACT_OBJ_RUNNING );
SetActivity( IsBuilding() ? ACT_OBJ_ASSEMBLING : ACT_OBJ_RUNNING );
SetPlaybackRate( flPlaybackRate );
// Check if the activity was valid because it might have still been using the older placement model
if ( GetActivity() != ACT_INVALID )
{
// Remember to retest our placement, but don't keep forcing the running activity
// Remember to retest our placement, but don't keep forcing the new activity
m_iLastPlacementPosValid = -1;
}
}
+55 -13
View File
@@ -60,7 +60,7 @@ C_ObjectSentrygun::C_ObjectSentrygun()
m_nShieldLevel = SHIELD_NONE;
m_nOldShieldLevel = SHIELD_NONE;
m_hLaserBeamEffect = NULL;
m_pTempShield = NULL;
m_hShieldModel = NULL;
m_bNearMiss = false;
m_flNextNearMissCheck = 0.f;
@@ -312,7 +312,7 @@ 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 )
if ( m_hShieldModel )
{
m_bRecreateShield = true;
m_bRecreateLaserBeam = true;
@@ -329,13 +329,12 @@ 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_hShieldModel = C_SentrygunShield::Create( "models/buildables/sentry_shield.mdl" );
if ( m_hShieldModel )
{
m_pTempShield->ChangeTeam( GetTeamNumber() );
m_pTempShield->m_nSkin = ( GetTeamNumber() == TF_TEAM_RED ) ? 0 : 1;
//m_pTempShield->m_nRenderFX = kRenderFxDistort;
m_hShieldModel->FollowEntity( this, false );
m_hShieldModel->ChangeTeam( GetTeamNumber() );
m_hShieldModel->m_nSkin = ( GetTeamNumber() == TF_TEAM_RED ) ? 0 : 1;
}
m_hShieldEffect = ParticleProp()->Create( "turret_shield", PATTACH_ABSORIGIN_FOLLOW, 0, Vector( 0,0,30) );
@@ -356,12 +355,10 @@ void C_ObjectSentrygun::CreateShield( void )
//-----------------------------------------------------------------------------
void C_ObjectSentrygun::DestroyShield( void )
{
if ( m_pTempShield )
if ( m_hShieldModel )
{
m_pTempShield->flags = FTENT_FADEOUT;
m_pTempShield->die = gpGlobals->curtime;
m_pTempShield->fadeSpeed = 1.0f;
m_pTempShield = NULL;
m_hShieldModel->StartFadeOut( 1.0f );
m_hShieldModel = NULL;
}
if ( m_hShieldEffect )
@@ -758,4 +755,49 @@ const char* C_ObjectSentrygun::GetStatusName() const
return "#TF_Object_Sentry";
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
C_SentrygunShield *C_SentrygunShield::Create( const char *pszModelName )
{
C_SentrygunShield *pShield = new C_SentrygunShield();
if ( !pShield )
return NULL;
if ( !pShield->InitializeAsClientEntity( pszModelName, RENDER_GROUP_TRANSLUCENT_ENTITY ) )
{
pShield->Release();
return NULL;
}
pShield->AddEffects( EF_NORECEIVESHADOW | EF_NOSHADOW );
return pShield;
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void C_SentrygunShield::ClientThink()
{
if ( m_flFadeOutEndTime <= gpGlobals->curtime )
{
Release();
return;
}
float flAlpha = RemapVal( gpGlobals->curtime, m_flFadeOutStartTime, m_flFadeOutEndTime, 255.0f, 0.0f );
SetRenderColorA( (byte)flAlpha );
SetNextClientThink( CLIENT_THINK_ALWAYS );
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void C_SentrygunShield::StartFadeOut( float flDuration )
{
SetRenderMode( kRenderTransTexture );
m_flFadeOutStartTime = gpGlobals->curtime;
m_flFadeOutEndTime = gpGlobals->curtime + flDuration;
SetNextClientThink( gpGlobals->curtime );
}
+21 -1
View File
@@ -27,6 +27,26 @@ enum
SHIELD_MAX, // 10% damage taken, no inactive period
};
//-----------------------------------------------------------------------------
// Purpose: Wrangler shield
//-----------------------------------------------------------------------------
class C_SentrygunShield : public C_BaseAnimating
{
DECLARE_CLASS( C_SentrygunShield, C_BaseAnimating );
public:
static C_SentrygunShield *Create( const char *pszModelName );
virtual void ClientThink();
void StartFadeOut( float flDuration );
private:
float m_flFadeOutStartTime;
float m_flFadeOutEndTime;
};
//-----------------------------------------------------------------------------
// Purpose: Sentry object
//-----------------------------------------------------------------------------
@@ -124,7 +144,7 @@ private:
bool m_bRecreateLaserBeam;
float m_flNextNearMissCheck;
C_LocalTempEntity *m_pTempShield;
CHandle<C_SentrygunShield> m_hShieldModel;
HPARTICLEFFECT m_hSirenEffect;
HPARTICLEFFECT m_hShieldEffect;
+7
View File
@@ -186,6 +186,13 @@ void C_ObjectTeleporter::StopActiveEffects()
ParticleProp()->StopEmission( m_hChargedRightArmEffect );
m_hChargedRightArmEffect = NULL;
}
if ( m_pSpinSound && IsCarried() )
{
CSoundEnvelopeController& controller = CSoundEnvelopeController::GetController();
controller.SoundDestroy( m_pSpinSound );
m_pSpinSound = NULL;
}
}
//-----------------------------------------------------------------------------
+80 -22
View File
@@ -76,6 +76,9 @@
#include "netadr.h"
#include "input.h"
// for rescue ranger
#include "materialsystem/imaterialproxy.h"
#include "gcsdk/gcclientsdk.h"
#include "econ_gcmessages.h"
#include "rtime.h"
@@ -2289,12 +2292,31 @@ public:
EXPOSE_INTERFACE( CProxyBenefactorLevel, IMaterialProxy, "BenefactorLevel" IMATERIAL_PROXY_INTERFACE_VERSION );
//-----------------------------------------------------------------------------
// Purpose: Used for scaling the oscilloscope on the Building Rescue Gun
// Flattens the Wave when the player has no energy
// Purpose: Used for scaling the oscilloscope on the Rescue Ranger
// Flattens the Wave when the player has insufficent energy to rescue buildings
// Wave has horizontal scrolling whose speed and direction can be controlled from material proxy
//-----------------------------------------------------------------------------
class CProxyBuildingRescueLevel : public CResultProxy
{
public:
// Add this member (default to something safe)
float m_flScrollSpeed = -0.1f;
virtual bool Init( IMaterial *pMaterial, KeyValues *pKeyValues )
{
// Call base init first if needed
if ( !CResultProxy::Init( pMaterial, pKeyValues ) )
return false;
// pKeyValues points to the { "screenScrollRate" "#" ... } subkey
if ( pKeyValues )
{
m_flScrollSpeed = pKeyValues->GetFloat( "screenScrollRate", -0.1f ); // fallback if missing
}
return true;
}
void OnBind( void *pC_BaseEntity )
{
Assert( m_pResult );
@@ -2338,6 +2360,17 @@ public:
MatrixBuildTranslation( temp, center.x, center.y, 0.0f );
MatrixMultiply( temp, mat, mat );
float flScrollSpeed = m_flScrollSpeed;
float scrollOffset = fmodf( gpGlobals->curtime * flScrollSpeed, 1.0f );
if ( scrollOffset < 0.0f )
scrollOffset += 1.0f; // [0,1) range for seamless loop
// Apply horizontal scroll AFTER the existing scale/center operations
MatrixBuildTranslation( temp, scrollOffset, 0.0f, 0.0f );
MatrixMultiply( temp, mat, mat );
m_pResult->SetMatrixValue( mat );
if ( ToolsEnabled() )
@@ -2347,7 +2380,7 @@ public:
}
};
EXPOSE_INTERFACE( CProxyBuildingRescueLevel, IMaterialProxy, "BuildingRescueLevel" IMATERIAL_PROXY_INTERFACE_VERSION );
EXPOSE_INTERFACE(CProxyBuildingRescueLevel, IMaterialProxy, "BuildingRescueLevel" IMATERIAL_PROXY_INTERFACE_VERSION);
//-----------------------------------------------------------------------------
@@ -3727,6 +3760,7 @@ IMPLEMENT_CLIENTCLASS_DT( C_TFPlayer, DT_TFPlayer, CTFPlayer )
RecvPropFloat( RECVINFO( m_flMvMLastDamageTime ) ),
RecvPropFloat( RECVINFO_NAME( m_flMvMLastDamageTime, "m_flLastDamageTime" ) ), // Renamed
RecvPropInt( RECVINFO( m_iSpawnCounter ) ),
RecvPropBool( RECVINFO( m_bFlipViewModels ) ),
RecvPropBool( RECVINFO( m_bArenaSpectator ) ),
RecvPropDataTable( RECVINFO_DT( m_AttributeManager ), 0, &REFERENCE_RECV_TABLE(DT_AttributeManager) ),
@@ -3756,6 +3790,7 @@ IMPLEMENT_CLIENTCLASS_DT( C_TFPlayer, DT_TFPlayer, CTFPlayer )
RecvPropInt( RECVINFO( m_iPlayerSkinOverride ) ),
RecvPropBool( RECVINFO( m_bViewingCYOAPDA ) ),
RecvPropBool( RECVINFO( m_bRegenerating ) ),
RecvPropEHandle( RECVINFO( m_hOffHandWeapon ) ),
END_RECV_TABLE()
@@ -5852,6 +5887,17 @@ bool C_TFPlayer::IsPlayerOnSteamFriendsList( C_BasePlayer *pPlayer )
return false;
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void C_TFPlayer::PreThink( void )
{
// Update timers.
UpdateTimers();
// Pass through to the base class think.
BaseClass::PreThink();
}
//-----------------------------------------------------------------------------
// Purpose:
@@ -6050,13 +6096,18 @@ void C_TFPlayer::ClientThink()
//
// Passtime ask for ball button
//
if ( m_nButtons & IN_ATTACK3 )
if ( m_afButtonPressed & IN_ATTACK3 )
{
engine->ClientCmd("voicemenu 1 8");
}
}
}
void C_TFPlayer::UpdateTimers( void )
{
m_Shared.SharedThink();
}
void C_TFPlayer::Touch( CBaseEntity *pOther )
{
BaseClass::Touch( pOther );
@@ -7001,6 +7052,15 @@ void C_TFPlayer::UpdateIDTarget()
if ( tr.m_pEnt && tr.m_pEnt->IsPlayer() )
{
trace_t trShot;
// use the shot mask to replicate the medigun's trace
UTIL_TraceLine( vecStart, vecEnd, MASK_SHOT, this, COLLISION_GROUP_NONE, &trShot );
if ( trShot.fraction != 1.0 && trShot.m_pEnt && trShot.m_pEnt->IsPlayer() && ( !tr.startsolid || tr.m_pEnt != trShot.m_pEnt ) )
{
tr = trShot;
}
// It's okay to start solid against enemies because we sometimes press right against them
bIsEnemyPlayer = GetTeamNumber() != tr.m_pEnt->GetTeamNumber();
}
@@ -9125,7 +9185,7 @@ CNewParticleEffect *C_TFPlayer::SpawnHalloweenSpellFootsteps( ParticleAttachment
kHalloweenSpell_RGBConstant_HHH = 2,
kHalloweenSpell_RGBConstant_TeamColor = 1,
kHalloweenSpell_RGB_Red = 12073019,
kHalloweenSpell_RGB_Blue = 5801378,
kHalloweenSpell_RGB_Blue = 2192591,
};
if ( iHalloweenFootstepType == kHalloweenSpell_RGBConstant_HHH )
@@ -11610,26 +11670,24 @@ void C_TFPlayer::ClientAdjustVOPitch( int& pitch )
{
pitch *= 1.3f;
}
// Halloween voice futzery?
else
float flVoicePitchScale = 1.f;
CALL_ATTRIB_HOOK_FLOAT( flVoicePitchScale, voice_pitch_scale );
int iHalloweenVoiceSpell = 0;
if ( TF_IsHolidayActive( kHoliday_HalloweenOrFullMoon ) )
{
float flVoicePitchScale = 1.f;
CALL_ATTRIB_HOOK_FLOAT( flVoicePitchScale, voice_pitch_scale );
CALL_ATTRIB_HOOK_INT( iHalloweenVoiceSpell, halloween_voice_modulation );
}
int iHalloweenVoiceSpell = 0;
if ( TF_IsHolidayActive( kHoliday_HalloweenOrFullMoon ) )
{
CALL_ATTRIB_HOOK_INT( iHalloweenVoiceSpell, halloween_voice_modulation );
}
if ( iHalloweenVoiceSpell > 0 )
{
pitch *= 0.8f;
}
else if ( flVoicePitchScale != 1.f )
{
pitch *= flVoicePitchScale;
}
if ( iHalloweenVoiceSpell > 0 )
{
pitch *= 0.8f;
}
else if ( flVoicePitchScale != 1.f )
{
pitch *= flVoicePitchScale;
}
}
+6
View File
@@ -111,8 +111,11 @@ public:
void StopViewModelParticles( C_BaseEntity *pParticleEnt );
virtual void PreThink( void );
virtual void ClientThink();
void UpdateTimers();
// Deal with recording
virtual void GetToolRecordingState( KeyValues *msg );
@@ -124,6 +127,7 @@ public:
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;
virtual void PlayStepSound( Vector &vecOrigin, surfacedata_t *psurface, float fvol, bool force );
CNewParticleEffect *SpawnHalloweenSpellFootsteps( ParticleAttachment_t eParticleAttachment, int iHalloweenFootstepType );
@@ -662,6 +666,8 @@ public:
int m_iSpawnCounter;
bool m_bArenaSpectator;
bool m_bFlipViewModels;
bool m_bIsMiniBoss;
bool m_bIsABot;
int m_nBotSkill;
+1
View File
@@ -531,6 +531,7 @@ void ClientModeTFNormal::Shutdown()
{
RemoveFilesInPath( "materials/temp" );
RemoveFilesInPath( "download/user_custom" );
RemoveFilesInPath( "sound/temp" );
}
DestroyStatsSummaryPanel();
+2 -2
View File
@@ -35,7 +35,7 @@ void CTFAutoRP::ParseDataFile( void )
Assert( !m_pDataFileKV );
// Load & parse the word files
KeyValues *pFileKV = new KeyValues( "AutoRPFile" );
KeyValuesAD pFileKV( "AutoRPFile" );
if ( pFileKV->LoadFromFile( filesystem, "scripts/autorp.txt", "MOD" ) == false )
return;
@@ -547,7 +547,7 @@ void CTFAutoRP::ModifySpeech( const char *pszInText, char *pszOutText, int iOutL
{
szStoredWord[0] = toupper( szStoredWord[0] );
}
else if ( pszCurWord[0] >= 'a' && pszCurWord[0] <= 'a' )
else if ( pszCurWord[0] >= 'a' && pszCurWord[0] <= 'z' )
{
szStoredWord[0] = tolower( szStoredWord[0] );
}
+4 -4
View File
@@ -198,7 +198,7 @@ public:
virtual const char *GetResFileName( void ) { return "resource/UI/HudAccountPanel.res"; }
protected:
virtual Color GetColor( const account_delta_t::eAccountDeltaType_t& type );
virtual Color GetColor( const account_delta_t::eAccountDeltaType_t &type, const int iDeltaValue = 0 );
CUtlVector <account_delta_t> m_AccountDeltaItems;
@@ -1030,7 +1030,7 @@ account_delta_t *CAccountPanel::OnAccountValueChanged( int iOldValue, int iNewVa
pNewDeltaItem->m_bLargeFont = false;
pNewDeltaItem->m_eDataType = type;
pNewDeltaItem->m_wzText[0] = NULL;
pNewDeltaItem->m_color = GetColor( type );
pNewDeltaItem->m_color = GetColor( type, iDelta );
pNewDeltaItem->m_bShadows = false;
return &m_AccountDeltaItems[index];
}
@@ -1038,7 +1038,7 @@ account_delta_t *CAccountPanel::OnAccountValueChanged( int iOldValue, int iNewVa
return NULL;
}
Color CAccountPanel::GetColor( const account_delta_t::eAccountDeltaType_t& type )
Color CAccountPanel::GetColor( const account_delta_t::eAccountDeltaType_t &type, const int iDeltaValue )
{
if ( type == account_delta_t::ACCOUNT_DELTA_BONUS_POINTS )
{
@@ -1046,7 +1046,7 @@ Color CAccountPanel::GetColor( const account_delta_t::eAccountDeltaType_t& type
}
else if ( type == account_delta_t::ACCOUNT_DELTA_HEALING )
{
return m_DeltaPositiveColor;
return ( iDeltaValue < 0 ) ? m_DeltaNegativeColor : m_DeltaPositiveColor;
}
else if ( type == account_delta_t::ACCOUNT_DELTA_DAMAGE )
{
+2 -2
View File
@@ -777,7 +777,7 @@ void CHudMainMenuOverride::LoadCharacterImageFile( void )
//-----------------------------------------------------------------------------
void CHudMainMenuOverride::LoadMenuEntries( void )
{
KeyValues *datafile = new KeyValues("GameMenu");
KeyValuesAD datafile("GameMenu");
datafile->UsesEscapeSequences( true ); // VGUI uses escape sequences
bool bLoaded = datafile->LoadFromFile( g_pFullFileSystem, "Resource/GameMenu.res", "custom_mod" );
if ( !bLoaded )
@@ -2274,7 +2274,7 @@ public:
//V_strcpy_safe( uilanguage, "german" );
KeyValues *pEntriesKV = new KeyValues( "motd_entries");
KeyValuesAD pEntriesKV( "motd_entries");
// Try and load the cache file. If we fail, we'll just create a new one.
if ( !pMMPanel->ReloadedAllMOTDs() )
@@ -851,7 +851,14 @@ void CWaveStatusPanel::UpdateEnemyCounts( void )
if ( pPanel->m_pEnemyCountImageBG )
{
pPanel->m_pEnemyCountImageBG->SetBgColor( m_clrNormal );
if ( support[i].iFlags & MVM_CLASS_FLAG_MINIBOSS )
{
pPanel->m_pEnemyCountImageBG->SetBgColor( m_clrMiniBoss );
}
else
{
pPanel->m_pEnemyCountImageBG->SetBgColor( m_clrNormal );
}
}
if ( pPanel->m_pEnemyCountCritBG )
+30 -7
View File
@@ -358,7 +358,7 @@ void CTFHudMatchStatus::ApplySchemeSettings(IScheme *pScheme)
pConditions = new KeyValues( "conditions" );
AddSubKeyNamed( pConditions, "if_match" );
const IMatchGroupDescription* pMatchDesc = GetMatchGroupDescription( GTFGCClientSystem()->GetLiveMatchGroup() );
const IMatchGroupDescription* pMatchDesc = GetMatchGroupDescription( TFGameRules() ? TFGameRules()->GetCurrentMatchGroup() : GTFGCClientSystem()->GetLiveMatchGroup() );
if ( pMatchDesc )
{
if ( pMatchDesc->GetMatchSize() > 12 )
@@ -574,16 +574,39 @@ void CTFHudMatchStatus::FireGameEvent( IGameEvent * event )
}
const IMatchGroupDescription* pMatchDesc = GetMatchGroupDescription( TFGameRules()->GetCurrentMatchGroup() );
bool bForceDoors = false;
if ( bForceDoors || ( pMatchDesc && pMatchDesc->BUsesPostRoundDoors() ) )
if ( pMatchDesc )
{
if ( TFGameRules() && TFGameRules()->MapHasMatchSummaryStage() && ( bForceDoors || pMatchDesc->BUseMatchSummaryStage() ) )
// FIX: Refresh versus doors so late-joiners do not see the wrong skin
int nSkin = 0;
int nSubModel = 0;
if ( pMatchDesc->BGetRoundDoorParameters( nSkin, nSubModel ) )
{
g_pClientMode->GetViewportAnimationController()->StartAnimationSequence( this, "HudMatchStatus_ShowMatchWinDoors", false );
if ( m_pMatchStartModelPanel )
{
// Is VS doors model not initialized yet?
if ( m_pMatchStartModelPanel->m_hModel == NULL )
{
m_pMatchStartModelPanel->UpdateModel();
}
m_pMatchStartModelPanel->SetBodyGroup( "logos", nSubModel );
m_pMatchStartModelPanel->UpdateModel();
m_pMatchStartModelPanel->SetSkin( nSkin );
}
}
else
bool bForceDoors = false;
if ( bForceDoors || ( pMatchDesc && pMatchDesc->BUsesPostRoundDoors() ) )
{
g_pClientMode->GetViewportAnimationController()->StartAnimationSequence( this, "HudMatchStatus_ShowMatchWinDoors_NoOpen", false );
if ( TFGameRules() && TFGameRules()->MapHasMatchSummaryStage() && ( bForceDoors || pMatchDesc->BUseMatchSummaryStage() ) )
{
g_pClientMode->GetViewportAnimationController()->StartAnimationSequence( this, "HudMatchStatus_ShowMatchWinDoors", false );
}
else
{
g_pClientMode->GetViewportAnimationController()->StartAnimationSequence( this, "HudMatchStatus_ShowMatchWinDoors_NoOpen", false );
}
}
}
}
+2
View File
@@ -813,6 +813,8 @@ CTFHudPasstimeBallStatus::CTFHudPasstimeBallStatus( Panel *pParent )
//-----------------------------------------------------------------------------
CTFHudPasstimeBallStatus::~CTFHudPasstimeBallStatus()
{
delete m_pEventText;
m_pEventText = nullptr;
}
//-----------------------------------------------------------------------------
+1
View File
@@ -242,6 +242,7 @@ protected:
virtual void ApplySchemeSettings(vgui::IScheme *scheme);
virtual void Paint( void );
virtual bool ShouldDraw( void );
virtual bool CanAnimate() const OVERRIDE { return false; }
private:
int m_iScopeTexture[4];
+1 -1
View File
@@ -403,7 +403,7 @@ void CCharacterInfoPanel::OnKeyCodePressed(vgui::KeyCode code)
{
ButtonCode_t nButtonCode = GetBaseButtonCode( code );
if ( nButtonCode == KEY_XBUTTON_B )
if ( nButtonCode == KEY_XBUTTON_B || nButtonCode == STEAMCONTROLLER_B )
{
if ( !m_bPreventClosure )
{
@@ -23,6 +23,7 @@
#include <tier0/memdbgon.h>
ConVar tf_explanations_charinfo_armory_panel( "tf_explanations_charinfo_armory_panel", "0", FCVAR_ARCHIVE, "Whether the user has seen explanations for this panel." );
ConVar tf_armory_page_skip( "tf_armory_page_skip", "10", FCVAR_ARCHIVE, "Number of pages to skip in the Mann Co. Catalog", true, 1, true, 100 );
const char *g_szArmoryFilterStrings[ARMFILT_TOTAL] =
{
@@ -60,8 +61,6 @@ CArmoryPanel::CArmoryPanel(Panel *parent, const char *panelName) : vgui::Editabl
m_CurrentFilter = ARMFILT_ALL_ITEMS;
m_OldFilter = ARMFILT_ALL_ITEMS;
m_iFilterPage = 0;
m_pNextPageButton = NULL;
m_pPrevPageButton = NULL;
m_pViewSetButton = NULL;
m_pStoreButton = NULL;
m_bAllowGotoStore = false;
@@ -109,8 +108,6 @@ void CArmoryPanel::ApplySchemeSettings( vgui::IScheme *pScheme )
m_pMouseOverItemPanel->SetBorder( pScheme->GetBorder("LoadoutItemPopupBorder") );
m_pDataTextRichText = dynamic_cast<CEconItemDetailsRichText*>( m_pDataPanel->FindChildByName( "Data_TextRichText" ) );
m_pNextPageButton = dynamic_cast<CExButton*>( FindChildByName("NextPageButton") );
m_pPrevPageButton = dynamic_cast<CExButton*>( FindChildByName("PrevPageButton") );
m_pViewSetButton = dynamic_cast<CExButton*>( FindChildByName("ViewSetButton") );
m_pStoreButton = dynamic_cast<CExButton*>( FindChildByName("StoreButton") );
@@ -311,26 +308,63 @@ void CArmoryPanel::OnClosing()
//-----------------------------------------------------------------------------
void CArmoryPanel::OnCommand( const char *command )
{
if ( !Q_strnicmp( command, "prevpage", 8 ) )
if ( !Q_stricmp( command, "prevpage" ) )
{
if ( m_iFilterPage > 0 )
{
m_iFilterPage--;
UpdateItemList();
UpdateSelectedItem();
}
return;
}
else if ( !Q_strnicmp( command, "nextpage", 8 ) )
{
int nMaxPages = MAX( 1, ceil(m_FilteredItemList.Count() / (float)(m_iThumbnailRows * m_iThumbnailColumns)) );
if ( m_iFilterPage < (nMaxPages-1) )
else
{
m_iFilterPage++;
UpdateItemList();
UpdateSelectedItem();
m_iFilterPage = ceil( m_FilteredItemList.Count() / (float)( m_iThumbnailRows * m_iThumbnailColumns ) ) - 1;
}
return;
UpdateItemList();
UpdateSelectedItem();
}
else if ( !Q_stricmp( command, "prevpageskip" ) )
{
for ( int i = 0; i < tf_armory_page_skip.GetInt(); i++ )
{
if ( m_iFilterPage > 0 )
{
m_iFilterPage--;
}
else
{
m_iFilterPage = ceil( m_FilteredItemList.Count() / (float)( m_iThumbnailRows * m_iThumbnailColumns ) ) - 1;
}
}
UpdateItemList();
UpdateSelectedItem();
}
else if ( !Q_stricmp( command, "skiptostart" ) )
{
m_iFilterPage = 0;
UpdateItemList();
UpdateSelectedItem();
}
else if ( !Q_stricmp( command, "nextpage" ) )
{
m_iFilterPage++;
if ( m_iFilterPage > ceil( m_FilteredItemList.Count() / (float)( m_iThumbnailRows * m_iThumbnailColumns ) ) - 1 )
{
m_iFilterPage = 0;
}
UpdateItemList();
UpdateSelectedItem();
}
else if ( !Q_stricmp( command, "nextpageskip" ) )
{
uint32 unNumPages = ceil( m_FilteredItemList.Count() / (float)( m_iThumbnailRows * m_iThumbnailColumns ) );
m_iFilterPage = ( ( m_iFilterPage + tf_armory_page_skip.GetInt() ) % unNumPages );
UpdateItemList();
UpdateSelectedItem();
}
else if ( !Q_stricmp( command, "skiptoend" ) )
{
m_iFilterPage = ceil( m_FilteredItemList.Count() / (float)( m_iThumbnailRows * m_iThumbnailColumns ) ) - 1;
UpdateItemList();
UpdateSelectedItem();
}
else if ( !Q_strnicmp( command, "back", 4 ) )
{
@@ -366,7 +400,7 @@ void CArmoryPanel::OnCommand( const char *command )
ELanguage iLang = PchLanguageToELanguage( uilanguage );
char szURL[512];
Q_snprintf( szURL, sizeof(szURL), "http://wiki.teamfortress.com/scripts/itemredirect.php?id=%d&lang=%s", m_SelectedItem.GetItemDefIndex(), GetLanguageICUName( iLang ) );
Q_snprintf( szURL, sizeof( szURL ), "https://wiki.teamfortress.com/scripts/itemredirect.php?id=%d&lang=%s", m_SelectedItem.GetItemDefIndex(), GetLanguageICUName( iLang ) );
steamapicontext->SteamFriends()->ActivateGameOverlayToWebPage( szURL );
C_CTF_GameStats.Event_Catalog( IE_ARMORY_BROWSE_WIKI, NULL, &m_SelectedItem );
@@ -682,10 +716,6 @@ void CArmoryPanel::UpdateItemList( void )
int nMaxPages = MAX( 1, ceil(m_FilteredItemList.Count() / (float)(m_iThumbnailRows * m_iThumbnailColumns)) );
Q_snprintf(szTmp, 16, "%d/%d", m_iFilterPage+1, nMaxPages );
SetDialogVariable( "thumbnailpage", szTmp );
bool bNextEnabled = m_iFilterPage < (nMaxPages-1);
m_pNextPageButton->SetEnabled( bNextEnabled );
m_pPrevPageButton->SetEnabled( m_iFilterPage > 0 );
}
//-----------------------------------------------------------------------------
@@ -112,8 +112,6 @@ private:
armory_filters_t m_CurrentFilter;
armory_filters_t m_OldFilter;
int m_iFilterPage;
CExButton *m_pNextPageButton;
CExButton *m_pPrevPageButton;
CUtlVector<item_definition_index_t> m_FilteredItemList;
CUtlVector<item_definition_index_t> m_CustomFilteredList;
@@ -1232,7 +1232,7 @@ void CCharInfoLoadoutSubPanel::OnKeyCodePressed(vgui::KeyCode code)
{
// let escape and B (aka "go back") through so we
// can actually get out of the loadout screen
if ( nButtonCode == KEY_XBUTTON_B )
if ( nButtonCode == KEY_XBUTTON_B || nButtonCode == STEAMCONTROLLER_B )
{
BaseClass::OnKeyCodePressed( code );
}
+1
View File
@@ -2215,6 +2215,7 @@ void CTFLogoPanel::PaintTFLogo( float flAngle, const Color& color ) const
void CTFLogoPanel::Paint()
{
m_flOffsetAngle += gpGlobals->frametime * m_flVelocity;
m_flOffsetAngle = fmodf( m_flOffsetAngle, 360.f );
PaintTFLogo( m_flOffsetAngle, GetFgColor() );
BaseClass::Paint();
}
+9 -9
View File
@@ -385,14 +385,6 @@ void CTFMapInfoMenu::LoadMapPage()
{
m_pMapInfo->SetText( wszMapDescription );
}
else if ( StringHasPrefix( m_szMapName, "vsh_" ) )
{
m_pMapInfo->SetText( "#default_vsh_description" );
}
else if ( StringHasPrefix( m_szMapName, "zi_" ) )
{
m_pMapInfo->SetText( "#default_zi_description" );
}
else
{
// try loading map descriptions from .txt files first
@@ -497,7 +489,15 @@ void CTFMapInfoMenu::LoadMapPage()
if( !g_pVGuiLocalize->Find( mapInfoKey ) )
{
if ( TFGameRules() )
if ( MapHasPrefix( m_szMapName, "vsh_" ) )
{
pszDescription = "#default_vsh_description";
}
else if ( MapHasPrefix( m_szMapName, "zi_" ) )
{
pszDescription = "#default_zi_description";
}
else if ( TFGameRules() )
{
if ( TFGameRules()->IsMannVsMachineMode() )
{
@@ -392,7 +392,7 @@ void CDashboardPartyMember::OnCommand( const char *command )
{
case MEMBER_PRESENT:
{
// You can always send a message to party memebers
// You can always send a message to party members
contextMenuBuilder.AddMenuItem( "#TF_Friends_SendMessage", new KeyValues( "Context_SendMessage" ), "party" );
// If we're the leader, we can kick
+57 -15
View File
@@ -34,6 +34,8 @@
DECLARE_BUILD_FACTORY( CTFPlayerModelPanel );
#define SCENE_LERP_TIME 0.1f
char g_szSceneTmpName[256];
static bool IsTauntItem( GameItemDefinition_t *pItemDef, const int iTeam, const int iClass, const char **ppSequence = NULL, const char **ppRequiredItem = NULL, const char **ppScene = NULL )
@@ -466,7 +468,7 @@ CChoreoScene *LoadSceneForModel( const char *filename, IChoreoEventCallback *pCa
if ( bSetEndTime )
{
*flSceneEndTime += 0.1f; // give time for lerp to idle pose
*flSceneEndTime += SCENE_LERP_TIME; // give time for lerp to idle pose
}
}
@@ -547,6 +549,7 @@ void CTFPlayerModelPanel::SwitchHeldItemTo( CEconItemView *pItem )
m_StatTrackModel.m_bDisabled = true;
m_StatTrackModel.m_MDL.SetMDL( MDLHANDLE_INVALID );
m_StatTrackModel.m_pStudioHdr = NULL; // ADDED: Clear the studio header
CAttribute_String attrModule;
if ( GetStattrak( m_pHeldItem, &attrModule ) )
@@ -587,13 +590,28 @@ void CTFPlayerModelPanel::SwitchHeldItemTo( CEconItemView *pItem )
{
hStatTrackMDL = MDLHANDLE_INVALID;
}
m_StatTrackModel.m_MDL.SetMDL( hStatTrackMDL );
mdlcache->Release( hStatTrackMDL ); // counterbalance addref from within FindMDL
m_StatTrackModel.m_MDL.m_pProxyData = static_cast<IClientRenderable*>(pItem);
m_StatTrackModel.m_bDisabled = false;
m_StatTrackModel.m_MDL.m_nSequence = ACT_IDLE;
SetIdentityMatrix( m_StatTrackModel.m_MDLToWorld );
if ( hStatTrackMDL != MDLHANDLE_INVALID )
{
m_StatTrackModel.m_MDL.SetMDL( hStatTrackMDL );
studiohdr_t* pStudioHdr = mdlcache->GetStudioHdr( hStatTrackMDL );
if ( pStudioHdr )
{
if ( !m_StatTrackModel.m_pStudioHdr )
{
m_StatTrackModel.m_pStudioHdr = new CStudioHdr();
}
m_StatTrackModel.m_pStudioHdr->Init( pStudioHdr, mdlcache );
}
mdlcache->Release( hStatTrackMDL );
m_StatTrackModel.m_MDL.m_pProxyData = static_cast<IClientRenderable*>( pItem );
m_StatTrackModel.m_bDisabled = false;
m_StatTrackModel.m_MDL.m_nSequence = ACT_IDLE;
SetIdentityMatrix( m_StatTrackModel.m_MDLToWorld );
}
}
}
@@ -952,6 +970,7 @@ static const char *s_pszDefaultAnimForWpnSlot[] =
"ACT_MP_STAND_PRIMARY", // TF_WPN_TYPE_PRIMARY2
"ACT_MP_STAND_ITEM3", // TF_WPN_TYPE_ITEM3
"ACT_MP_STAND_ITEM4", // TF_WPN_TYPE_ITEM4
"ACT_MP_STAND_PASSTIME", // TF_WPN_TYPE_PASSTIME_BALL
};
COMPILE_TIME_ASSERT( ARRAYSIZE( s_pszDefaultAnimForWpnSlot ) == TF_WPN_TYPE_COUNT );
@@ -1250,6 +1269,14 @@ void CTFPlayerModelPanel::UpdatePreviewVisuals()
SetMDLSkinForTeam( GetMergeMDL( m_MergeMDL ), GetPreviewItem( m_pHeldItem ), m_iTeam );
}
// Set the StatTrack model skin
if ( !m_StatTrackModel.m_bDisabled )
{
int iSkin = 0;
iSkin = m_iTeam == TF_TEAM_RED ? 0 : 1;
m_StatTrackModel.m_MDL.m_nSkin = iSkin;
}
// Set the skin for all other equipped items (wearables, etc).
for ( int i=0; i<m_vecDynamicAssetsLoaded.Count(); i++ )
{
@@ -1516,17 +1543,31 @@ bool CTFPlayerModelPanel::RenderStatTrack( CStudioHdr *pStudioHdr, matrix3x4_t *
{
matrix3x4_t matMergeBoneToWorld[MAXSTUDIOBONES];
// Get the merge studio header.
CStudioHdr *pStatTrackStudioHdr = m_StatTrackModel.m_pStudioHdr;
matrix3x4_t *pMergeBoneToWorld = &matMergeBoneToWorld[0];
// Get the StatTrak model's studio header from the MDL cache
CStudioHdr* pStatTrackStudioHdr = m_StatTrackModel.m_pStudioHdr;
// If m_pStudioHdr isn't set, try to get it from the MDL directly
if ( !pStatTrackStudioHdr )
{
MDLHandle_t hStatTrackMDL = m_StatTrackModel.m_MDL.GetMDL();
if ( hStatTrackMDL != MDLHANDLE_INVALID )
{
pStatTrackStudioHdr = GetMergeMDLStudioHdr( hStatTrackMDL );
}
}
matrix3x4_t* pMergeBoneToWorld = &matMergeBoneToWorld[0];
// If we have a valid mesh, bonemerge it. If we have an invalid mesh we can't bonemerge because
// it'll crash trying to pull data from the missing header.
if ( pStatTrackStudioHdr != NULL )
if ( pStatTrackStudioHdr != NULL && pStudioHdr != NULL )
{
CStudioHdr &mergeHdr = *m_RootMDL.m_pStudioHdr;
m_StatTrackModel.m_MDL.SetupBonesWithBoneMerge( &mergeHdr, pMergeBoneToWorld, pStudioHdr, pWorldMatrix, m_StatTrackModel.m_MDLToWorld );
for ( int i=0; i<mergeHdr.numbones(); ++i )
// The StatTrak model should bone-merge with the WEAPON (pStudioHdr), not the player model
// Parameters: (source header, output matrices, parent header, parent matrices, local transform)
m_StatTrackModel.m_MDL.SetupBonesWithBoneMerge( pStatTrackStudioHdr, pMergeBoneToWorld, pStudioHdr, pWorldMatrix, m_StatTrackModel.m_MDLToWorld );
// Scale the StatTrak model's bones, not the player model bones
for ( int i = 0; i < pStatTrackStudioHdr->numbones(); ++i )
{
MatrixScaleBy( m_flStatTrackScale, pMergeBoneToWorld[i] );
}
@@ -2291,10 +2332,11 @@ void CTFPlayerModelPanel::SetupFlexWeights( void )
// Advance time
if ( m_flLastTickTime < FLT_EPSILON )
{
m_flLastTickTime = m_RootMDL.m_MDL.m_flTime - 0.1;
m_flLastTickTime = m_RootMDL.m_MDL.m_flTime - SCENE_LERP_TIME;
}
m_flSceneTime += (m_RootMDL.m_MDL.m_flTime - m_flLastTickTime);
m_flSceneTime = Max( m_flSceneTime, -SCENE_LERP_TIME );
m_flLastTickTime = m_RootMDL.m_MDL.m_flTime;
if ( m_flSceneEndTime > FLT_EPSILON && m_flSceneTime > m_flSceneEndTime )
+21
View File
@@ -88,6 +88,7 @@ static const char *kBodygroupArray[] =
"headphones",
"shoes",
"shoes_socks",
"bullets"
};
extern IFileSystem *g_pFullFileSystem;
@@ -6998,6 +6999,9 @@ CTFFileImportDialog::LOAD_RESULT CTFFileImportDialog::LoadTxt( const char *pszFi
}
}
char szFileBase[ MAX_PATH ];
V_FileBase( pszSourceFile, szFileBase, sizeof( szFileBase ) );
LOAD_RESULT result = SetAnimationSource( nClassIndex, pszSourceFile );
if ( result != LOAD_OKAY )
{
@@ -7013,6 +7017,23 @@ CTFFileImportDialog::LOAD_RESULT CTFFileImportDialog::LoadTxt( const char *pszFi
V_ComposeFileName( pszBasePath, pszVCDFile, pszLoadPath, sizeof(pszLoadPath) );
pszVCDFile = pszLoadPath;
}
if ( !g_pFullFileSystem->FileExists( pszVCDFile, "MOD" ) )
{
const char *pszTempVCDFile = pszVCDFile;
// If the file isn't found using the path in the manifest, let's look where we think it should be on disk.
// We're sometimes seeing absolute paths for the creator's hard drive in the manifest for the vcd_file.
char szFallbackTest[ MAX_PATH ];
V_sprintf_safe( szFallbackTest, "%sgame\\scenes\\%s\\player\\%s\\low\\%s.vcd", pszBasePath, GetWorkshopFolder(), kClassFolders[ nClassIndex ], szFileBase );
pszVCDFile = szFallbackTest;
if ( !g_pFullFileSystem->FileExists( pszVCDFile, "MOD" ) )
{
// Set it back to the original value and let it fail below.
pszVCDFile = pszTempVCDFile;
}
}
}
result = SetAnimationVCD( nClassIndex, pszVCDFile );
+3 -3
View File
@@ -768,10 +768,10 @@ void CNetGraphPanel::DrawTextFields( int graphvalue, int x, int y, int w, netban
g_pMatSystemSurface->DrawColoredText( font, x, y, GRAPH_RED, GRAPH_GREEN, GRAPH_BLUE, 255, "%s", sz );
Q_snprintf( sz, sizeof( sz ), "lerp: %5.1f ms", GetClientInterpAmount() * 1000.0f );
Q_snprintf( sz, sizeof( sz ), "lerp: %5.1f ms", ROUND_TO_TICKS( GetClientInterpAmount() ) * 1000.0f );
int interpcolor[ 3 ] = { (int)GRAPH_RED, (int)GRAPH_GREEN, (int)GRAPH_BLUE };
float flInterp = GetClientInterpAmount();
float flInterp = ROUND_TO_TICKS( GetClientInterpAmount() );
if ( flInterp > 0.001f )
{
// Server framerate is lower than interp can possibly deal with
@@ -782,7 +782,7 @@ void CNetGraphPanel::DrawTextFields( int graphvalue, int x, int y, int w, netban
interpcolor[ 2 ] = 31;
}
// flInterp is below recommended setting!!!
else if ( flInterp < ( 2.0f / cl_updaterate->GetFloat() ) )
else if ( flInterp < ROUND_TO_TICKS( 2.0f / cl_updaterate->GetFloat() ) )
{
interpcolor[ 0 ] = 255;
interpcolor[ 1 ] = 125;
+5 -1
View File
@@ -17,6 +17,10 @@
static int g_ActiveVoiceMenu = 0;
#if defined( TF_CLIENT_DLL )
extern ConVar tf_voice_command_suspension_mode;
#endif
void OpenVoiceMenu( int index )
{
// do not show the menu if the player is dead or is an observer
@@ -28,7 +32,7 @@ void OpenVoiceMenu( int index )
return;
#if defined ( TF_CLIENT_DLL )
if ( GTFGCClientSystem() && GTFGCClientSystem()->BHaveChatSuspensionInCurrentMatch() )
if ( GTFGCClientSystem() && GTFGCClientSystem()->BHaveChatSuspensionInCurrentMatch() && tf_voice_command_suspension_mode.GetInt() == 1 )
{
CBaseHudChat *pHUDChat = ( CBaseHudChat * ) GET_HUDELEMENT( CHudChat );
if ( pHUDChat )
+1
View File
@@ -40,6 +40,7 @@ public:
virtual Vector EyePosition( void );
virtual INextBot *MyNextBotPointer( void ) { return this; }
virtual bool IsNextBot(void) const { return true; }
// Event hooks into NextBot system ---------------------------------------
virtual int OnTakeDamage_Alive( const CTakeDamageInfo &info );
+6
View File
@@ -146,4 +146,10 @@ void CSkyCamera::Activate( )
}
}
#endif
// matches the behavior of fog controller
if ( GameRules()->IsOfficialMap() )
{
m_skyboxData.fog.radial = true;
}
}
+1 -1
View File
@@ -1257,7 +1257,7 @@ int CAI_AssaultBehavior::TranslateSchedule( int scheduleType )
break;
case SCHED_HOLD_RALLY_POINT:
if( HasCondition(COND_NO_PRIMARY_AMMO) | HasCondition(COND_LOW_PRIMARY_AMMO) )
if( HasCondition(COND_NO_PRIMARY_AMMO) || HasCondition(COND_LOW_PRIMARY_AMMO) )
{
return SCHED_RELOAD;
}
+1 -1
View File
@@ -70,7 +70,7 @@ public:
bool IsMarkSet()
{
return ( m_flMarkTolerance != (float)NO_MARK );
return ( m_flMarkTolerance != NO_MARK );
}
bool TargetMoved( CBaseEntity *pEntity )
+1
View File
@@ -279,6 +279,7 @@ IMPLEMENT_SERVERCLASS_ST_NOBASE( CBaseEntity, DT_BaseEntity )
SendPropInt (SENDINFO(m_clrRender), 32, SPROP_UNSIGNED),
SendPropInt (SENDINFO(m_iTeamNum), TEAMNUM_NUM_BITS, 0),
SendPropInt (SENDINFO(m_CollisionGroup), 5, SPROP_UNSIGNED),
SendPropFloat (SENDINFO(m_flGravity)),
SendPropFloat (SENDINFO(m_flElasticity), 0, SPROP_COORD),
SendPropFloat (SENDINFO(m_flShadowCastDistance), 12, SPROP_UNSIGNED ),
SendPropEHandle (SENDINFO(m_hOwnerEntity)),
+4 -1
View File
@@ -996,6 +996,9 @@ public:
void TraceBleed( float flDamage, const Vector &vecDir, trace_t *ptr, int bitsDamageType );
virtual bool IsTriggered( CBaseEntity *pActivator ) {return true;}
virtual bool IsNPC( void ) const { return false; }
#ifdef NEXT_BOT
virtual bool IsNextBot(void) const { return false; }
#endif
CAI_BaseNPC *MyNPCPointer( void );
virtual CBaseCombatCharacter *MyCombatCharacterPointer( void ) { return NULL; }
virtual INextBot *MyNextBotPointer( void ) { return NULL; }
@@ -1872,7 +1875,7 @@ private:
EHANDLE m_pBlocker;
// was pev->gravity;
float m_flGravity; // rename to m_flGravityScale;
CNetworkVar( float, m_flGravity ); // rename to m_flGravityScale;
// was pev->friction
CNetworkVarForDerived( float, m_flFriction );
CNetworkVar( float, m_flElasticity );
+1 -1
View File
@@ -1885,7 +1885,7 @@ int CNPC_Combine::SelectFailSchedule( int failedSchedule, int failedTask, AI_Tas
{
// This eases the effects of an unfortunate bug that usually plagues shotgunners. Since their rate of fire is low,
// they spend relatively long periods of time without an attack squad slot. If you corner a shotgunner, usually
// the other memebers of the squad will hog all of the attack slots and pick schedules to move to establish line of
// the other members of the squad will hog all of the attack slots and pick schedules to move to establish line of
// fire. During this time, the shotgunner is prevented from attacking. If he also cannot find cover (the fallback case)
// he will stand around like an idiot, right in front of you. Instead of this, we have him run up to you for a melee attack.
return SCHED_COMBINE_MOVE_TO_MELEE;
+1 -1
View File
@@ -190,7 +190,7 @@ float CHL2MPBotSquad::GetSlowestMemberIdealSpeed( bool includeLeader ) const
//----------------------------------------------------------------------
// Return the maximum formation error of the squad's memebers.
// Return the maximum formation error of the squad's members.
float CHL2MPBotSquad::GetMaxSquadFormationError( void ) const
{
float maxError = 0.0f;
+4 -2
View File
@@ -145,9 +145,11 @@ CBaseEntity *CreateInfoCameraLink( CBaseEntity *pTarget, CPointCamera *pCamera )
//-----------------------------------------------------------------------------
void PointCameraSetupVisibility( CBaseEntity *pPlayer, int area, unsigned char *pvs, int pvssize )
{
int nPlayerIndex = pPlayer->entindex();
for ( CPointCamera *pCameraEnt = GetPointCameraList(); pCameraEnt != NULL; pCameraEnt = pCameraEnt->m_pNext )
{
pCameraEnt->SetActive( false );
pCameraEnt->TransmitToPlayer( nPlayerIndex, false );
}
intp nNext;
@@ -175,7 +177,7 @@ void PointCameraSetupVisibility( CBaseEntity *pPlayer, int area, unsigned char *
if ( pCameraEnt )
{
engine->AddOriginToPVS( pCameraEnt->GetAbsOrigin() );
pCameraEnt->SetActive( true );
pCameraEnt->TransmitToPlayer( nPlayerIndex, true );
}
}
}
+3 -10
View File
@@ -95,9 +95,9 @@ ConVar spec_freeze_traveltime( "spec_freeze_traveltime", "0.4", FCVAR_CHEAT | FC
ConVar sv_bonus_challenge( "sv_bonus_challenge", "0", FCVAR_REPLICATED, "Set to values other than 0 to select a bonus map challenge type." );
ConVar sv_chat_bucket_size_tier1( "sv_chat_bucket_size_tier1", "4", FCVAR_NONE, "The maxmimum size of the short term chat msg bucket." );
ConVar sv_chat_bucket_size_tier1( "sv_chat_bucket_size_tier1", "4", FCVAR_NONE, "The maximum size of the short term chat msg bucket." );
ConVar sv_chat_seconds_per_msg_tier1( "sv_chat_seconds_per_msg_tier1", "3", FCVAR_NONE, "The number of seconds to accrue an additional short term chat msg." );
ConVar sv_chat_bucket_size_tier2( "sv_chat_bucket_size_tier2", "30", FCVAR_NONE, "The maxmimum size of the long term chat msg bucket." );
ConVar sv_chat_bucket_size_tier2( "sv_chat_bucket_size_tier2", "30", FCVAR_NONE, "The maximum size of the long term chat msg bucket." );
ConVar sv_chat_seconds_per_msg_tier2( "sv_chat_seconds_per_msg_tier2", "10", FCVAR_NONE, "The number of seconds to accrue an additional long term chat msg." );
static ConVar sv_maxusrcmdprocessticks( "sv_maxusrcmdprocessticks", "24", FCVAR_NOTIFY, "Maximum number of client-issued usrcmd ticks that can be replayed in packet loss conditions, 0 to allow no restrictions" );
@@ -8102,13 +8102,6 @@ void CMovementSpeedMod::InputSpeedMod(inputdata_t &data)
}
void SendProxy_CropFlagsToPlayerFlagBitsLength( const SendProp *pProp, const void *pStruct, const void *pVarData, DVariant *pOut, int iElement, int objectID)
{
int mask = (1<<PLAYER_FLAG_BITS) - 1;
int data = *(int *)pVarData;
pOut->m_Int = ( data & mask );
}
// -------------------------------------------------------------------------------- //
// SendTable for CPlayerState.
// -------------------------------------------------------------------------------- //
@@ -8187,7 +8180,7 @@ void SendProxy_CropFlagsToPlayerFlagBitsLength( const SendProp *pProp, const voi
SendPropInt (SENDINFO(m_iBonusProgress), 15 ),
SendPropInt (SENDINFO(m_iBonusChallenge), 4 ),
SendPropFloat (SENDINFO(m_flMaxspeed), 12, SPROP_ROUNDDOWN, 0.0f, 2048.0f ), // CL
SendPropInt (SENDINFO(m_fFlags), PLAYER_FLAG_BITS, SPROP_UNSIGNED|SPROP_CHANGES_OFTEN, SendProxy_CropFlagsToPlayerFlagBitsLength ),
SendPropInt (SENDINFO(m_fFlags), 0, SPROP_UNSIGNED|SPROP_CHANGES_OFTEN ),
SendPropInt (SENDINFO(m_iObserverMode), 3, SPROP_UNSIGNED ),
SendPropEHandle (SENDINFO(m_hObserverTarget) ),
SendPropInt (SENDINFO(m_iFOV), 8, SPROP_UNSIGNED ),
+26 -14
View File
@@ -52,6 +52,9 @@ CPointCamera::CPointCamera()
m_bFogEnable = false;
m_bFogRadial = false;
// By default, transmit to everyone
m_bitsTransmitPlayers.SetAll();
g_PointCameraList.Insert( this );
}
@@ -74,34 +77,43 @@ void CPointCamera::Spawn( void )
SetActive( m_bIsOn );
}
//-----------------------------------------------------------------------------
// Purpose: Transmit only to players who are in PVS of the camera and its link
// See PointCameraSetupVisibility
//-----------------------------------------------------------------------------
int CPointCamera::ShouldTransmit( const CCheckTransmitInfo *pInfo )
{
if ( m_bitsTransmitPlayers.IsBitSet( pInfo->m_pClientEnt->m_EdictIndex ) )
return FL_EDICT_ALWAYS;
return FL_EDICT_DONTSEND;
}
//-----------------------------------------------------------------------------
// Purpose: Override ShouldTransmit since we want to be sent even though we don't have a model, etc.
// All that matters is if we are in the pvs.
//-----------------------------------------------------------------------------
int CPointCamera::UpdateTransmitState()
{
if ( m_bActive )
{
return SetTransmitState( FL_EDICT_ALWAYS );
}
else
{
return SetTransmitState( FL_EDICT_DONTSEND );
}
return SetTransmitState( FL_EDICT_FULLCHECK );
}
//-----------------------------------------------------------------------------
// Purpose: Toggle networking of the camera to the specified player
//-----------------------------------------------------------------------------
void CPointCamera::TransmitToPlayer( int nPlayerIndex, bool bTransmit )
{
if ( bTransmit )
m_bitsTransmitPlayers.Set( nPlayerIndex );
else
m_bitsTransmitPlayers.Clear( nPlayerIndex );
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CPointCamera::SetActive( bool bActive )
{
// If the mapmaker's told the camera it's off, it enforces inactive state
if ( !m_bIsOn )
{
bActive = false;
}
if ( m_bActive != bActive )
{
m_bActive = bActive;
+5 -1
View File
@@ -29,7 +29,9 @@ public:
// Tell the client that this camera needs to be rendered
void SetActive( bool bActive );
int UpdateTransmitState(void);
int ShouldTransmit( const CCheckTransmitInfo *pInfo );
int UpdateTransmitState( void );
void TransmitToPlayer( int nPlayerIndex, bool bTransmit );
void ChangeFOVThink( void );
@@ -56,6 +58,8 @@ private:
// Allows the mapmaker to control whether a camera is active or not
bool m_bIsOn;
CBitVec< MAX_PLAYERS > m_bitsTransmitPlayers;
public:
CPointCamera *m_pNext;
};
+1 -1
View File
@@ -523,7 +523,7 @@ void CSlideshowDisplay::BuildSlideShowImagesList( void )
char szFullFileName[_MAX_PATH];
Q_snprintf( szFullFileName, sizeof( szFullFileName ), "materials/vgui/%s/%s", m_szSlideshowDirectory.Get(), szMatFileName );
KeyValues *pMaterialKeys = new KeyValues( "material" );
KeyValuesAD pMaterialKeys( "material" );
bool bLoaded = pMaterialKeys->LoadFromFile( g_pFullFileSystem, szFullFileName, NULL );
if ( bLoaded )
+1 -6
View File
@@ -336,11 +336,6 @@ void CTeamControlPoint::InputSetOwner( inputdata_t &input )
Assert( iCapTeam >= 0 && iCapTeam < GetNumberOfTeams() );
Assert( input.pCaller );
if ( !input.pCaller )
return;
if ( GetOwner() == iCapTeam )
return;
@@ -349,7 +344,7 @@ void CTeamControlPoint::InputSetOwner( inputdata_t &input )
// must be done before setting the owner
HandleScoring( iCapTeam );
if ( input.pCaller->IsPlayer() )
if ( input.pCaller && input.pCaller->IsPlayer() )
{
int iCappingPlayer = input.pCaller->entindex();
InternalSetOwner( iCapTeam, true, 1, &iCappingPlayer );
@@ -1156,6 +1156,9 @@ int CTeamControlPointMaster::GetNumPointsOwnedByTeam( int iTeam )
//-----------------------------------------------------------------------------
int CTeamControlPointMaster::CalcNumRoundsRemaining( int iTeam )
{
if ( m_ControlPointRounds.IsEmpty() )
return 0;
// To determine how many rounds remain for a given team if it consistently wins mini-rounds, we have to
// simulate forward each mini-round and track the control point ownership that would result
@@ -29,7 +29,8 @@ ActionResult< CTFBot > CTFBotEngineerBuildTeleportEntrance::OnStart( CTFBot *me,
ActionResult< CTFBot > CTFBotEngineerBuildTeleportEntrance::Update( CTFBot *me, float interval )
{
CTeamControlPoint *point = me->GetMyControlPoint();
if ( !point )
CCaptureZone *zone = me->GetFlagCaptureZone();
if ( !point && !zone )
{
// wait until a control point becomes available
return Continue();
@@ -64,7 +65,14 @@ ActionResult< CTFBot > CTFBotEngineerBuildTeleportEntrance::Update( CTFBot *me,
if ( !m_path.IsValid() )
{
CTFBotPathCost cost( me, FASTEST_ROUTE );
m_path.Compute( me, point->GetAbsOrigin(), cost );
if ( point )
{
m_path.Compute( me, point->GetAbsOrigin(), cost );
}
else if ( zone )
{
m_path.Compute( me, zone->WorldSpaceCenter(), cost );
}
}
m_path.Update( me );
@@ -243,7 +243,7 @@ ActionResult< CTFBot > CTFBotDeliverFlag::Update( CTFBot *me, float interval )
m_flTotalTravelDistance = NavAreaTravelDistance( me->GetLastKnownArea(), TheNavMesh->GetNavArea( zone->WorldSpaceCenter() ), cost );
if ( flOldTravelDistance != -1.0f && m_flTotalTravelDistance - flOldTravelDistance > 2000.0f )
if ( TFGameRules()->IsMannVsMachineMode() && flOldTravelDistance != -1.0f && m_flTotalTravelDistance - flOldTravelDistance > 2000.0f )
{
TFGameRules()->BroadcastSound( 255, "Announcer.MVM_Bomb_Reset" );
@@ -70,7 +70,14 @@ ActionResult< CTFBot > CTFBotSpyHide::Update( CTFBot *me, float interval )
if ( m_talkTimer.IsElapsed() )
{
m_talkTimer.Start( RandomFloat( 5.0f, 10.0f ) );
me->EmitSound( "Spy.TeaseVictim" );
if ( TFGameRules()->IsMannVsMachineMode() && me->GetTeamNumber() == TF_TEAM_PVE_INVADERS )
{
me->EmitSound( "Spy.MVM_TeaseVictim" );
}
else
{
me->EmitSound( "Spy.TeaseVictim" );
}
}
if ( m_isAtGoal )
+6 -6
View File
@@ -704,9 +704,9 @@ DEFINE_SCRIPTFUNC( IsOnAnyMission, "Return true if this bot has a current missio
DEFINE_SCRIPTFUNC_WRAPPED( SetMissionTarget, "Set this bot's mission target to the given entity" )
DEFINE_SCRIPTFUNC_WRAPPED( GetMissionTarget, "Get this bot's current mission target" )
DEFINE_SCRIPTFUNC( SetBehaviorFlag, "Set the given behavior flag(s) for this bot" )
DEFINE_SCRIPTFUNC( ClearBehaviorFlag, "Clear the given behavior flag(s) for this bot" )
DEFINE_SCRIPTFUNC( IsBehaviorFlagSet, "Return true if the given behavior flag(s) are set for this bot" )
DEFINE_SCRIPTFUNC_WRAPPED( SetBehaviorFlag, "Set the given behavior flag(s) for this bot" )
DEFINE_SCRIPTFUNC_WRAPPED( ClearBehaviorFlag, "Clear the given behavior flag(s) for this bot" )
DEFINE_SCRIPTFUNC_WRAPPED( IsBehaviorFlagSet, "Return true if the given behavior flag(s) are set for this bot" )
DEFINE_SCRIPTFUNC_WRAPPED( SetActionPoint, "Set the given action point for this bot" )
DEFINE_SCRIPTFUNC_WRAPPED( GetActionPoint, "Get the given action point for this bot" )
@@ -4597,15 +4597,15 @@ Action< CTFBot > *CTFBot::OpportunisticallyUseWeaponAbilities( void )
}
}
}
else if ( weapon->GetWeaponID() == TF_WEAPON_BAT_WOOD )
else if ( ( weapon->GetWeaponID() == TF_WEAPON_BAT_WOOD ) || ( weapon->GetWeaponID() == TF_WEAPON_BAT_GIFTWRAP ) )
{
// sandman
// sandman or wrap assassin
if ( GetAmmoCount( TF_AMMO_GRENADES1 ) > 0 )
{
const CKnownEntity *threat = GetVisionInterface()->GetPrimaryKnownThreat();
if ( threat && threat->IsVisibleInFOVNow() )
{
// hit a stunball
// hit a stunball or bauble
PressAltFireButton();
}
}
+8 -5
View File
@@ -331,6 +331,9 @@ public:
void SetBehaviorFlag( unsigned int flags );
void ClearBehaviorFlag( unsigned int flags );
bool IsBehaviorFlagSet( unsigned int flags ) const;
void ScriptSetBehaviorFlag( int flags ) { this->SetBehaviorFlag( (unsigned int)flags ); }
void ScriptClearBehaviorFlag( int flags ) { this->ClearBehaviorFlag( (unsigned int)flags ); }
bool ScriptIsBehaviorFlagSet( int flags ) const { return this->IsBehaviorFlagSet( (unsigned int)flags ); }
bool FindSplashTarget( CBaseEntity *target, float maxSplashRadius, Vector *splashTarget ) const;
@@ -358,11 +361,11 @@ public:
CBaseEntity *GetMissionTarget( void ) const;
void SetMissionString( CUtlString string );
CUtlString *GetMissionString( void );
void ScriptSetMission( unsigned int mission, bool resetBehaviorSystem = true ) { this->SetMission( (MissionType)mission, resetBehaviorSystem ); }
void ScriptSetPrevMission( unsigned int mission ) { this->SetPrevMission( (MissionType)mission ); }
unsigned int ScriptGetMission( void ) const { return (unsigned int)this->GetMission(); }
unsigned int ScriptGetPrevMission( void ) const { return (unsigned int)this->GetPrevMission(); }
bool ScriptHasMission( unsigned int mission ) const { return this->HasMission( (MissionType)mission ); }
void ScriptSetMission( int mission, bool resetBehaviorSystem = true ) { this->SetMission( (MissionType)mission, resetBehaviorSystem ); }
void ScriptSetPrevMission( int mission ) { this->SetPrevMission( (MissionType)mission ); }
int ScriptGetMission( void ) const { return (int)this->GetMission(); }
int ScriptGetPrevMission( void ) const { return (int)this->GetPrevMission(); }
bool ScriptHasMission( int mission ) const { return this->HasMission( (MissionType)mission ); }
void ScriptSetMissionTarget( HSCRIPT hTarget ) { this->SetMissionTarget( ToEnt( hTarget ) ); }
HSCRIPT ScriptGetMissionTarget( void ) const { return ToHScript( this->GetMissionTarget() ); }
+1 -1
View File
@@ -202,7 +202,7 @@ float CTFBotSquad::GetSlowestMemberIdealSpeed( bool includeLeader ) const
//----------------------------------------------------------------------
// Return the maximum formation error of the squad's memebers.
// Return the maximum formation error of the squad's members.
float CTFBotSquad::GetMaxSquadFormationError( void ) const
{
float maxError = 0.0f;
+1 -3
View File
@@ -88,7 +88,7 @@ void CEntityBird::SpawnRandomBirds( void )
if ( !pszMapName || !pszMapName[0] )
return;
KeyValues *pFileKV = new KeyValues( "birds" );
KeyValuesAD pFileKV( "birds" );
if ( !pFileKV->LoadFromFile( g_pFullFileSystem, "scripts/birds.txt", "MOD" ) )
return;
@@ -139,8 +139,6 @@ void CEntityBird::SpawnRandomBirds( void )
}
}
}
pFileKV->deleteThis();
}
+16
View File
@@ -17,6 +17,7 @@
#include "particle_parse.h"
#include "player_vs_environment/tf_population_manager.h"
#include "collisionutils.h"
#include "func_respawnroom.h"
#include "tf_objective_resource.h"
//=============================================================================
@@ -209,6 +210,21 @@ void CCurrencyPack::ComeToRest( void )
}
}
}
// Or a func_respawnroom (robots can drop money in their own spawn)
for ( int i = 0; i < IFuncRespawnRoomAutoList::AutoList().Count(); i++ )
{
CFuncRespawnRoom *pRespawnRoom = static_cast<CFuncRespawnRoom *>( IFuncRespawnRoomAutoList::AutoList()[ i ] );
Vector vecMins, vecMaxs;
pRespawnRoom->GetCollideable()->WorldSpaceSurroundingBounds( &vecMins, &vecMaxs );
if ( IsPointInBox( GetCollideable()->GetCollisionOrigin(), vecMins, vecMaxs ) )
{
TFGameRules()->DistributeCurrencyAmount( m_nAmount );
m_bTouched = true;
UTIL_Remove( this );
}
}
}
//-----------------------------------------------------------------------------
+1 -1
View File
@@ -304,5 +304,5 @@ bool CHealthAmmoKit::MyTouch( CBasePlayer *pPlayer )
}
}
return bAmmoSuccess | bHealthSuccess;
return bAmmoSuccess || bHealthSuccess;
}
@@ -2626,7 +2626,7 @@ void CPopulationManager::AllocateBots()
Warning( "%d bots were already allocated some how before CPopulationManager::AllocateBots was called\n", botVector.Count() );
}
for ( int i = nNumEnemyBots; i < MVM_INVADERS_TEAM_SIZE; ++i )
for ( int i = nNumEnemyBots; i < tf_mvm_max_invaders.GetInt(); ++i )
{
CTFBot* newBot = NextBotCreatePlayerBot< CTFBot >( "TFBot", false );
if ( newBot )
@@ -137,8 +137,6 @@ public:
bool IsBonusRound() const { return m_bBonusRound; }
CBaseCombatCharacter* GetBonusBoss() const { return m_hBonusBoss; }
enum { MVM_INVADERS_TEAM_SIZE = 22 };
static bool GetWavesUseReadyBetween() { return true; }
void SetDefaultEventChangeAttributesName( const char* pszDefaultEventChangeAttributesName ) { m_defaultEventChangeAttributesName = pszDefaultEventChangeAttributesName; }
@@ -1014,7 +1014,7 @@ bool CTFBotSpawner::Spawn( const Vector &rawHere, EntityHandleVector_t *result )
nNumEnemyBots = botVector.Count();
if ( nNumEnemyBots >= CPopulationManager::MVM_INVADERS_TEAM_SIZE )
if ( nNumEnemyBots >= tf_mvm_max_invaders.GetInt() )
{
// no room for more
if ( tf_populator_debug.GetBool() )
@@ -1023,10 +1023,10 @@ bool CTFBotSpawner::Spawn( const Vector &rawHere, EntityHandleVector_t *result )
}
// extra guard if we're over full on bots
if ( nNumEnemyBots > CPopulationManager::MVM_INVADERS_TEAM_SIZE )
if ( nNumEnemyBots > tf_mvm_max_invaders.GetInt() )
{
// Kick bots until we are at the proper number starting with spectator bots
int iNumberToKick = nNumEnemyBots - CPopulationManager::MVM_INVADERS_TEAM_SIZE;
int iNumberToKick = nNumEnemyBots - tf_mvm_max_invaders.GetInt();
int iKickedBots = 0;
// loop through spectators and invaders in that order
@@ -741,7 +741,7 @@ bool CMissionPopulator::UpdateMission( CTFBot::MissionType mission )
// are there enough free slots?
int currentEnemyCount = GetGlobalTeam( TF_TEAM_PVE_INVADERS )->GetNumPlayers();
if ( currentEnemyCount + m_desiredCount > CPopulationManager::MVM_INVADERS_TEAM_SIZE )
if ( currentEnemyCount + m_desiredCount > tf_mvm_max_invaders.GetInt() )
{
// not enough slots yet
if ( tf_populator_debug.GetBool() )
@@ -1578,7 +1578,7 @@ void CWaveSpawnPopulator::Update( void )
int currentEnemyCount = GetGlobalTeam( TF_TEAM_PVE_INVADERS )->GetNumPlayers();
if ( currentEnemyCount + m_spawnCount + m_reservedPlayerSlotCount > CPopulationManager::MVM_INVADERS_TEAM_SIZE )
if ( currentEnemyCount + m_spawnCount + m_reservedPlayerSlotCount > tf_mvm_max_invaders.GetInt() )
{
// no space right now
return;
+1
View File
@@ -1367,6 +1367,7 @@ bool CObjectSentrygun::FireRocket()
// Setup next rocket shot
if ( m_bPlayerControlled )
{
AddGesture( ACT_RANGE_ATTACK2, 2.25, true );
m_flNextRocketAttack = gpGlobals->curtime + 2.25;
}
else
+6
View File
@@ -1166,6 +1166,12 @@ void CObjectTeleporter::TeleporterThink( void )
SetState( TELEPORTER_STATE_RECHARGING );
m_flCurrentRechargeDuration = (float)g_iTeleporterRechargeTimes[GetUpgradeLevel()];
if ( !m_bWasMapPlaced )
{
CALL_ATTRIB_HOOK_FLOAT_ON_OTHER( GetBuilder(), m_flCurrentRechargeDuration, mult_teleporter_recharge_rate );
}
m_flRechargeTime = gpGlobals->curtime + m_flCurrentRechargeDuration;
m_flMyNextThink = gpGlobals->curtime + m_flCurrentRechargeDuration;
}
break;
+4 -1
View File
@@ -1853,11 +1853,14 @@ bool CTFPasstimeLogic::ParseSetSection( const char *pStr, SetSectionParams &s )
{
char pszStartName[64];
char pszEndName[64];
const int iScanCount = sscanf( pStr, "%i %s %s", &s.num, pszStartName, pszEndName ); // WHAT YEAR IS IT
const int iScanCount = sscanf( pStr, "%i %63s %63s", &s.num, pszStartName, pszEndName ); // WHAT YEAR IS IT
if ( iScanCount != 3 )
{
return false;
}
pszStartName[ ARRAYSIZE( pszStartName ) - 1 ] = '\0';
pszEndName[ ARRAYSIZE( pszEndName ) - 1 ] = '\0';
s.pSectionStart = dynamic_cast<CPathTrack*>( gEntList.FindEntityByName( 0, pszStartName ) );
s.pSectionEnd = dynamic_cast<CPathTrack*>( gEntList.FindEntityByName( 0, pszEndName ) );
+100 -80
View File
@@ -126,7 +126,6 @@
#include "tf_revive.h"
#include "tf_logic_halloween_2014.h"
#include "tf_logic_player_destruction.h"
#include "tf_weapon_rocketpack.h"
#include "tf_weapon_slap.h"
#include "func_croc.h"
#include "tf_weapon_bonesaw.h"
@@ -278,6 +277,7 @@ extern ConVar sv_vote_allow_spectators;
ConVar sv_vote_late_join_time( "sv_vote_late_join_time", "90", FCVAR_NONE, "Grace period after the match starts before players who join the match receive a vote-creation cooldown" );
ConVar sv_vote_late_join_cooldown( "sv_vote_late_join_cooldown", "300", FCVAR_NONE, "Length of the vote-creation cooldown when joining the server after the grace period has expired" );
extern ConVar tf_voice_command_suspension_mode;
extern ConVar tf_feign_death_duration;
extern ConVar spec_freeze_time;
extern ConVar spec_freeze_traveltime;
@@ -815,6 +815,7 @@ IMPLEMENT_SERVERCLASS_ST( CTFPlayer, DT_TFPlayer )
SendPropFloat( SENDINFO( m_flMvMLastDamageTime ), 16, SPROP_ROUNDUP ),
SendPropInt( SENDINFO( m_iSpawnCounter ) ),
SendPropBool( SENDINFO( m_bFlipViewModels ) ),
SendPropBool( SENDINFO( m_bArenaSpectator ) ),
SendPropFloat( SENDINFO( m_flHeadScale ) ),
SendPropFloat( SENDINFO( m_flTorsoScale ) ),
@@ -843,6 +844,7 @@ IMPLEMENT_SERVERCLASS_ST( CTFPlayer, DT_TFPlayer )
SendPropInt( SENDINFO( m_iPlayerSkinOverride ) ),
SendPropBool( SENDINFO( m_bViewingCYOAPDA ) ),
SendPropBool( SENDINFO( m_bRegenerating ) ),
SendPropEHandle( SENDINFO( m_hOffHandWeapon ) ),
END_SEND_TABLE()
// -------------------------------------------------------------------------------- //
@@ -997,7 +999,6 @@ CTFPlayer::CTFPlayer()
m_flNextChangeClassTime = 0.0f;
m_flNextChangeTeamTime = 0.0f;
m_bScattergunJump = false;
m_iOldStunFlags = 0;
m_iLastWeaponSlot = 1;
m_iNumberofDominations = 0;
@@ -1453,35 +1454,6 @@ void CTFPlayer::TFPlayerThink()
else
{
m_iLeftGroundHealth = -1;
if ( GetFlags() & FL_ONGROUND )
{
// Airborne conditions end on ground contact
m_Shared.RemoveCond( TF_COND_KNOCKED_INTO_AIR );
m_Shared.RemoveCond( TF_COND_AIR_CURRENT );
if ( m_Shared.InCond( TF_COND_ROCKETPACK ) )
{
// Make sure we're still not dealing with launch, where it's possible
// to hit your head and fall to the ground before the second stage.
CTFWeaponBase *pRocketPack = Weapon_OwnsThisID( TF_WEAPON_ROCKETPACK );
if ( pRocketPack )
{
if ( gpGlobals->curtime > ( static_cast< CTFRocketPack* >( pRocketPack )->GetRefireTime() ) )
{
EmitSound( "Weapon_RocketPack.BoostersShutdown" );
EmitSound( "Weapon_RocketPack.Land" );
m_Shared.RemoveCond( TF_COND_ROCKETPACK );
IGameEvent *pEvent = gameeventmanager->CreateEvent( "rocketpack_landed" );
if ( pEvent )
{
pEvent->SetInt( "userid", GetUserID() );
gameeventmanager->FireEvent( pEvent );
}
}
}
}
}
if ( m_iBlastJumpState )
{
@@ -2833,6 +2805,7 @@ void CTFPlayer::PrecacheMvM()
PrecacheScriptSound( "MVM.DeployBombGiant" );
PrecacheScriptSound( "Weapon_Upgrade.ExplosiveHeadshot" );
PrecacheScriptSound( "Spy.MVM_Chuckle" );
PrecacheScriptSound( "Spy.MVM_TeaseVictim" );
PrecacheScriptSound( "MVM.Robot_Engineer_Spawn" );
PrecacheScriptSound( "MVM.Robot_Teleporter_Deliver" );
PrecacheScriptSound( "MVM.MoneyPickup" );
@@ -3781,7 +3754,6 @@ void CTFPlayer::Spawn()
m_Shared.SetFeignDeathReady( false );
m_bScattergunJump = false;
m_iOldStunFlags = 0;
m_flAccumulatedHealthRegen = 0;
@@ -5979,8 +5951,9 @@ void CTFPlayer::HandleAnimEvent( animevent_t *pEvent )
char szAttrName[128];
float flVal;
float flDuration;
if ( sscanf( pEvent->options, "%s %f %f", szAttrName, &flVal, &flDuration ) == 3 )
if ( sscanf( pEvent->options, "%127s %f %f", szAttrName, &flVal, &flDuration ) == 3 )
{
szAttrName[ ARRAYSIZE( szAttrName ) - 1 ] = '\0';
Assert( flDuration > 0.f );
AddCustomAttribute( szAttrName, flVal, flDuration );
}
@@ -6898,20 +6871,29 @@ void CTFPlayer::HandleCommand_JoinClass( const char *pClassName, bool bAllowSpaw
}
else
{
int iTries = 20;
// The player has selected Random class...so let's pick one for them.
do{
// Don't let them be the same class twice in a row
iClass = random->RandomInt( TF_FIRST_NORMAL_CLASS, TF_LAST_NORMAL_CLASS - 1 ); // -1 to remove the civilian from the randomness
iTries--;
} while( iClass == GetPlayerClass()->GetClassIndex() || (iTries > 0 && !TFGameRules()->CanPlayerChooseClass(this,iClass)) );
int iChoices = 0;
int iClasses[ TF_LAST_NORMAL_CLASS - 1 ] = {}; // -1 to remove the civilian from the randomness
int iCurrentClass = GetPlayerClass()->GetClassIndex();
if ( iTries <= 0 )
for ( iClass = TF_FIRST_NORMAL_CLASS; iClass < TF_LAST_NORMAL_CLASS; iClass++ )
{
if ( iClass != iCurrentClass && TFGameRules()->CanPlayerChooseClass( this, iClass ) )
{
iClasses[ iChoices++ ] = iClass;
}
}
if ( !iChoices )
{
if ( TFGameRules()->CanPlayerChooseClass( this, iCurrentClass ) )
return;
// We failed to find a random class. Bring up the class menu again.
ShowViewPortPanel( ( GetTeamNumber() == TF_TEAM_RED ) ? PANEL_CLASS_RED : PANEL_CLASS_BLUE );
return;
}
iClass = iClasses[ random->RandomInt( 0, iChoices - 1 ) ];
}
if ( TFGameRules() && TFGameRules()->State_Get() == GR_STATE_RND_RUNNING )
@@ -7362,7 +7344,7 @@ bool CTFPlayer::ClientCommand( const CCommand &args )
if ( FStrEq( pcmd, "jointeam" ) )
{
// don't let them spam the server with changes
if ( GetNextChangeTeamTime() > gpGlobals->curtime )
if ( ( GetNextChangeTeamTime() > gpGlobals->curtime ) && ( GetTeamNumber() != TEAM_UNASSIGNED ) )
return true;
SetNextChangeTeamTime( gpGlobals->curtime + 2.0f ); // limit to one change every 2 secs
@@ -9127,44 +9109,40 @@ int CTFPlayer::OnTakeDamage( const CTakeDamageInfo &inputInfo )
}
}
if ( pTFAttacker && pTFAttacker->IsPlayerClass( TF_CLASS_MEDIC ) )
if ( pTFAttacker && pTFAttacker->IsPlayerClass( TF_CLASS_MEDIC ) && pWeapon && pWeapon->GetWeaponID() == TF_WEAPON_BONESAW )
{
CTFWeaponBase *pAttackerWeapon = pTFAttacker->GetActiveTFWeapon();
if ( pAttackerWeapon && pAttackerWeapon->GetWeaponID() == TF_WEAPON_BONESAW )
CTFBonesaw *pBoneSaw = static_cast< CTFBonesaw* >( pWeapon );
if ( pBoneSaw->GetBonesawType() == BONESAW_UBER_SAVEDONDEATH )
{
CTFBonesaw *pBoneSaw = static_cast< CTFBonesaw* >( pAttackerWeapon );
if ( pBoneSaw->GetBonesawType() == BONESAW_UBER_SAVEDONDEATH )
// Spawn their spleen
CPhysicsProp *pRandomInternalOrgan = dynamic_cast< CPhysicsProp* >( CreateEntityByName( "prop_physics_override" ) );
if ( pRandomInternalOrgan )
{
// Spawn their spleen
CPhysicsProp *pRandomInternalOrgan = dynamic_cast< CPhysicsProp* >( CreateEntityByName( "prop_physics_override" ) );
if ( pRandomInternalOrgan )
{
pRandomInternalOrgan->SetCollisionGroup( COLLISION_GROUP_DEBRIS );
pRandomInternalOrgan->AddFlag( FL_GRENADE );
char buf[512];
Q_snprintf( buf, sizeof( buf ), "%.10f %.10f %.10f", GetAbsOrigin().x, GetAbsOrigin().y, GetAbsOrigin().z );
pRandomInternalOrgan->KeyValue( "origin", buf );
Q_snprintf( buf, sizeof( buf ), "%.10f %.10f %.10f", GetAbsAngles().x, GetAbsAngles().y, GetAbsAngles().z );
pRandomInternalOrgan->KeyValue( "angles", buf );
pRandomInternalOrgan->KeyValue( "model", "models/player/gibs/random_organ.mdl" );
pRandomInternalOrgan->KeyValue( "fademindist", "-1" );
pRandomInternalOrgan->KeyValue( "fademaxdist", "0" );
pRandomInternalOrgan->KeyValue( "fadescale", "1" );
pRandomInternalOrgan->KeyValue( "inertiaScale", "1.0" );
pRandomInternalOrgan->KeyValue( "physdamagescale", "0.1" );
DispatchSpawn( pRandomInternalOrgan );
pRandomInternalOrgan->m_takedamage = DAMAGE_YES; // Take damage, otherwise this can block trains
pRandomInternalOrgan->SetHealth( 100 );
pRandomInternalOrgan->Activate();
pRandomInternalOrgan->SetCollisionGroup( COLLISION_GROUP_DEBRIS );
pRandomInternalOrgan->AddFlag( FL_GRENADE );
char buf[512];
Q_snprintf( buf, sizeof( buf ), "%.10f %.10f %.10f", GetAbsOrigin().x, GetAbsOrigin().y, GetAbsOrigin().z );
pRandomInternalOrgan->KeyValue( "origin", buf );
Q_snprintf( buf, sizeof( buf ), "%.10f %.10f %.10f", GetAbsAngles().x, GetAbsAngles().y, GetAbsAngles().z );
pRandomInternalOrgan->KeyValue( "angles", buf );
pRandomInternalOrgan->KeyValue( "model", "models/player/gibs/random_organ.mdl" );
pRandomInternalOrgan->KeyValue( "fademindist", "-1" );
pRandomInternalOrgan->KeyValue( "fademaxdist", "0" );
pRandomInternalOrgan->KeyValue( "fadescale", "1" );
pRandomInternalOrgan->KeyValue( "inertiaScale", "1.0" );
pRandomInternalOrgan->KeyValue( "physdamagescale", "0.1" );
DispatchSpawn( pRandomInternalOrgan );
pRandomInternalOrgan->m_takedamage = DAMAGE_YES; // Take damage, otherwise this can block trains
pRandomInternalOrgan->SetHealth( 100 );
pRandomInternalOrgan->Activate();
Vector vecImpulse = RandomVector( -1.f, 1.f );
vecImpulse.z = 1.f;
VectorNormalize( vecImpulse );
Vector vecVelocity = vecImpulse * 250.0;
pRandomInternalOrgan->ApplyAbsVelocityImpulse( vecVelocity );
Vector vecImpulse = RandomVector( -1.f, 1.f );
vecImpulse.z = 1.f;
VectorNormalize( vecImpulse );
Vector vecVelocity = vecImpulse * 250.0;
pRandomInternalOrgan->ApplyAbsVelocityImpulse( vecVelocity );
pRandomInternalOrgan->ThinkSet( &CBaseEntity::SUB_Remove, gpGlobals->curtime + 5.f, "DieContext" );
}
pRandomInternalOrgan->ThinkSet( &CBaseEntity::SUB_Remove, gpGlobals->curtime + 5.f, "DieContext" );
}
}
}
@@ -14786,10 +14764,7 @@ void CTFPlayer::CheatImpulseCommands( int iImpulse )
pWeapon->GiveDefaultAmmo();
if ( pWeapon->IsEnergyWeapon() )
{
pWeapon->WeaponRegenerate();
}
pWeapon->WeaponRegenerate();
}
m_Shared.m_flRageMeter = 100.f;
@@ -19157,6 +19132,30 @@ void CTFPlayer::DoTauntAttack( void )
pLoser->TakeDamage( CTakeDamageInfo( pWinner, pWinner, NULL, 999, DMG_GENERIC, 0 ) );
}
}
else if ( iTauntAttack == TAUNTATK_ENGINEER_TRICKSHOT )
{
// Engineer "Texan Trickshot" attack
Vector vecForward;
AngleVectors( EyeAngles(), &vecForward );
Vector vecEnd = EyePosition() + vecForward * 500;
trace_t tr;
UTIL_TraceLine( EyePosition(), vecEnd, ( MASK_SOLID | CONTENTS_HITBOX ), this, COLLISION_GROUP_PLAYER, &tr );
// DebugDrawLine( EyePosition(), vecEnd, 0, 0, 255, true, 3.0f );
if ( tr.fraction < 1.0 )
{
CBaseEntity *pEnt = tr.m_pEnt;
if ( pEnt && pEnt->IsPlayer() && pEnt->GetTeamNumber() > LAST_SHARED_TEAM && pEnt->GetTeamNumber() != GetTeamNumber() )
{
// Launch them up a little
AngleVectors( QAngle( -45, m_angEyeAngles[ YAW ], 0 ), &vecForward );
pEnt->TakeDamage( CTakeDamageInfo( this, this, GetActiveTFWeapon(), vecForward * 25000, WorldSpaceCenter(), 500.0f, DMG_BULLET, TF_DMG_CUSTOM_TAUNTATK_TRICKSHOT ) );
}
}
}
// Particle Being played in VCD instead
//else if ( iTauntAttack == TAUNTATK_FLIP_LAND_PARTICLE )
//{
@@ -20028,7 +20027,20 @@ bool CTFPlayer::ShouldShowVoiceSubtitleToEnemy( void )
//-----------------------------------------------------------------------------
bool CTFPlayer::CanSpeakVoiceCommand( void )
{
return ( gpGlobals->curtime > m_flNextVoiceCommandTime );
if ( tf_voice_command_suspension_mode.GetInt() == 1 )
return false;
if ( gpGlobals->curtime <= m_flNextVoiceCommandTime )
return false;
// misyl: New F2P voice command rate-limiting path.
if ( BHaveChatSuspensionInCurrentMatch() && tf_voice_command_suspension_mode.GetInt() == 2 )
{
if ( !m_RateLimitedVoiceCommandTokenBucket.BTakeToken( gpGlobals->curtime ) )
return false;
}
return true;
}
//-----------------------------------------------------------------------------
@@ -21593,6 +21605,7 @@ static bool SelectPartnerTaunt( const GameItemDefinition_t *pItemDef, CTFPlayer
{
static CSchemaItemDefHandle pItemDef_rpsTaunt( "RPS Taunt" );
static CSchemaItemDefHandle pItemDef_TauntNeckSnap( "Taunt: Neck Snap" );
static CSchemaItemDefHandle pItemDef_TauntBearHug( "Taunt: Bear Hug" );
CTFTauntInfo *pTauntData = pItemDef->GetTauntData();
if ( !pTauntData )
@@ -21642,6 +21655,13 @@ static bool SelectPartnerTaunt( const GameItemDefinition_t *pItemDef, CTFPlayer
iInitiator = 0;
iReceiver = ( iReceiverClass != TF_CLASS_SOLDIER ) ? 0 : 1;
}
else if ( pItemDef == pItemDef_TauntBearHug )
{
Assert( iInitiatorSceneCount == 2 && iReceiverSceneCount > 0 );
iInitiator = 0;
iReceiver = ( iReceiverClass != TF_CLASS_HEAVYWEAPONS ) ? 0 : 1;
}
else
{
// randomly select a player to pick 0 (could be silent taunt)
+45 -2
View File
@@ -66,6 +66,46 @@ enum EAmmoSource
kAmmoSource_ResourceMeter, // it regenerated after a cooldown
};
extern ConVar tf_voice_command_suspension_rate_limit_bucket_count;
extern ConVar tf_voice_command_suspension_rate_limit_bucket_refill_rate;
class CVoiceCommandBucketSizer
{
public:
int GetBucketSize() const { return tf_voice_command_suspension_rate_limit_bucket_count.GetInt(); }
float GetBucketRefillRate() const { return tf_voice_command_suspension_rate_limit_bucket_refill_rate.GetFloat(); }
};
template <typename TBucketSizer>
class CRateLimitingTokenBucket : public TBucketSizer
{
public:
CRateLimitingTokenBucket()
: m_nBucket( this->GetBucketSize() )
{
}
bool BTakeToken( float flNow )
{
// misyl: This token bucket doesn't go negative, so you don't ever dig yourself into a hole by spamming.
// You might want that if you use this class, feel free to add something to the BucketSizer.
int nNewBucket = MIN( m_nBucket + ( flNow - m_flLastTokenTaken ) / this->GetBucketRefillRate(), this->GetBucketSize() ) - 1;
if ( nNewBucket <= 0 )
{
return false;
}
m_nBucket = nNewBucket;
m_flLastTokenTaken = flNow;
return true;
}
private:
float m_flLastTokenTaken = 0.0f;
int m_nBucket = 0;
};
//=============================================================================
//
// TF Player
@@ -483,6 +523,8 @@ public:
float m_flNextVoiceCommandTime;
int m_iVoiceSpamCounter;
CRateLimitingTokenBucket<CVoiceCommandBucketSizer> m_RateLimitedVoiceCommandTokenBucket;
float m_flNextSpeakWeaponFire;
virtual int CalculateTeamBalanceScore( void );
@@ -911,6 +953,8 @@ public:
CTFWeaponBase *Weapon_OwnsThisID( int iWeaponID ) const;
CTFWeaponBase *Weapon_GetWeaponByType( int iType );
virtual void PlayStepSound( Vector &vecOrigin, surfacedata_t *psurface, float fvol, bool force );
medigun_charge_types GetChargeEffectBeingProvided( void );
// Achievements
@@ -938,10 +982,9 @@ public:
bool m_bSuicideExplode;
bool m_bScattergunJump;
int m_iOldStunFlags;
bool m_bFlipViewModels;
CNetworkVar( bool, m_bFlipViewModels );
int m_iBlastJumpState;
float m_flBlastJumpLandTime;
bool m_bTakenBlastDamageSinceLastMovement;
+1 -1
View File
@@ -413,7 +413,7 @@ void CTFProjectile_Flare::Explode_Air( trace_t *pTrace, int bitsDamageType, bool
if ( bSelfOnly )
{
bitsDamageType |= DMG_BLAST;
nSound = SPECIAL2;
nSound = SPECIAL3;
}
CTakeDamageInfo info( this, pAttacker, m_hLauncher, vec3_origin, vecOrigin, GetDamage(), bitsDamageType | DMG_HALF_FALLOFF, TF_DMG_CUSTOM_FLARE_EXPLOSION );
+9 -1
View File
@@ -153,7 +153,15 @@ void CTFProjectile_Rocket::Deflected( CBaseEntity *pDeflectedBy, Vector &vecDir
ChangeTeam( pTFDeflector->GetTeamNumber() );
SetLauncher( pTFDeflector->GetActiveWeapon() );
CTFPlayer* pOldOwner = ToTFPlayer( GetOwnerEntity() );
CTFPlayer *pOldOwner = ToTFPlayer( GetOwnerEntity() );
if ( pOldOwner == nullptr )
{
CBaseObject *pBaseObject = dynamic_cast< CBaseObject* >( GetOwnerEntity() );
if ( pBaseObject && pBaseObject->GetOwner() )
{
pOldOwner = ToTFPlayer( pBaseObject->GetOwner() );
}
}
SetOwnerEntity( pTFDeflector );
if ( pOldOwner )
+1 -1
View File
@@ -39,7 +39,7 @@ class variant_t
public:
// constructor
variant_t() : iVal(0), fieldType(FIELD_VOID) {}
variant_t() : fieldType(FIELD_VOID), iVal(0) {}
inline bool Bool( void ) const { return( fieldType == FIELD_BOOLEAN ) ? bVal : false; }
inline const char *String( void ) const { return( fieldType == FIELD_STRING ) ? STRING(iszVal) : ToString(); }
+1
View File
@@ -3370,6 +3370,7 @@ DECLARE_SCRIPT_CONST( ETFDmgCustom, TF_DMG_CUSTOM_SLAP_KILL )
DECLARE_SCRIPT_CONST( ETFDmgCustom, TF_DMG_CUSTOM_CROC )
DECLARE_SCRIPT_CONST( ETFDmgCustom, TF_DMG_CUSTOM_TAUNTATK_GASBLAST )
DECLARE_SCRIPT_CONST( ETFDmgCustom, TF_DMG_CUSTOM_AXTINGUISHER_BOOSTED )
DECLARE_SCRIPT_CONST( ETFDmgCustom, TF_DMG_CUSTOM_TAUNTATK_TRICKSHOT )
DECLARE_SCRIPT_CONST( ETFDmgCustom, TF_DMG_CUSTOM_END )
REGISTER_SCRIPT_CONST_TABLE( ETFDmgCustom )
+1 -1
View File
@@ -801,7 +801,7 @@ void CAchievementMgr::LoadGlobalState()
// HPE_END
//=============================================================================
KeyValues *pKV = new KeyValues("GameState" );
KeyValuesAD pKV("GameState" );
if ( pKV->LoadFromFile( filesystem, szFilename, "MOD" ) )
{
KeyValues *pNode = pKV->GetFirstSubKey();
+1 -1
View File
@@ -2607,7 +2607,7 @@ void UTIL_LoadActivityRemapFile( const char *filename, const char *section, CUtl
return;
}
KeyValues *pkvFile = new KeyValues( section );
KeyValuesAD pkvFile( section );
if ( pkvFile->LoadFromFile( filesystem, filename, NULL ) )
{
+1 -3
View File
@@ -54,8 +54,6 @@ BEGIN_DATADESC( CBaseGrenade )
END_DATADESC()
void SendProxy_CropFlagsToPlayerFlagBitsLength( const SendProp *pProp, const void *pStruct, const void *pVarData, DVariant *pOut, int iElement, int objectID);
#endif
IMPLEMENT_NETWORKCLASS_ALIASED( BaseGrenade, DT_BaseGrenade )
@@ -70,7 +68,7 @@ BEGIN_NETWORK_TABLE( CBaseGrenade, DT_BaseGrenade )
SendPropVector( SENDINFO( m_vecVelocity ), 0, SPROP_NOSCALE ),
// HACK: Use same flag bits as player for now
SendPropInt ( SENDINFO(m_fFlags), PLAYER_FLAG_BITS, SPROP_UNSIGNED, SendProxy_CropFlagsToPlayerFlagBitsLength ),
SendPropInt ( SENDINFO(m_fFlags), 0, SPROP_UNSIGNED ),
#else
RecvPropFloat( RECVINFO( m_flDamage ) ),
RecvPropFloat( RECVINFO( m_DmgRadius ) ),
+2 -2
View File
@@ -20,6 +20,7 @@
#if defined(TF_CLIENT_DLL)
#include "c_tf_player.h"
#include "c_baseviewmodel.h"
#include "tf_gamerules.h"
#include "c_playerresource.h"
#include "tf_shareddefs.h"
@@ -92,7 +93,6 @@ END_SCRIPTDESC();
#endif
#ifdef TF_CLIENT_DLL
extern ConVar cl_flipviewmodels;
#endif
@@ -857,7 +857,7 @@ int C_ViewmodelAttachmentModel::InternalDrawModel( int flags )
{
#ifdef TF_CLIENT_DLL
CMatRenderContextPtr pRenderContext( materials );
if ( cl_flipviewmodels.GetBool() != m_bAlwaysFlip )
if ( TeamFortress_ShouldFlipClientViewModel() != m_bAlwaysFlip )
{
pRenderContext->CullMode( MATERIAL_CULLMODE_CW );
}
+3 -3
View File
@@ -316,7 +316,7 @@ static CDateBasedHolidayNoSpecificYear g_Holiday_ValentinesDay ( "valentines", "
static CDateBasedHoliday g_Holiday_MeetThePyro ( "meet_the_pyro", "2012-06-26", "2012-07-05" );
/* starting date cycle length in days bonus time in days on both sides */
static CCyclicalHoliday g_Holiday_FullMoon ( "fullmoon", 12, 15, 2024, 29.53f, 1.0f );
static CCyclicalHoliday g_Holiday_FullMoon ( "fullmoon", 10, 06, 2025, 29.53f, 1.0f );
// note: the cycle length is 29.5 instead of 29.53 so that the time calculations always start at noon based on the way CCyclicalHoliday works
static COrHoliday g_Holiday_HalloweenOrFullMoon ( "halloween_or_fullmoon", &g_Holiday_Halloween, &g_Holiday_FullMoon );
@@ -330,8 +330,8 @@ static CDateBasedHoliday g_Holiday_CommunityUpdate ( "community_update", "2015
static CDateBasedHolidayNoSpecificYear g_Holiday_Soldier ( "soldier", "04-12", "04-14" );
// only setup for 2024 right now...need to figure out how we want future events to run and maybe remove the year
static CDateBasedHoliday g_Holiday_Summer( "summer", "2024-07-01", "2024-09-16" );
// only setup for 2025 right now...need to figure out how we want future events to run and maybe remove the year
static CDateBasedHoliday g_Holiday_Summer( "summer", "2025-07-16", "2025-09-16" );
// ORDER NEEDS TO MATCH enum EHoliday
static IIsHolidayActive *s_HolidayChecks[] =
+11 -2
View File
@@ -2817,6 +2817,10 @@ void CEconItemDescription::Generate_CollectionDesc( const CLocalizationProvider
if ( !pItemDef )
return;
// Adding a check for if the collection we are browsing contains cosmetics or decorated weapons.
// We can handle decorated weapons the same as cosmetics, since they have proper schema entries
bool bIsHatOrDecorated = false;
// For War Painted items (not War Paints themselves) we want highlight the row of the
// War Paint itself in the collection. Look up our corresponding War Paint's item def
// and use that as our own if there is one.
@@ -2824,6 +2828,10 @@ void CEconItemDescription::Generate_CollectionDesc( const CLocalizationProvider
if ( GetPaintKitDefIndex( pEconItem, &nPaintkitDefindex ) )
{
auto pPaintkitItemDef = GetItemSchema()->GetPaintKitItemDefinition( nPaintkitDefindex );
if ( pPaintkitItemDef == NULL )
{
bIsHatOrDecorated = true;
}
pItemDef = pPaintkitItemDef ? pPaintkitItemDef : pItemDef;
}
@@ -2885,7 +2893,7 @@ void CEconItemDescription::Generate_CollectionDesc( const CLocalizationProvider
return &vecItemsWithDefindex;
uint32 unPaintkitDefidnex = 0;
if ( GetPaintKitDefIndex( pItemDef, &unPaintkitDefidnex ) )
if ( GetPaintKitDefIndex( pItemDef, &unPaintkitDefidnex ) && !bIsHatOrDecorated )
{
auto& vecItemsWithPaintkit = pLocalInv->GetItemsWithPaintkitDefindex( unPaintkitDefidnex );
if ( !vecItemsWithPaintkit.IsEmpty() )
@@ -3689,7 +3697,8 @@ void CEconItemDescription::AddAttributeDescription( const CLocalizationProvider
}
// They can also be from Halloween spells. These are intended to expire after Halloween in any
// event, but for display purposes they'll appear in grey unless the holiday is active.
else if ( pAttribDef->GetUserGenerationType() == kUserGeneratedAttributeType_HalloweenSpell && !EconHolidays_IsHolidayActive( kHoliday_Halloween, CRTime::RTime32TimeCur() ) )
else if ( pAttribDef->GetUserGenerationType() == kUserGeneratedAttributeType_HalloweenSpell &&
!(EconHolidays_IsHolidayActive(kHoliday_Halloween, CRTime::RTime32TimeCur()) || EconHolidays_IsHolidayActive(kHoliday_FullMoon, CRTime::RTime32TimeCur())) )
{
eDefaultAttribColor = ATTRIB_COL_ITEMSET_MISSING;
}
+6
View File
@@ -177,10 +177,14 @@ void CEconItemSystem::ReloadWhitelist( void )
// If we didn't find a file, we're done.
if ( !bFoundWhitelist )
{
pWhitelistKV->deleteThis();
return;
}
// Otherwise, go through the KVs and turn on the matching items.
Msg("Parsing item whitelist (default: %s)\n", bDefault ? "allowed" : "disallowed" );
KeyValues* ownerWhitelistKV = pWhitelistKV;
pWhitelistKV = pWhitelistKV->GetFirstSubKey();
while ( pWhitelistKV )
{
@@ -204,6 +208,8 @@ void CEconItemSystem::ReloadWhitelist( void )
pWhitelistKV = pWhitelistKV->GetNextKey();
}
Msg("Finished.\n");
ownerWhitelistKV->deleteThis();
}
#ifdef GAME_DLL
+1 -1
View File
@@ -64,7 +64,7 @@ COMPILE_TIME_ASSERT( ARRAYSIZE( g_QuestPointsDefs ) == EQuestPoints_ARRAYSIZE );
extern bool InitPerClassRandomChanceStringArray( KeyValues *pPerClassData, CRandomChanceString (&outputArray)[LOADOUT_COUNT], CUtlVector<CUtlString>* pVecErrors );
#ifdef CLIENT_DLL
CON_COMMAND( set_party_contract_progress_enabled, "Set whether or not you'd like your party memebers to be able to make progress on your Contracts along with you." )
CON_COMMAND( set_party_contract_progress_enabled, "Set whether or not you'd like your party members to be able to make progress on your Contracts along with you." )
{
if ( args.ArgC() != 2 )
{
+14 -6
View File
@@ -4011,6 +4011,18 @@ void CGameMovement::PlayerRoughLandingEffects( float fvol )
}
}
//-----------------------------------------------------------------------------
// Purpose: Reset interpolation when player duck state changes
// Input : direction -
//-----------------------------------------------------------------------------
void CGameMovement::ResetDuckLatched()
{
#ifdef CLIENT_DLL
if ( !player->InFirstPersonView() )
player->ResetLatched();
#endif
}
//-----------------------------------------------------------------------------
// Purpose: Use for ease-in, ease-out style interpolation (accel/decel) Used by ducking code.
// Input : value -
@@ -4133,9 +4145,7 @@ void CGameMovement::FinishUnDuck( void )
mv->SetAbsOrigin( newOrigin );
#ifdef CLIENT_DLL
player->ResetLatched();
#endif // CLIENT_DLL
ResetDuckLatched();
// Recategorize position since ducking can change origin
CategorizePosition();
@@ -4232,9 +4242,7 @@ void CGameMovement::FinishDuck( void )
VectorAdd( mv->GetAbsOrigin(), viewDelta, out );
mv->SetAbsOrigin( out );
#ifdef CLIENT_DLL
player->ResetLatched();
#endif // CLIENT_DLL
ResetDuckLatched();
}
// See if we are stuck?
+1
View File
@@ -227,6 +227,7 @@ protected:
void FinishUnDuckJump( trace_t &trace );
void SetDuckedEyeOffset( float duckFraction );
void FixPlayerCrouchStuck( bool moveup );
void ResetDuckLatched();
float SplineFraction( float value, float scale );
+456
View File
@@ -0,0 +1,456 @@
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
//=============================================================================
#ifndef GAMESTATS_H
#define GAMESTATS_H
#ifdef _WIN32
#pragma once
#endif
#include "tier1/utldict.h"
#include "tier1/utlbuffer.h"
#include "igamesystem.h"
//#include "steamworks_gamestats.h"
const int GAMESTATS_VERSION = 1;
enum StatSendType_t
{
STATSEND_LEVELSHUTDOWN,
STATSEND_APPSHUTDOWN,
STATSEND_NOTENOUGHPLAYERS,
};
struct StatsBufferRecord_t
{
float m_flFrameRate; // fps
float m_flServerPing; // client ping to server
};
#define STATS_WINDOW_SIZE ( 60 * 10 ) // # of records to hold
#define STATS_RECORD_INTERVAL 1 // # of seconds between data grabs. 2 * 300 = every 10 minutes
class CGameStats;
void UpdatePerfStats( void );
void SetGameStatsHandler( CGameStats *pGameStats );
class CBasePlayer;
class CPropVehicleDriveable;
class CTakeDamageInfo;
#ifdef GAME_DLL
#define GAMESTATS_STANDARD_NOT_SAVED 0xFEEDBEEF
enum GameStatsVersions_t
{
GAMESTATS_FILE_VERSION_OLD = 001,
GAMESTATS_FILE_VERSION_OLD2,
GAMESTATS_FILE_VERSION_OLD3,
GAMESTATS_FILE_VERSION_OLD4,
GAMESTATS_FILE_VERSION_OLD5,
GAMESTATS_FILE_VERSION
};
struct BasicGameStatsRecord_t
{
public:
BasicGameStatsRecord_t() :
m_nCount( 0 ),
m_nSeconds( 0 ),
m_nCommentary( 0 ),
m_nHDR( 0 ),
m_nCaptions( 0 ),
m_bSteam( true ),
m_bCyberCafe( false ),
m_nDeaths( 0 )
{
Q_memset( m_nSkill, 0, sizeof( m_nSkill ) );
}
void Clear();
void SaveToBuffer( CUtlBuffer& buf );
bool ParseFromBuffer( CUtlBuffer& buf, int iBufferStatsVersion );
// Data
public:
int m_nCount;
int m_nSeconds;
int m_nCommentary;
int m_nHDR;
int m_nCaptions;
int m_nSkill[ 3 ];
bool m_bSteam;
bool m_bCyberCafe;
int m_nDeaths;
};
struct BasicGameStats_t
{
public:
BasicGameStats_t() :
m_nSecondsToCompleteGame( 0 ),
m_nHL2ChaptureUnlocked( 0 ),
m_bSteam( true ),
m_bCyberCafe( false ),
m_nDXLevel( 0 )
{
}
void Clear();
void SaveToBuffer( CUtlBuffer& buf );
bool ParseFromBuffer( CUtlBuffer& buf, int iBufferStatsVersion );
BasicGameStatsRecord_t *FindOrAddRecordForMap( char const *mapname );
// Data
public:
int m_nSecondsToCompleteGame; // 0 means they haven't finished playing yet
BasicGameStatsRecord_t m_Summary; // Summary record
CUtlDict< BasicGameStatsRecord_t, unsigned short > m_MapTotals;
bool m_bSteam;
bool m_bCyberCafe;
int m_nHL2ChaptureUnlocked;
int m_nDXLevel;
};
#endif // GAME_DLL
class CBaseGameStats
{
public:
CBaseGameStats();
// override this to declare what format you want to send. New products should use new format.
virtual bool UseOldFormat()
{
#ifdef GAME_DLL
return true; // servers by default send old format for backward compat
#else
return false; // clients never used old format so no backward compat issues, they use new format by default
#endif
}
// Implement this if you support new format gamestats.
// Return true if you added data to KeyValues, false if you have no data to report
virtual bool AddDataForSend( KeyValues *pKV, StatSendType_t sendType ) { return false; }
// These methods used for new format gamestats only and control when data gets sent.
virtual bool ShouldSendDataOnLevelShutdown()
{
// by default, servers send data at every level change and clients don't
#ifdef GAME_DLL
return true;
#else
return false;
#endif
}
virtual bool ShouldSendDataOnAppShutdown()
{
// by default, clients send data at app shutdown and servers don't
#ifdef GAME_DLL
return false;
#else
return true;
#endif
}
virtual void Event_Init( void );
virtual void Event_Shutdown( void );
virtual void Event_MapChange( const char *szOldMapName, const char *szNewMapName );
virtual void Event_LevelInit( void );
virtual void Event_LevelShutdown( float flElapsed );
virtual void Event_SaveGame( void );
virtual void Event_LoadGame( void );
void CollectData( StatSendType_t sendType );
void SendData();
void StatsLog( PRINTF_FORMAT_STRING char const *fmt, ... );
// This is the first call made, so that we can "subclass" the CBaseGameStats based on gamedir as needed (e.g., ep2 vs. episodic)
virtual CBaseGameStats *OnInit( CBaseGameStats *pCurrentGameStats, char const *gamedir ) { return pCurrentGameStats; }
// Frees up data from gamestats and resets it to a clean state.
virtual void Clear( void );
virtual bool StatTrackingEnabledForMod( void ) { return false; } //Override this to turn on the system. Stat tracking is disabled by default and will always be disabled at the user's request
static bool StatTrackingAllowed( void ); //query whether stat tracking is possible and warranted by the user
virtual bool HaveValidData( void ) { return true; } // whether we currently have an interesting enough data set to upload. Called at upload time; if false, data is not uploaded.
virtual bool ShouldTrackStandardStats( void ) { return true; } //exactly what was tracked for EP1 release
//Get mod specific strings used for tracking, defaults should work fine for most cases
virtual const char *GetStatSaveFileName( void );
virtual const char *GetStatUploadRegistryKeyName( void );
const char *GetUserPseudoUniqueID( void );
virtual bool UserPlayedAllTheMaps( void ) { return false; } //be sure to override this to determine user completion time
#ifdef CLIENT_DLL
virtual void Event_AchievementProgress( int achievementID, const char* achievementName ) {}
#endif
#ifdef GAME_DLL
virtual void Event_PlayerKilled( CBasePlayer *pPlayer, const CTakeDamageInfo &info );
virtual void Event_PlayerConnected( CBasePlayer *pBasePlayer );
virtual void Event_PlayerDisconnected( CBasePlayer *pBasePlayer );
virtual void Event_PlayerDamage( CBasePlayer *pBasePlayer, const CTakeDamageInfo &info );
virtual void Event_PlayerKilledOther( CBasePlayer *pAttacker, CBaseEntity *pVictim, const CTakeDamageInfo &info );
virtual void Event_PlayerSuicide( CBasePlayer* pPlayer ) {}
virtual void Event_Credits();
virtual void Event_Commentary();
virtual void Event_CrateSmashed();
virtual void Event_Punted( CBaseEntity *pObject );
virtual void Event_PlayerTraveled( CBasePlayer *pBasePlayer, float distanceInInches, bool bInVehicle, bool bSprinting );
virtual void Event_WeaponFired( CBasePlayer *pShooter, bool bPrimary, char const *pchWeaponName );
virtual void Event_WeaponHit( CBasePlayer *pShooter, bool bPrimary, char const *pchWeaponName, const CTakeDamageInfo &info );
virtual void Event_FlippedVehicle( CBasePlayer *pDriver, CPropVehicleDriveable *pVehicle );
virtual void Event_PreSaveGameLoaded( char const *pSaveName, bool bInGame );
virtual void Event_PlayerEnteredGodMode( CBasePlayer *pBasePlayer );
virtual void Event_PlayerEnteredNoClip( CBasePlayer *pBasePlayer );
virtual void Event_DecrementPlayerEnteredNoClip( CBasePlayer *pBasePlayer );
virtual void Event_IncrementCountedStatistic( const Vector& vecAbsOrigin, char const *pchStatisticName, float flIncrementAmount );
//=============================================================================
// HPE_BEGIN
// [dwenger] Functions necessary for cs-specific stats
//=============================================================================
virtual void Event_WindowShattered( CBasePlayer *pPlayer );
//=============================================================================
// HPE_END
//=============================================================================
//custom data to tack onto existing stats if you're not doing a complete overhaul
virtual void AppendCustomDataToSaveBuffer( CUtlBuffer &SaveBuffer ) { } //custom data you want thrown into the default save and upload path
virtual void LoadCustomDataFromBuffer( CUtlBuffer &LoadBuffer ) { }; //when loading the saved stats file, this will point to where you started saving data to the save buffer
virtual void LoadingEvent_PlayerIDDifferentThanLoadedStats( void ); //Only called if you use the base SaveToFileNOW() and LoadFromFile() functions. Used in case you want to keep/invalidate data that was just loaded.
virtual bool LoadFromFile( void ); //called just before Event_Init()
virtual bool SaveToFileNOW( bool bForceSyncWrite = false ); //saves buffers to their respective files now, returns success or failure
virtual bool UploadStatsFileNOW( void ); //uploads data to the CSER now, returns success or failure
static bool AppendLump( int nMaxLumpCount, CUtlBuffer &SaveBuffer, unsigned short iLump, unsigned short iLumpCount, size_t nSize, void *pData );
static bool GetLumpHeader( int nMaxLumpCount, CUtlBuffer &LoadBuffer, unsigned short &iLump, unsigned short &iLumpCount, bool bPermissive = false );
static void LoadLump( CUtlBuffer &LoadBuffer, unsigned short iLumpCount, size_t nSize, void *pData );
//default save behavior is to save on level shutdown, and game shutdown
virtual bool AutoSave_OnInit( void ) { return false; }
virtual bool AutoSave_OnShutdown( void ) { return true; }
virtual bool AutoSave_OnMapChange( void ) { return false; }
virtual bool AutoSave_OnLevelInit( void ) { return false; }
virtual bool AutoSave_OnLevelShutdown( void ) { return true; }
//default upload behavior is to upload on game shutdown
virtual bool AutoUpload_OnInit( void ) { return false; }
virtual bool AutoUpload_OnShutdown( void ) { return true; }
virtual bool AutoUpload_OnMapChange( void ) { return false; }
virtual bool AutoUpload_OnLevelInit( void ) { return false; }
virtual bool AutoUpload_OnLevelShutdown( void ) { return false; }
// Helper for builtin stuff
void SetSteamStatistic( bool bUsingSteam );
void SetCyberCafeStatistic( bool bIsCyberCafeUser );
void SetHDRStatistic( bool bHDREnabled );
void SetCaptionsStatistic( bool bClosedCaptionsEnabled );
void SetSkillStatistic( int iSkillSetting );
void SetDXLevelStatistic( int iDXLevel );
void SetHL2UnlockedChapterStatistic( void );
#endif // GAMEDLL
public:
#ifdef GAME_DLL
BasicGameStats_t m_BasicStats; //exposed in case you do a complete overhaul and still want to save it
#endif
bool m_bLogging : 1;
bool m_bLoggingToFile : 1;
};
#ifdef GAME_DLL
//-----------------------------------------------------------------------------
// Purpose:
// Input : &SaveBuffer -
// iLump -
// iLumpCount -
//-----------------------------------------------------------------------------
inline bool CBaseGameStats::AppendLump( int nMaxLumpCount, CUtlBuffer &SaveBuffer, unsigned short iLump, unsigned short iLumpCount, size_t nSize, void *pData )
{
// Verify the lump index.
Assert( ( iLump > 0 ) && ( iLump < nMaxLumpCount ) );
if ( !( ( iLump > 0 ) && ( iLump < nMaxLumpCount ) ) )
return false;
// Check to see if we have any elements to save.
if ( iLumpCount <= 0 )
return false;
// Write the lump id and element count.
SaveBuffer.PutUnsignedShort( iLump );
SaveBuffer.PutUnsignedShort( iLumpCount );
size_t nTotalSize = iLumpCount * nSize;
SaveBuffer.Put( pData, nTotalSize );
return true;
}
//-----------------------------------------------------------------------------
// Purpose:
// Input : &LoadBuffer -
// &iLump -
// &iLumpCount -
// Output : Returns true on success, false on failure.
//-----------------------------------------------------------------------------
inline bool CBaseGameStats::GetLumpHeader( int nMaxLumpCount, CUtlBuffer &LoadBuffer, unsigned short &iLump, unsigned short &iLumpCount, bool bPermissive /*= false*/ )
{
// Get the lump id and element count.
iLump = LoadBuffer.GetUnsignedShort();
if ( !LoadBuffer.IsValid() )
{
// check for EOF
return false;
}
iLumpCount = LoadBuffer.GetUnsignedShort();
if ( bPermissive )
return true;
// Verify the lump index.
Assert( ( iLump > 0 ) && ( iLump < nMaxLumpCount ) );
if ( !( ( iLump > 0 ) && ( iLump < nMaxLumpCount ) ) )
{
return false;
}
// Check to see if we have any elements to save.
if ( iLumpCount <= 0 )
return false;
return true;
}
//-----------------------------------------------------------------------------
// Purpose: Loads 1 or more lumps of raw data
// Input : &LoadBuffer - buffer to be read from
// iLumpCount - # of lumps to read
// nSize - size of each lump
// pData - where to store the data
//-----------------------------------------------------------------------------
inline void CBaseGameStats::LoadLump( CUtlBuffer &LoadBuffer, unsigned short iLumpCount, size_t nSize, void *pData )
{
LoadBuffer.Get( pData, iLumpCount * nSize );
}
#endif // GAME_DLL
// Moving the extern out of the GAME_DLL block so that the client can access it
extern CBaseGameStats *gamestats; //starts out pointing at a singleton of the class above, overriding this in any constructor should work for replacing it
//used to drive most of the game stat event handlers as well as track basic stats under the hood of CBaseGameStats
class CBaseGameStats_Driver : public CAutoGameSystemPerFrame
{
public:
CBaseGameStats_Driver( void );
typedef CAutoGameSystemPerFrame BaseClass;
// IGameSystem overloads
virtual bool Init();
virtual void Shutdown();
// Level init, shutdown
virtual void LevelInitPreEntity();
virtual void LevelShutdownPreEntity();
virtual void LevelShutdownPreClearSteamAPIContext();
virtual void LevelShutdown();
// Called during game save
virtual void OnSave();
// Called during game restore, after the local player has connected and entities have been fully restored
virtual void OnRestore();
virtual void FrameUpdatePostEntityThink();
void PossibleMapChange( void );
void CollectData( StatSendType_t sendType );
void SendData();
void ResetData();
bool AddBaseDataForSend( KeyValues *pKV, StatSendType_t sendType );
StatsBufferRecord_t m_StatsBuffer[STATS_WINDOW_SIZE];
bool m_bBufferFull;
int m_nWriteIndex;
float m_flLastRealTime;
float m_flLastSampleTime;
float m_flTotalTimeInLevels;
int m_iNumLevels;
bool m_bDidVoiceChat; // Did the player use voice chat at ALL this map?
template<class T> T AverageStat( T StatsBufferRecord_t::*field ) const
{
T sum = 0;
for( int i = 0; i < STATS_WINDOW_SIZE; i++ )
sum += m_StatsBuffer[i].*field;
return sum / STATS_WINDOW_SIZE;
}
template<class T> T MaxStat( T StatsBufferRecord_t::*field ) const
{
T maxsofar = -16000000;
for( int i = 0; i < STATS_WINDOW_SIZE; i++ )
maxsofar = MAX( maxsofar, m_StatsBuffer[i].*field );
return maxsofar;
}
template<class T> T MinStat( T StatsBufferRecord_t::*field ) const
{
T minsofar = 16000000;
for( int i = 0; i < STATS_WINDOW_SIZE; i++ )
minsofar = MIN( minsofar, m_StatsBuffer[i].*field );
return minsofar;
}
inline void AdvanceIndex( void )
{
m_nWriteIndex++;
if ( m_nWriteIndex == STATS_WINDOW_SIZE )
{
m_nWriteIndex = 0;
m_bBufferFull = true;
}
}
void UpdatePerfStats( void );
CUtlString m_PrevMapName; //used to track "OnMapChange" events
int m_iLoadedVersion;
char m_szLoadedUserID[ 17 ]; // GUID
bool m_bEnabled; //false if incapable of uploading or the user doesn't want to enable stat tracking
bool m_bShuttingDown;
bool m_bInLevel;
bool m_bFirstLevel;
time_t m_tLastUpload;
float m_flLevelStartTime;
bool m_bStationary;
float m_flLastMovementTime;
CUserCmd m_LastUserCmd;
bool m_bGamePaused;
float m_flPauseStartTime;
CGamestatsData *m_pGamestatsData;
};
#endif // GAMESTATS_H
+12 -9
View File
@@ -11,6 +11,7 @@
#ifdef CLIENT_DLL
#include "c_hl2mp_player.h"
#include <prediction.h>
#else
#include "hl2mp_player.h"
#endif
@@ -133,16 +134,18 @@ void CWeapon357::PrimaryAttack( void )
// Fire the bullets, and force the first shot to be perfectly accuracy
pPlayer->FireBullets( info );
#ifdef CLIENT_DLL
//Disorient the player
QAngle angles = pPlayer->GetLocalAngles();
angles.x += random->RandomInt( -1, 1 );
angles.y += random->RandomInt( -1, 1 );
angles.z = 0;
#ifndef CLIENT_DLL
pPlayer->SnapEyeAngles( angles );
#endif
if ( prediction->IsFirstTimePredicted() )
{
QAngle angles;
engine->GetViewAngles( angles );
angles.x += random->RandomInt( -1, 1 );
angles.y += random->RandomInt( -1, 1 );
angles.z += 0.0f;
engine->SetViewAngles( angles );
}
#endif // CLIENT_DLL
pPlayer->ViewPunch( QAngle( -8, random->RandomFloat( -2, 2 ), 0 ) );
+1 -1
View File
@@ -186,7 +186,7 @@ void ParseParticleEffectsMap( const char *pMapName, bool bLoadSheets )
V_snprintf( szMapManifestFilename, sizeof( szMapManifestFilename ), "maps/%s_particles.txt", pMapName );
}
KeyValues *manifest = new KeyValues( szMapManifestFilename );
KeyValuesAD manifest( szMapManifestFilename );
// In order:
// - particles.txt within the map BSP

Some files were not shown because too many files have changed in this diff Show More