mirror of
https://github.com/alliedmodders/hl2sdk.git
synced 2025-09-19 20:16:10 +08:00
Sync with upstream (Issue #30).
Recompiled tier1 and mathlib for all platforms will come in next commit.
This commit is contained in:
@ -46,6 +46,11 @@ extern const ConVar *sv_cheats;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef CLIENT_DLL
|
||||
// Ensure this is declared in the client dll so everyone finds the same one.
|
||||
ConVar dev_loadtime_mainmenu("dev_loadtime_mainmenu", "0.0", FCVAR_HIDDEN );
|
||||
#endif
|
||||
|
||||
// NOTE: This has to be the last file included!
|
||||
#include "tier0/memdbgon.h"
|
||||
|
||||
@ -141,7 +146,7 @@ CBaseGameStats_Driver::CBaseGameStats_Driver( void ) :
|
||||
m_bDidVoiceChat( false )
|
||||
|
||||
{
|
||||
m_szLoadedUserID[0] = 0;;
|
||||
m_szLoadedUserID[0] = 0;
|
||||
m_tLastUpload = 0;
|
||||
m_LastUserCmd.Reset();
|
||||
}
|
||||
@ -1061,6 +1066,33 @@ void CBaseGameStats_Driver::SendData()
|
||||
ResetData();
|
||||
}
|
||||
|
||||
#ifdef CLIENT_DLL
|
||||
// Adds the main menu load time to the specified key values, but only ever does the work once.
|
||||
static void AddLoadTimeMainMenu( KeyValues* pKV )
|
||||
{
|
||||
Assert( pKV );
|
||||
float loadTimeMainMenu = dev_loadtime_mainmenu.GetFloat();
|
||||
if ( loadTimeMainMenu > 0.0f ) {
|
||||
pKV->SetFloat( "LoadTimeMainMenu", loadTimeMainMenu );
|
||||
// Only want to set this once, clear it to 0.0 here. The other code will only ever set it once.
|
||||
dev_loadtime_mainmenu.SetValue( 0.0f );
|
||||
}
|
||||
}
|
||||
|
||||
// Adds the map load time to the specified key values, but clears the elapsed data to 0.0 for next computation.
|
||||
static void AddLoadTimeMap(KeyValues* pKV)
|
||||
{
|
||||
static ConVarRef dev_loadtime_map_elapsed( "dev_loadtime_map_elapsed" );
|
||||
float loadTimeMap = dev_loadtime_map_elapsed.GetFloat();
|
||||
if ( loadTimeMap > 0.0f )
|
||||
{
|
||||
pKV->SetFloat( "LoadTimeMap", loadTimeMap );
|
||||
dev_loadtime_map_elapsed.SetValue( 0.0f );
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
bool CBaseGameStats_Driver::AddBaseDataForSend( KeyValues *pKV, StatSendType_t sendType )
|
||||
{
|
||||
switch ( sendType )
|
||||
@ -1074,6 +1106,12 @@ bool CBaseGameStats_Driver::AddBaseDataForSend( KeyValues *pKV, StatSendType_t s
|
||||
pKVData->SetInt( "TotalLevelTime", m_flTotalTimeInLevels );
|
||||
pKVData->SetInt( "NumLevels", m_iNumLevels );
|
||||
pKV->AddSubKey( pKVData );
|
||||
|
||||
AddLoadTimeMainMenu( pKV );
|
||||
// If the user quits directly from the map, we still want to (possibly) capture their map load time, so
|
||||
// do add it here. It will not be added if it was already attached to a session.
|
||||
AddLoadTimeMap( pKV );
|
||||
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
@ -1141,6 +1179,9 @@ bool CBaseGameStats_Driver::AddBaseDataForSend( KeyValues *pKV, StatSendType_t s
|
||||
int mapTime = gpGlobals->realtime - m_flLevelStartTime;
|
||||
pKV->SetInt( "MapTime", mapTime );
|
||||
|
||||
AddLoadTimeMainMenu(pKV);
|
||||
AddLoadTimeMap(pKV);
|
||||
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
@ -1177,6 +1218,10 @@ void CBaseGameStats_Driver::ResetData()
|
||||
OverWriteCharsWeHate( cpu.m_szProcessorID );
|
||||
pKV->SetString( "CPUID", cpu.m_szProcessorID );
|
||||
pKV->SetFloat( "CPUGhz", cpu.m_Speed * ( 1.0 / 1.0e9 ) );
|
||||
pKV->SetUint64( "CPUModel", cpu.m_nModel );
|
||||
pKV->SetUint64( "CPUFeatures0", cpu.m_nFeatures[ 0 ] );
|
||||
pKV->SetUint64( "CPUFeatures1", cpu.m_nFeatures[ 1 ] );
|
||||
pKV->SetUint64( "CPUFeatures2", cpu.m_nFeatures[ 2 ] );
|
||||
pKV->SetInt( "NumCores", cpu.m_nPhysicalProcessors );
|
||||
|
||||
MaterialAdapterInfo_t gpu;
|
||||
|
@ -68,7 +68,7 @@ void CModelSoundsCache::Restore( CUtlBuffer& buf )
|
||||
{
|
||||
char soundname[ 512 ];
|
||||
|
||||
buf.GetString( soundname, sizeof( soundname ) );
|
||||
buf.GetString( soundname );
|
||||
|
||||
int idx = soundemitterbase->GetSoundIndex( soundname );
|
||||
if ( idx != -1 )
|
||||
|
@ -91,6 +91,10 @@ CMultiPlayerAnimState::CMultiPlayerAnimState( CBasePlayer *pPlayer, MultiPlayerM
|
||||
|
||||
m_flMaxGroundSpeed = 0.0f;
|
||||
|
||||
// If you are forcing aim yaw, your code is almost definitely broken if you don't include a delay between
|
||||
// teleporting and forcing yaw. This is due to an unfortunate interaction between the command lookback window,
|
||||
// and the fact that m_flEyeYaw is never propogated from the server to the client.
|
||||
// TODO: Fix this after Halloween 2014.
|
||||
m_bForceAimYaw = false;
|
||||
|
||||
Init( pPlayer, movementData );
|
||||
@ -1655,6 +1659,10 @@ void CMultiPlayerAnimState::ComputePoseParam_AimYaw( CStudioHdr *pStudioHdr )
|
||||
bool bMoving = ( vecVelocity.Length() > 1.0f ) ? true : false;
|
||||
|
||||
// If we are moving or are prone and undeployed.
|
||||
// If you are forcing aim yaw, your code is almost definitely broken if you don't include a delay between
|
||||
// teleporting and forcing yaw. This is due to an unfortunate interaction between the command lookback window,
|
||||
// and the fact that m_flEyeYaw is never propogated from the server to the client.
|
||||
// TODO: Fix this after Halloween 2014.
|
||||
if ( bMoving || m_bForceAimYaw )
|
||||
{
|
||||
// The feet match the eye direction when moving - the move yaw takes care of the rest.
|
||||
@ -1688,6 +1696,10 @@ void CMultiPlayerAnimState::ComputePoseParam_AimYaw( CStudioHdr *pStudioHdr )
|
||||
m_flGoalFeetYaw = AngleNormalize( m_flGoalFeetYaw );
|
||||
if ( m_flGoalFeetYaw != m_flCurrentFeetYaw )
|
||||
{
|
||||
// If you are forcing aim yaw, your code is almost definitely broken if you don't include a delay between
|
||||
// teleporting and forcing yaw. This is due to an unfortunate interaction between the command lookback window,
|
||||
// and the fact that m_flEyeYaw is never propogated from the server to the client.
|
||||
// TODO: Fix this after Halloween 2014.
|
||||
if ( m_bForceAimYaw )
|
||||
{
|
||||
m_flCurrentFeetYaw = m_flGoalFeetYaw;
|
||||
|
@ -63,6 +63,10 @@ enum PlayerAnimEvent_t
|
||||
PLAYERANIMEVENT_STUN_BEGIN,
|
||||
PLAYERANIMEVENT_STUN_MIDDLE,
|
||||
PLAYERANIMEVENT_STUN_END,
|
||||
PLAYERANIMEVENT_PASSTIME_THROW_BEGIN,
|
||||
PLAYERANIMEVENT_PASSTIME_THROW_MIDDLE,
|
||||
PLAYERANIMEVENT_PASSTIME_THROW_END,
|
||||
PLAYERANIMEVENT_PASSTIME_THROW_CANCEL,
|
||||
|
||||
PLAYERANIMEVENT_ATTACK_PRIMARY_SUPER,
|
||||
|
||||
@ -203,6 +207,10 @@ public:
|
||||
bool VerifyAnimLayerInSlot( int iGestureSlot );
|
||||
|
||||
// Feet.
|
||||
// If you are forcing aim yaw, your code is almost definitely broken if you don't include a delay between
|
||||
// teleporting and forcing yaw. This is due to an unfortunate interaction between the command lookback window,
|
||||
// and the fact that m_flEyeYaw is never propogated from the server to the client.
|
||||
// TODO: Fix this after Halloween 2014.
|
||||
bool m_bForceAimYaw;
|
||||
|
||||
protected:
|
||||
|
@ -59,7 +59,7 @@ void CSceneCache::Restore( CUtlBuffer& buf )
|
||||
for ( int i = 0; i < c; ++i )
|
||||
{
|
||||
char soundname[ 512 ];
|
||||
buf.GetString( soundname, sizeof( soundname ) );
|
||||
buf.GetString( soundname );
|
||||
|
||||
int idx = soundemitterbase->GetSoundIndex( soundname );
|
||||
if ( idx != -1 )
|
||||
|
@ -337,6 +337,15 @@ public:
|
||||
FinishLog();
|
||||
#endif
|
||||
}
|
||||
|
||||
void Flush()
|
||||
{
|
||||
Assert( soundemitterbase );
|
||||
#if !defined( CLIENT_DLL )
|
||||
FinishLog();
|
||||
#endif
|
||||
soundemitterbase->Flush();
|
||||
}
|
||||
|
||||
void InternalPrecacheWaves( int soundIndex )
|
||||
{
|
||||
@ -998,10 +1007,7 @@ void S_SoundEmitterSystemFlush( void )
|
||||
|
||||
// save the current soundscape
|
||||
// kill the system
|
||||
g_SoundEmitterSystem.Shutdown();
|
||||
|
||||
// restart the system
|
||||
g_SoundEmitterSystem.Init();
|
||||
g_SoundEmitterSystem.Flush();
|
||||
|
||||
#if !defined( CLIENT_DLL )
|
||||
// Redo precache all wave files... (this should work now that we have dynamic string tables)
|
||||
|
@ -82,8 +82,8 @@ private:
|
||||
enum
|
||||
{
|
||||
// NOTE: # of points max must be a power of two!
|
||||
MAX_SPRITE_TRAIL_POINTS = 64,
|
||||
MAX_SPRITE_TRAIL_MASK = 0x3F,
|
||||
MAX_SPRITE_TRAIL_POINTS = 256,
|
||||
MAX_SPRITE_TRAIL_MASK = MAX_SPRITE_TRAIL_POINTS - 1,
|
||||
};
|
||||
|
||||
TrailPoint_t *GetTrailPoint( int n );
|
||||
@ -114,6 +114,11 @@ private:
|
||||
string_t m_iszSpriteName;
|
||||
bool m_bAnimate;
|
||||
bool m_bDrawForMoveParent;
|
||||
|
||||
#if defined( CLIENT_DLL )
|
||||
public:
|
||||
void SetUpdateTime(float setTo){ m_flUpdateTime = setTo; }
|
||||
#endif
|
||||
};
|
||||
|
||||
#endif // SPRITETRAIL_H
|
||||
|
@ -1802,6 +1802,11 @@ void ActivityList_RegisterSharedActivities( void )
|
||||
REGISTER_SHARED_ACTIVITY( ACT_MP_ATTACK_SWIM_GRENADE_ITEM2 );
|
||||
REGISTER_SHARED_ACTIVITY( ACT_MP_ATTACK_AIRWALK_GRENADE_ITEM2 );
|
||||
|
||||
// Passtime
|
||||
REGISTER_SHARED_ACTIVITY( ACT_MP_STAND_PASSTIME );
|
||||
REGISTER_SHARED_ACTIVITY( ACT_MP_RUN_PASSTIME );
|
||||
REGISTER_SHARED_ACTIVITY( ACT_MP_CROUCHWALK_PASSTIME );
|
||||
|
||||
// Flinches
|
||||
REGISTER_SHARED_ACTIVITY( ACT_MP_GESTURE_FLINCH );
|
||||
REGISTER_SHARED_ACTIVITY( ACT_MP_GESTURE_FLINCH_PRIMARY );
|
||||
@ -1943,6 +1948,7 @@ void ActivityList_RegisterSharedActivities( void )
|
||||
REGISTER_SHARED_ACTIVITY ( ACT_MP_DOUBLEJUMP_CROUCH_ITEM1 );
|
||||
REGISTER_SHARED_ACTIVITY ( ACT_MP_DOUBLEJUMP_CROUCH_ITEM2 );
|
||||
REGISTER_SHARED_ACTIVITY ( ACT_MP_DOUBLEJUMP_CROUCH_LOSERSTATE );
|
||||
REGISTER_SHARED_ACTIVITY ( ACT_MP_DOUBLEJUMP_CROUCH_PASSTIME );
|
||||
|
||||
REGISTER_SHARED_ACTIVITY( ACT_MP_GESTURE_VC_HANDMOUTH );
|
||||
REGISTER_SHARED_ACTIVITY( ACT_MP_GESTURE_VC_FINGERPOINT );
|
||||
@ -2004,6 +2010,11 @@ void ActivityList_RegisterSharedActivities( void )
|
||||
REGISTER_SHARED_ACTIVITY( ACT_MP_STUN_MIDDLE );
|
||||
REGISTER_SHARED_ACTIVITY( ACT_MP_STUN_END );
|
||||
|
||||
REGISTER_SHARED_ACTIVITY( ACT_MP_PASSTIME_THROW_BEGIN );
|
||||
REGISTER_SHARED_ACTIVITY( ACT_MP_PASSTIME_THROW_MIDDLE );
|
||||
REGISTER_SHARED_ACTIVITY( ACT_MP_PASSTIME_THROW_END );
|
||||
REGISTER_SHARED_ACTIVITY( ACT_MP_PASSTIME_THROW_CANCEL );
|
||||
|
||||
REGISTER_SHARED_ACTIVITY ( ACT_VM_UNUSABLE );
|
||||
REGISTER_SHARED_ACTIVITY ( ACT_VM_UNUSABLE_TO_USABLE );
|
||||
REGISTER_SHARED_ACTIVITY ( ACT_VM_USABLE_TO_UNUSABLE );
|
||||
@ -2304,6 +2315,42 @@ void ActivityList_RegisterSharedActivities( void )
|
||||
REGISTER_SHARED_ACTIVITY( ACT_BOT_PANIC_START );
|
||||
REGISTER_SHARED_ACTIVITY( ACT_BOT_PANIC_END );
|
||||
|
||||
REGISTER_SHARED_ACTIVITY( ACT_ENGINEER_REVOLVER_DRAW );
|
||||
REGISTER_SHARED_ACTIVITY( ACT_ENGINEER_REVOLVER_IDLE );
|
||||
REGISTER_SHARED_ACTIVITY( ACT_ENGINEER_REVOLVER_PRIMARYATTACK );
|
||||
REGISTER_SHARED_ACTIVITY( ACT_ENGINEER_REVOLVER_RELOAD );
|
||||
|
||||
REGISTER_SHARED_ACTIVITY( ACT_KART_IDLE );
|
||||
REGISTER_SHARED_ACTIVITY( ACT_KART_ACTION_SHOOT );
|
||||
REGISTER_SHARED_ACTIVITY( ACT_KART_ACTION_DASH );
|
||||
REGISTER_SHARED_ACTIVITY( ACT_KART_JUMP_START );
|
||||
REGISTER_SHARED_ACTIVITY( ACT_KART_JUMP_FLOAT );
|
||||
REGISTER_SHARED_ACTIVITY( ACT_KART_JUMP_LAND );
|
||||
REGISTER_SHARED_ACTIVITY( ACT_KART_IMPACT );
|
||||
REGISTER_SHARED_ACTIVITY( ACT_KART_IMPACT_BIG );
|
||||
REGISTER_SHARED_ACTIVITY( ACT_KART_GESTURE_POSITIVE );
|
||||
REGISTER_SHARED_ACTIVITY( ACT_KART_GESTURE_NEGATIVE );
|
||||
|
||||
REGISTER_SHARED_ACTIVITY( ACT_GRAPPLE_DRAW );
|
||||
REGISTER_SHARED_ACTIVITY( ACT_GRAPPLE_IDLE );
|
||||
REGISTER_SHARED_ACTIVITY( ACT_GRAPPLE_FIRE_START );
|
||||
REGISTER_SHARED_ACTIVITY( ACT_GRAPPLE_FIRE_IDLE );
|
||||
REGISTER_SHARED_ACTIVITY( ACT_GRAPPLE_PULL_START );
|
||||
REGISTER_SHARED_ACTIVITY( ACT_GRAPPLE_PULL_IDLE );
|
||||
REGISTER_SHARED_ACTIVITY( ACT_GRAPPLE_PULL_END );
|
||||
|
||||
REGISTER_SHARED_ACTIVITY( ACT_PRIMARY_VM_INSPECT_START );
|
||||
REGISTER_SHARED_ACTIVITY( ACT_PRIMARY_VM_INSPECT_IDLE );
|
||||
REGISTER_SHARED_ACTIVITY( ACT_PRIMARY_VM_INSPECT_END );
|
||||
|
||||
REGISTER_SHARED_ACTIVITY( ACT_SECONDARY_VM_INSPECT_START );
|
||||
REGISTER_SHARED_ACTIVITY( ACT_SECONDARY_VM_INSPECT_IDLE );
|
||||
REGISTER_SHARED_ACTIVITY( ACT_SECONDARY_VM_INSPECT_END );
|
||||
|
||||
REGISTER_SHARED_ACTIVITY( ACT_MELEE_VM_INSPECT_START );
|
||||
REGISTER_SHARED_ACTIVITY( ACT_MELEE_VM_INSPECT_IDLE );
|
||||
REGISTER_SHARED_ACTIVITY( ACT_MELEE_VM_INSPECT_END );
|
||||
|
||||
AssertMsg( g_HighestActivity == LAST_SHARED_ACTIVITY - 1, "Not all activities from ai_activity.h registered in activitylist.cpp" );
|
||||
}
|
||||
|
||||
|
@ -1631,6 +1631,11 @@ typedef enum
|
||||
ACT_MP_ATTACK_SWIM_GRENADE_ITEM2,
|
||||
ACT_MP_ATTACK_AIRWALK_GRENADE_ITEM2,
|
||||
|
||||
// Passtime
|
||||
ACT_MP_STAND_PASSTIME,
|
||||
ACT_MP_RUN_PASSTIME,
|
||||
ACT_MP_CROUCHWALK_PASSTIME,
|
||||
|
||||
// Flinches
|
||||
ACT_MP_GESTURE_FLINCH,
|
||||
ACT_MP_GESTURE_FLINCH_PRIMARY,
|
||||
@ -1771,6 +1776,7 @@ typedef enum
|
||||
ACT_MP_DOUBLEJUMP_CROUCH_ITEM1,
|
||||
ACT_MP_DOUBLEJUMP_CROUCH_ITEM2,
|
||||
ACT_MP_DOUBLEJUMP_CROUCH_LOSERSTATE,
|
||||
ACT_MP_DOUBLEJUMP_CROUCH_PASSTIME,
|
||||
|
||||
ACT_MP_GESTURE_VC_HANDMOUTH,
|
||||
ACT_MP_GESTURE_VC_FINGERPOINT,
|
||||
@ -1832,6 +1838,11 @@ typedef enum
|
||||
ACT_MP_STUN_MIDDLE,
|
||||
ACT_MP_STUN_END,
|
||||
|
||||
ACT_MP_PASSTIME_THROW_BEGIN,
|
||||
ACT_MP_PASSTIME_THROW_MIDDLE,
|
||||
ACT_MP_PASSTIME_THROW_END,
|
||||
ACT_MP_PASSTIME_THROW_CANCEL,
|
||||
|
||||
ACT_VM_UNUSABLE,
|
||||
ACT_VM_UNUSABLE_TO_USABLE,
|
||||
ACT_VM_USABLE_TO_UNUSABLE,
|
||||
@ -2138,6 +2149,45 @@ typedef enum
|
||||
ACT_BOT_PANIC_START,
|
||||
ACT_BOT_PANIC_END,
|
||||
|
||||
ACT_ENGINEER_REVOLVER_DRAW,
|
||||
ACT_ENGINEER_REVOLVER_IDLE,
|
||||
ACT_ENGINEER_REVOLVER_PRIMARYATTACK,
|
||||
ACT_ENGINEER_REVOLVER_RELOAD,
|
||||
|
||||
// Kart!
|
||||
ACT_KART_IDLE,
|
||||
ACT_KART_ACTION_SHOOT,
|
||||
ACT_KART_ACTION_DASH,
|
||||
ACT_KART_JUMP_START,
|
||||
ACT_KART_JUMP_FLOAT,
|
||||
ACT_KART_JUMP_LAND,
|
||||
ACT_KART_IMPACT,
|
||||
ACT_KART_IMPACT_BIG,
|
||||
ACT_KART_GESTURE_POSITIVE,
|
||||
ACT_KART_GESTURE_NEGATIVE,
|
||||
|
||||
// grappling hook
|
||||
ACT_GRAPPLE_DRAW,
|
||||
ACT_GRAPPLE_IDLE,
|
||||
ACT_GRAPPLE_FIRE_START,
|
||||
ACT_GRAPPLE_FIRE_IDLE,
|
||||
ACT_GRAPPLE_PULL_START,
|
||||
ACT_GRAPPLE_PULL_IDLE,
|
||||
ACT_GRAPPLE_PULL_END,
|
||||
|
||||
// inspect
|
||||
ACT_PRIMARY_VM_INSPECT_START,
|
||||
ACT_PRIMARY_VM_INSPECT_IDLE,
|
||||
ACT_PRIMARY_VM_INSPECT_END,
|
||||
|
||||
ACT_SECONDARY_VM_INSPECT_START,
|
||||
ACT_SECONDARY_VM_INSPECT_IDLE,
|
||||
ACT_SECONDARY_VM_INSPECT_END,
|
||||
|
||||
ACT_MELEE_VM_INSPECT_START,
|
||||
ACT_MELEE_VM_INSPECT_IDLE,
|
||||
ACT_MELEE_VM_INSPECT_END,
|
||||
|
||||
// this is the end of the global activities, private per-monster activities start here.
|
||||
LAST_SHARED_ACTIVITY,
|
||||
} Activity;
|
||||
|
@ -342,6 +342,77 @@ int CStudioHdr::CActivityToSequenceMapping::SelectWeightedSequence( CStudioHdr *
|
||||
|
||||
}
|
||||
|
||||
int CStudioHdr::CActivityToSequenceMapping::SelectWeightedSequenceFromModifiers( CStudioHdr *pstudiohdr, int activity, CUtlSymbol *pActivityModifiers, int iModifierCount )
|
||||
{
|
||||
if ( !pstudiohdr->SequencesAvailable() )
|
||||
{
|
||||
return ACTIVITY_NOT_AVAILABLE;
|
||||
}
|
||||
|
||||
VerifySequenceIndex( pstudiohdr );
|
||||
|
||||
if ( pstudiohdr->GetNumSeq() == 1 )
|
||||
{
|
||||
return ( ::GetSequenceActivity( pstudiohdr, 0, NULL ) == activity ) ? 0 : ACTIVITY_NOT_AVAILABLE;
|
||||
}
|
||||
|
||||
if (!ValidateAgainst(pstudiohdr))
|
||||
{
|
||||
AssertMsg1(false, "CStudioHdr %s has changed its vmodel pointer without reinitializing its activity mapping! Now performing emergency reinitialization.", pstudiohdr->pszName());
|
||||
ExecuteOnce(DebuggerBreakIfDebugging());
|
||||
Reinitialize(pstudiohdr);
|
||||
}
|
||||
|
||||
// a null m_pSequenceTuples just means that this studio header has no activities.
|
||||
if (!m_pSequenceTuples)
|
||||
return ACTIVITY_NOT_AVAILABLE;
|
||||
|
||||
// get the data for the given activity
|
||||
HashValueType dummy( activity, 0, 0, 0 );
|
||||
UtlHashHandle_t handle = m_ActToSeqHash.Find(dummy);
|
||||
if (!m_ActToSeqHash.IsValidHandle(handle))
|
||||
{
|
||||
return ACTIVITY_NOT_AVAILABLE;
|
||||
}
|
||||
const HashValueType * __restrict actData = &m_ActToSeqHash[handle];
|
||||
|
||||
// go through each sequence and give it a score
|
||||
int top_score = -1;
|
||||
CUtlVector<int> topScoring( actData->count, actData->count );
|
||||
for ( int i = 0; i < actData->count; i++ )
|
||||
{
|
||||
SequenceTuple * __restrict sequenceInfo = m_pSequenceTuples + actData->startingIdx + i;
|
||||
int score = 0;
|
||||
// count matching activity modifiers
|
||||
for ( int m = 0; m < iModifierCount; m++ )
|
||||
{
|
||||
int num_modifiers = sequenceInfo->iNumActivityModifiers;
|
||||
for ( int k = 0; k < num_modifiers; k++ )
|
||||
{
|
||||
if ( sequenceInfo->pActivityModifiers[ k ] == pActivityModifiers[ m ] )
|
||||
{
|
||||
score++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if ( score > top_score )
|
||||
{
|
||||
topScoring.RemoveAll();
|
||||
topScoring.AddToTail( sequenceInfo->seqnum );
|
||||
top_score = score;
|
||||
}
|
||||
}
|
||||
|
||||
// randomly pick between the highest scoring sequences ( NOTE: this method of selecting a sequence ignores activity weights )
|
||||
if ( IsInPrediction() )
|
||||
{
|
||||
return topScoring[ SharedRandomInt( "SelectWeightedSequence", 0, topScoring.Count() - 1 ) ];
|
||||
}
|
||||
|
||||
return topScoring[ RandomInt( 0, topScoring.Count() - 1 ) ];
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
@ -449,9 +520,9 @@ int LookupSequence( CStudioHdr *pstudiohdr, const char *label )
|
||||
|
||||
void GetSequenceLinearMotion( CStudioHdr *pstudiohdr, int iSequence, const float poseParameter[], Vector *pVec )
|
||||
{
|
||||
if (! pstudiohdr)
|
||||
if ( !pstudiohdr)
|
||||
{
|
||||
Msg( "Bad pstudiohdr in GetSequenceLinearMotion()!\n" );
|
||||
ExecuteNTimes( 20, Msg( "Bad pstudiohdr in GetSequenceLinearMotion()!\n" ) );
|
||||
return;
|
||||
}
|
||||
|
||||
@ -463,11 +534,7 @@ void GetSequenceLinearMotion( CStudioHdr *pstudiohdr, int iSequence, const float
|
||||
// Don't spam on bogus model
|
||||
if ( pstudiohdr->GetNumSeq() > 0 )
|
||||
{
|
||||
static int msgCount = 0;
|
||||
while ( ++msgCount <= 10 )
|
||||
{
|
||||
Msg( "Bad sequence (%i out of %i max) in GetSequenceLinearMotion() for model '%s'!\n", iSequence, pstudiohdr->GetNumSeq(), pstudiohdr->pszName() );
|
||||
}
|
||||
ExecuteNTimes( 20, Msg( "Bad sequence (%i out of %i max) in GetSequenceLinearMotion() for model '%s'!\n", iSequence, pstudiohdr->GetNumSeq(), pstudiohdr->pszName() ) );
|
||||
}
|
||||
pVec->Init();
|
||||
return;
|
||||
@ -852,7 +919,7 @@ const char *GetBodygroupName( CStudioHdr *pstudiohdr, int iGroup )
|
||||
|
||||
int FindBodygroupByName( CStudioHdr *pstudiohdr, const char *name )
|
||||
{
|
||||
if ( !pstudiohdr )
|
||||
if ( !pstudiohdr || !pstudiohdr->IsValid() )
|
||||
return -1;
|
||||
|
||||
int group;
|
||||
|
@ -269,7 +269,7 @@ void CBasePlayerAnimState::ComputeMainSequence()
|
||||
int animDesired = SelectWeightedSequence( TranslateActivity(idealActivity) );
|
||||
|
||||
#if !defined( HL1_CLIENT_DLL ) && !defined ( HL1_DLL )
|
||||
if ( pPlayer->GetSequenceActivity( pPlayer->GetSequence() ) == pPlayer->GetSequenceActivity( animDesired ) )
|
||||
if ( !ShouldResetMainSequence( pPlayer->GetSequence(), animDesired ) )
|
||||
return;
|
||||
#endif
|
||||
|
||||
@ -289,8 +289,13 @@ void CBasePlayerAnimState::ComputeMainSequence()
|
||||
#endif
|
||||
}
|
||||
|
||||
bool CBasePlayerAnimState::ShouldResetMainSequence( int iCurrentSequence, int iNewSequence )
|
||||
{
|
||||
if ( !GetOuter() )
|
||||
return false;
|
||||
|
||||
|
||||
return GetOuter()->GetSequenceActivity( iCurrentSequence ) != GetOuter()->GetSequenceActivity( iNewSequence );
|
||||
}
|
||||
|
||||
|
||||
void CBasePlayerAnimState::UpdateAimSequenceLayers(
|
||||
|
@ -234,6 +234,7 @@ private:
|
||||
|
||||
void EstimateYaw();
|
||||
|
||||
virtual bool ShouldResetMainSequence( int iCurrentSequence, int iNewSequence );
|
||||
void ComputeMainSequence();
|
||||
void ComputeAimSequence();
|
||||
|
||||
|
@ -90,8 +90,23 @@ bool CBaseCombatCharacter::Weapon_CanSwitchTo( CBaseCombatWeapon *pWeapon )
|
||||
|
||||
if ( m_hActiveWeapon )
|
||||
{
|
||||
if ( !m_hActiveWeapon->CanHolster() )
|
||||
if ( !m_hActiveWeapon->CanHolster() && !pWeapon->ForceWeaponSwitch() )
|
||||
return false;
|
||||
|
||||
if ( IsPlayer() )
|
||||
{
|
||||
CBasePlayer *pPlayer = (CBasePlayer *)this;
|
||||
// check if active weapon force the last weapon to switch
|
||||
if ( m_hActiveWeapon->ForceWeaponSwitch() )
|
||||
{
|
||||
// last weapon wasn't allowed to switch, don't allow to switch to new weapon
|
||||
CBaseCombatWeapon *pLastWeapon = pPlayer->GetLastWeapon();
|
||||
if ( pLastWeapon && pWeapon != pLastWeapon && !pLastWeapon->CanHolster() && !pWeapon->ForceWeaponSwitch() )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
|
@ -1149,7 +1149,7 @@ float CBaseCombatWeapon::GetViewModelSequenceDuration()
|
||||
return vm->SequenceDuration();
|
||||
}
|
||||
|
||||
bool CBaseCombatWeapon::IsViewModelSequenceFinished( void )
|
||||
bool CBaseCombatWeapon::IsViewModelSequenceFinished( void ) const
|
||||
{
|
||||
// These are not valid activities and always complete immediately
|
||||
if ( GetActivity() == ACT_RESET || GetActivity() == ACT_INVALID )
|
||||
@ -1452,7 +1452,12 @@ selects and deploys each weapon as you pass it. (sjb)
|
||||
bool CBaseCombatWeapon::Deploy( )
|
||||
{
|
||||
MDLCACHE_CRITICAL_SECTION();
|
||||
return DefaultDeploy( (char*)GetViewModel(), (char*)GetWorldModel(), GetDrawActivity(), (char*)GetAnimPrefix() );
|
||||
bool bResult = DefaultDeploy( (char*)GetViewModel(), (char*)GetWorldModel(), GetDrawActivity(), (char*)GetAnimPrefix() );
|
||||
|
||||
// override pose parameters
|
||||
PoseParameterOverride( false );
|
||||
|
||||
return bResult;
|
||||
}
|
||||
|
||||
Activity CBaseCombatWeapon::GetDrawActivity( void )
|
||||
@ -1511,6 +1516,9 @@ bool CBaseCombatWeapon::Holster( CBaseCombatWeapon *pSwitchingTo )
|
||||
RescindReloadHudHint();
|
||||
}
|
||||
|
||||
// reset pose parameters
|
||||
PoseParameterOverride( true );
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -1775,8 +1783,8 @@ void CBaseCombatWeapon::ItemPostFrame( void )
|
||||
|
||||
// -----------------------
|
||||
// Reload pressed / Clip Empty
|
||||
// -----------------------
|
||||
if ( ( pOwner->m_nButtons & IN_RELOAD ) && UsesClipsForAmmo1() && !m_bInReload )
|
||||
// Can only start the Reload Cycle after the firing cycle
|
||||
if ( ( pOwner->m_nButtons & IN_RELOAD ) && m_flNextPrimaryAttack <= gpGlobals->curtime && UsesClipsForAmmo1() && !m_bInReload )
|
||||
{
|
||||
// reload when reload is pressed, or if no buttons are down and weapon is empty.
|
||||
Reload();
|
||||
@ -2440,23 +2448,53 @@ bool CBaseCombatWeapon::IsLocked( CBaseEntity *pAsker )
|
||||
//-----------------------------------------------------------------------------
|
||||
Activity CBaseCombatWeapon::ActivityOverride( Activity baseAct, bool *pRequired )
|
||||
{
|
||||
acttable_t *pTable = ActivityList();
|
||||
int actCount = ActivityListCount();
|
||||
int actCount = 0;
|
||||
acttable_t *pTable = ActivityList( actCount );
|
||||
|
||||
for ( int i = 0; i < actCount; i++, pTable++ )
|
||||
for ( int i = 0; i < actCount; i++ )
|
||||
{
|
||||
if ( baseAct == pTable->baseAct )
|
||||
const acttable_t& act = pTable[i];
|
||||
if ( baseAct == act.baseAct )
|
||||
{
|
||||
if (pRequired)
|
||||
{
|
||||
*pRequired = pTable->required;
|
||||
*pRequired = act.required;
|
||||
}
|
||||
return (Activity)pTable->weaponAct;
|
||||
return (Activity)act.weaponAct;
|
||||
}
|
||||
}
|
||||
return baseAct;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void CBaseCombatWeapon::PoseParameterOverride( bool bReset )
|
||||
{
|
||||
CBaseCombatCharacter *pOwner = GetOwner();
|
||||
if ( !pOwner )
|
||||
return;
|
||||
|
||||
CStudioHdr *pStudioHdr = pOwner->GetModelPtr();
|
||||
if ( !pStudioHdr )
|
||||
return;
|
||||
|
||||
int iCount = 0;
|
||||
poseparamtable_t *pPoseParamList = PoseParamList( iCount );
|
||||
if ( pPoseParamList )
|
||||
{
|
||||
for ( int i=0; i<iCount; ++i )
|
||||
{
|
||||
int iPoseParam = pOwner->LookupPoseParameter( pStudioHdr, pPoseParamList[i].pszName );
|
||||
|
||||
if ( iPoseParam != -1 )
|
||||
pOwner->SetPoseParameter( iPoseParam, bReset ? 0 : pPoseParamList[i].flValue );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
@ -2745,6 +2783,13 @@ void* SendProxy_SendNonLocalWeaponDataTable( const SendProp *pProp, const void *
|
||||
}
|
||||
REGISTER_SEND_PROXY_NON_MODIFIED_POINTER( SendProxy_SendNonLocalWeaponDataTable );
|
||||
|
||||
#else
|
||||
void CBaseCombatWeapon::RecvProxy_WeaponState( const CRecvProxyData *pData, void *pStruct, void *pOut )
|
||||
{
|
||||
CBaseCombatWeapon *pWeapon = (CBaseCombatWeapon*)pStruct;
|
||||
pWeapon->m_iState = pData->m_Value.m_Int;
|
||||
pWeapon->UpdateVisibility();
|
||||
}
|
||||
#endif
|
||||
|
||||
#if PREDICTION_ERROR_CHECK_LEVEL > 1
|
||||
@ -2818,7 +2863,7 @@ BEGIN_NETWORK_TABLE(CBaseCombatWeapon, DT_BaseCombatWeapon)
|
||||
RecvPropDataTable("LocalActiveWeaponData", 0, 0, &REFERENCE_RECV_TABLE(DT_LocalActiveWeaponData)),
|
||||
RecvPropInt( RECVINFO(m_iViewModelIndex)),
|
||||
RecvPropInt( RECVINFO(m_iWorldModelIndex)),
|
||||
RecvPropInt( RECVINFO(m_iState )),
|
||||
RecvPropInt( RECVINFO(m_iState), 0, &CBaseCombatWeapon::RecvProxy_WeaponState ),
|
||||
RecvPropEHandle( RECVINFO(m_hOwner ) ),
|
||||
#endif
|
||||
END_NETWORK_TABLE()
|
||||
|
@ -55,8 +55,7 @@ class CUserCmd;
|
||||
// Put this in your derived class definition to declare it's activity table
|
||||
// UNDONE: Cascade these?
|
||||
#define DECLARE_ACTTABLE() static acttable_t m_acttable[];\
|
||||
acttable_t *ActivityList( void );\
|
||||
int ActivityListCount( void );
|
||||
virtual acttable_t *ActivityList( int &iActivityCount ) OVERRIDE;
|
||||
|
||||
// You also need to include the activity table itself in your class' implementation:
|
||||
// e.g.
|
||||
@ -73,8 +72,7 @@ class CUserCmd;
|
||||
// activity table.
|
||||
// UNDONE: Cascade these?
|
||||
#define IMPLEMENT_ACTTABLE(className) \
|
||||
acttable_t *className::ActivityList( void ) { return m_acttable; } \
|
||||
int className::ActivityListCount( void ) { return ARRAYSIZE(m_acttable); } \
|
||||
acttable_t *className::ActivityList( int &iActivityCount ) { iActivityCount = ARRAYSIZE(m_acttable); return m_acttable; }
|
||||
|
||||
typedef struct
|
||||
{
|
||||
@ -83,6 +81,29 @@ typedef struct
|
||||
bool required;
|
||||
} acttable_t;
|
||||
|
||||
|
||||
struct poseparamtable_t
|
||||
{
|
||||
const char *pszName;
|
||||
float flValue;
|
||||
};
|
||||
|
||||
// Put this in your derived class definition to declare it's poseparam table
|
||||
#define DECLARE_POSEPARAMTABLE() static poseparamtable_t m_poseparamtable[];\
|
||||
virtual poseparamtable_t* PoseParamList( int &iPoseParamCount ) { return NULL; }
|
||||
|
||||
// You also need to include the activity table itself in your class' implementation:
|
||||
// e.g.
|
||||
// acttable_t CTFGrapplingHook::m_poseparamtable[] =
|
||||
// {
|
||||
// { "r_arm", 2 },
|
||||
// };
|
||||
//
|
||||
// The grapplinghook overrides the r_arm pose param, value to 2.
|
||||
|
||||
#define IMPLEMENT_POSEPARAMTABLE(className)\
|
||||
poseparamtable_t* className::PoseParamList( int &iPoseParamCount ) { iPoseParamCount = ARRAYSIZE(m_poseparamtable); return m_poseparamtable; }
|
||||
|
||||
class CHudTexture;
|
||||
class Color;
|
||||
|
||||
@ -208,7 +229,7 @@ public:
|
||||
virtual bool SendWeaponAnim( int iActivity );
|
||||
virtual void SendViewModelAnim( int nSequence );
|
||||
float GetViewModelSequenceDuration(); // Return how long the current view model sequence is.
|
||||
bool IsViewModelSequenceFinished( void ); // Returns if the viewmodel's current animation is finished
|
||||
bool IsViewModelSequenceFinished( void ) const; // Returns if the viewmodel's current animation is finished
|
||||
|
||||
virtual void SetViewModel();
|
||||
|
||||
@ -224,7 +245,7 @@ public:
|
||||
bool UsesSecondaryAmmo( void ); // returns true if the weapon actually uses secondary ammo
|
||||
void GiveDefaultAmmo( void );
|
||||
|
||||
virtual bool CanHolster( void ) { return TRUE; }; // returns true if the weapon can be holstered
|
||||
virtual bool CanHolster( void ) const { return TRUE; }; // returns true if the weapon can be holstered
|
||||
virtual bool DefaultDeploy( char *szViewModel, char *szWeaponModel, int iActivity, char *szAnimExt );
|
||||
virtual bool CanDeploy( void ) { return true; } // return true if the weapon's allowed to deploy
|
||||
virtual bool Deploy( void ); // returns true is deploy was successful
|
||||
@ -266,8 +287,7 @@ public:
|
||||
bool DefaultReload( int iClipSize1, int iClipSize2, int iActivity );
|
||||
bool ReloadsSingly( void ) const;
|
||||
|
||||
virtual bool AutoFiresFullClip( void ) { return false; }
|
||||
virtual bool CanOverload( void ) { return false; }
|
||||
virtual bool AutoFiresFullClip( void ) const { return false; }
|
||||
virtual void UpdateAutoFire( void );
|
||||
|
||||
// Weapon firing
|
||||
@ -308,7 +328,7 @@ public:
|
||||
|
||||
virtual void SetActivity( Activity act, float duration );
|
||||
inline void SetActivity( Activity eActivity ) { m_Activity = eActivity; }
|
||||
inline Activity GetActivity( void ) { return m_Activity; }
|
||||
inline Activity GetActivity( void ) const { return m_Activity; }
|
||||
|
||||
virtual void AddViewKick( void ); // Add in the view kick for the weapon
|
||||
|
||||
@ -349,6 +369,7 @@ public:
|
||||
virtual int GetWeight( void ) const;
|
||||
virtual bool AllowsAutoSwitchTo( void ) const;
|
||||
virtual bool AllowsAutoSwitchFrom( void ) const;
|
||||
virtual bool ForceWeaponSwitch( void ) const { return false; }
|
||||
virtual int GetWeaponFlags( void ) const;
|
||||
virtual int GetSlot( void ) const;
|
||||
virtual int GetPosition( void ) const;
|
||||
@ -387,8 +408,10 @@ public:
|
||||
virtual CHudTexture const *GetSpriteZoomedAutoaim( void ) const;
|
||||
|
||||
virtual Activity ActivityOverride( Activity baseAct, bool *pRequired );
|
||||
virtual acttable_t* ActivityList( void ) { return NULL; }
|
||||
virtual int ActivityListCount( void ) { return 0; }
|
||||
virtual acttable_t* ActivityList( int &iActivityCount ) { return NULL; }
|
||||
|
||||
virtual void PoseParameterOverride( bool bReset );
|
||||
virtual poseparamtable_t* PoseParamList( int &iPoseParamCount ) { return NULL; }
|
||||
|
||||
virtual void Activate( void );
|
||||
|
||||
@ -577,6 +600,9 @@ public:
|
||||
|
||||
IMPLEMENT_NETWORK_VAR_FOR_DERIVED( m_nNextThinkTick );
|
||||
|
||||
#ifdef CLIENT_DLL
|
||||
static void RecvProxy_WeaponState( const CRecvProxyData *pData, void *pStruct, void *pOut );
|
||||
#endif
|
||||
int WeaponState() const { return m_iState; }
|
||||
|
||||
// Weapon data
|
||||
|
@ -636,10 +636,17 @@ void CBaseEntity::SetPredictionRandomSeed( const CUserCmd *cmd )
|
||||
if ( !cmd )
|
||||
{
|
||||
m_nPredictionRandomSeed = -1;
|
||||
#ifdef GAME_DLL
|
||||
m_nPredictionRandomSeedServer = -1;
|
||||
#endif
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
m_nPredictionRandomSeed = ( cmd->random_seed );
|
||||
#ifdef GAME_DLL
|
||||
m_nPredictionRandomSeedServer = ( cmd->server_random_seed );
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
@ -1679,7 +1686,7 @@ void CBaseEntity::FireBullets( const FireBulletsInfo_t &info )
|
||||
int iSeed = 0;
|
||||
if ( IsPlayer() )
|
||||
{
|
||||
iSeed = CBaseEntity::GetPredictionRandomSeed() & 255;
|
||||
iSeed = CBaseEntity::GetPredictionRandomSeed( info.m_bUseServerRandomSeed ) & 255;
|
||||
}
|
||||
|
||||
#if defined( HL2MP ) && defined( GAME_DLL )
|
||||
|
@ -119,9 +119,13 @@ inline CBaseEntity *CBaseEntity::GetEffectEntity() const
|
||||
return m_hEffectEntity.Get();
|
||||
}
|
||||
|
||||
inline int CBaseEntity::GetPredictionRandomSeed( void )
|
||||
inline int CBaseEntity::GetPredictionRandomSeed( bool bUseUnSyncedServerPlatTime )
|
||||
{
|
||||
#ifdef GAME_DLL
|
||||
return bUseUnSyncedServerPlatTime ? m_nPredictionRandomSeedServer : m_nPredictionRandomSeed;
|
||||
#else
|
||||
return m_nPredictionRandomSeed;
|
||||
#endif
|
||||
}
|
||||
|
||||
inline CBasePlayer *CBaseEntity::GetPredictionPlayer( void )
|
||||
|
@ -342,7 +342,7 @@ Vector CBasePlayer::EyePosition( )
|
||||
#ifdef CLIENT_DLL
|
||||
if ( IsObserver() )
|
||||
{
|
||||
if ( GetObserverMode() == OBS_MODE_CHASE )
|
||||
if ( GetObserverMode() == OBS_MODE_CHASE || GetObserverMode() == OBS_MODE_POI )
|
||||
{
|
||||
if ( IsLocalPlayer() )
|
||||
{
|
||||
@ -1035,7 +1035,7 @@ void CBasePlayer::SelectItem( const char *pstr, int iSubType )
|
||||
// Make sure the current weapon can be holstered
|
||||
if ( GetActiveWeapon() )
|
||||
{
|
||||
if ( !GetActiveWeapon()->CanHolster() )
|
||||
if ( !GetActiveWeapon()->CanHolster() && !pItem->ForceWeaponSwitch() )
|
||||
return;
|
||||
|
||||
ResetAutoaim( );
|
||||
@ -1703,6 +1703,7 @@ void CBasePlayer::CalcObserverView( Vector& eyeOrigin, QAngle& eyeAngles, float&
|
||||
case OBS_MODE_IN_EYE : CalcInEyeCamView( eyeOrigin, eyeAngles, fov );
|
||||
break;
|
||||
|
||||
case OBS_MODE_POI : // PASSTIME
|
||||
case OBS_MODE_CHASE : CalcChaseCamView( eyeOrigin, eyeAngles, fov );
|
||||
break;
|
||||
|
||||
|
@ -20,6 +20,11 @@ BEGIN_NETWORK_TABLE( CBaseProjectile, DT_BaseProjectile )
|
||||
END_NETWORK_TABLE()
|
||||
|
||||
|
||||
#ifndef CLIENT_DLL
|
||||
IMPLEMENT_AUTO_LIST( IBaseProjectileAutoList );
|
||||
#endif // !CLIENT_DLL
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Constructor.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
@ -28,7 +28,12 @@
|
||||
// Base Projectile.
|
||||
//
|
||||
//=============================================================================
|
||||
#ifdef CLIENT_DLL
|
||||
class CBaseProjectile : public CBaseAnimating
|
||||
#else // CLIENT_DLL
|
||||
DECLARE_AUTO_LIST( IBaseProjectileAutoList );
|
||||
class CBaseProjectile : public CBaseAnimating, public IBaseProjectileAutoList
|
||||
#endif // !CLIENT_DLL
|
||||
{
|
||||
public:
|
||||
DECLARE_CLASS( CBaseProjectile, CBaseAnimating );
|
||||
@ -39,10 +44,12 @@ public:
|
||||
virtual void Spawn();
|
||||
|
||||
#ifdef GAME_DLL
|
||||
virtual int GetBaseProjectileType() const { return -1; } // no base
|
||||
virtual int GetProjectileType() const { return -1; } // no type
|
||||
virtual int GetDestroyableHitCount( void ) const { return m_iDestroyableHitCount; }
|
||||
void IncrementDestroyableHitCount( void ) { ++m_iDestroyableHitCount; }
|
||||
|
||||
bool CanCollideWithTeammates() const { return m_bCanCollideWithTeammates; }
|
||||
virtual bool CanCollideWithTeammates() const { return m_bCanCollideWithTeammates; }
|
||||
virtual float GetCollideWithTeammatesDelay() const { return 0.25f; }
|
||||
#endif // GAME_DLL
|
||||
|
||||
|
@ -21,10 +21,6 @@ static Vector CAM_HULL_MAX( CAM_HULL_OFFSET, CAM_HULL_OFFSET, CAM_HULL_OFFSET);
|
||||
|
||||
extern const ConVar *sv_cheats;
|
||||
|
||||
extern ConVar cam_idealdist;
|
||||
extern ConVar cam_idealdistright;
|
||||
extern ConVar cam_idealdistup;
|
||||
|
||||
void CAM_ToThirdPerson(void);
|
||||
void CAM_ToFirstPerson(void);
|
||||
|
||||
@ -103,16 +99,6 @@ void CThirdPersonManager::Update( void )
|
||||
|
||||
}
|
||||
|
||||
Vector CThirdPersonManager::GetDesiredCameraOffset( void )
|
||||
{
|
||||
if ( IsOverridingThirdPerson() == true )
|
||||
{
|
||||
return Vector( cam_idealdist.GetFloat(), cam_idealdistright.GetFloat(), cam_idealdistup.GetFloat() );
|
||||
}
|
||||
|
||||
return m_vecDesiredCameraOffset;
|
||||
}
|
||||
|
||||
Vector CThirdPersonManager::GetFinalCameraOffset( void )
|
||||
{
|
||||
Vector vDesired = GetDesiredCameraOffset();
|
||||
@ -157,7 +143,7 @@ Vector CThirdPersonManager::GetDistanceFraction( void )
|
||||
return Vector( flFraction, flFraction, flUpFraction );
|
||||
}
|
||||
|
||||
void CThirdPersonManager::PositionCamera( CBasePlayer *pPlayer, QAngle angles )
|
||||
void CThirdPersonManager::PositionCamera( CBasePlayer *pPlayer, const QAngle& angles )
|
||||
{
|
||||
if ( pPlayer )
|
||||
{
|
||||
|
@ -42,25 +42,25 @@ class CThirdPersonManager
|
||||
public:
|
||||
|
||||
CThirdPersonManager();
|
||||
void SetCameraOffsetAngles( Vector vecOffset ) { m_vecCameraOffset = vecOffset; }
|
||||
Vector GetCameraOffsetAngles( void ) { return m_vecCameraOffset; }
|
||||
void SetCameraOffsetAngles( const Vector& vecOffset ) { m_vecCameraOffset = vecOffset; }
|
||||
const Vector& GetCameraOffsetAngles( void ) const { return m_vecCameraOffset; }
|
||||
|
||||
void SetDesiredCameraOffset( Vector vecOffset ) { m_vecDesiredCameraOffset = vecOffset; }
|
||||
Vector GetDesiredCameraOffset( void );
|
||||
void SetDesiredCameraOffset( const Vector& vecOffset ) { m_vecDesiredCameraOffset = vecOffset; }
|
||||
const Vector& GetDesiredCameraOffset( void ) const { return m_vecDesiredCameraOffset; }
|
||||
|
||||
Vector GetFinalCameraOffset( void );
|
||||
|
||||
void SetCameraOrigin( Vector vecOffset ) { m_vecCameraOrigin = vecOffset; }
|
||||
Vector GetCameraOrigin( void ) { return m_vecCameraOrigin; }
|
||||
void SetCameraOrigin( const Vector& vecOffset ) { m_vecCameraOrigin = vecOffset; }
|
||||
const Vector& GetCameraOrigin( void ) const { return m_vecCameraOrigin; }
|
||||
|
||||
void Update( void );
|
||||
|
||||
void PositionCamera( CBasePlayer *pPlayer, QAngle angles );
|
||||
void PositionCamera( CBasePlayer *pPlayer, const QAngle& angles );
|
||||
|
||||
void UseCameraOffsets( bool bUse ) { m_bUseCameraOffsets = bUse; }
|
||||
bool UsingCameraOffsets( void ) { return m_bUseCameraOffsets; }
|
||||
|
||||
QAngle GetCameraViewAngles( void ) { return m_ViewAngles; }
|
||||
const QAngle& GetCameraViewAngles( void ) const { return m_ViewAngles; }
|
||||
|
||||
Vector GetDistanceFraction( void );
|
||||
|
||||
|
@ -116,7 +116,7 @@
|
||||
|
||||
SendPropInt( SENDINFO_NOCHECK( m_nMaterial ), MAX_MODEL_INDEX_BITS, SPROP_UNSIGNED ),
|
||||
SendPropInt( SENDINFO_NOCHECK( m_nDamageType ), 32, SPROP_UNSIGNED ),
|
||||
SendPropInt( SENDINFO_NOCHECK( m_nHitBox ), 11, SPROP_UNSIGNED ),
|
||||
SendPropInt( SENDINFO_NOCHECK( m_nHitBox ), 12, SPROP_UNSIGNED ),
|
||||
|
||||
SendPropInt( SENDINFO_NAME( m_nEntIndex, entindex ), MAX_EDICT_BITS, SPROP_UNSIGNED ),
|
||||
|
||||
|
@ -249,4 +249,7 @@ void EventList_RegisterSharedEvents( void )
|
||||
|
||||
REGISTER_SHARED_ANIMEVENT( AE_WPN_PLAYWPNSOUND, AE_TYPE_CLIENT | AE_TYPE_SERVER );
|
||||
REGISTER_SHARED_ANIMEVENT( AE_RD_ROBOT_POP_PANELS_OFF, AE_TYPE_CLIENT | AE_TYPE_SERVER );
|
||||
|
||||
REGISTER_SHARED_ANIMEVENT( AE_TAUNT_ENABLE_MOVE, AE_TYPE_CLIENT | AE_TYPE_SERVER );
|
||||
REGISTER_SHARED_ANIMEVENT( AE_TAUNT_DISABLE_MOVE, AE_TYPE_CLIENT | AE_TYPE_SERVER );
|
||||
}
|
@ -87,6 +87,9 @@ typedef enum
|
||||
|
||||
AE_RD_ROBOT_POP_PANELS_OFF,
|
||||
|
||||
AE_TAUNT_ENABLE_MOVE,
|
||||
AE_TAUNT_DISABLE_MOVE,
|
||||
|
||||
LAST_SHARED_ANIMEVENT,
|
||||
} Animevent;
|
||||
|
||||
|
@ -69,6 +69,7 @@ private:
|
||||
class ICurveDataAccessor
|
||||
{
|
||||
public:
|
||||
virtual ~ICurveDataAccessor(){}
|
||||
virtual float GetDuration() = 0;
|
||||
virtual bool CurveHasEndTime() = 0; // only matters for events
|
||||
virtual int GetDefaultCurveType() = 0;
|
||||
|
@ -2147,7 +2147,7 @@ void CGameMovement::FullObserverMove( void )
|
||||
{
|
||||
int mode = player->GetObserverMode();
|
||||
|
||||
if ( mode == OBS_MODE_IN_EYE || mode == OBS_MODE_CHASE )
|
||||
if ( mode == OBS_MODE_IN_EYE || mode == OBS_MODE_CHASE || mode == OBS_MODE_POI )
|
||||
{
|
||||
CBaseEntity * target = player->GetObserverTarget();
|
||||
|
||||
|
@ -418,6 +418,8 @@ public:
|
||||
|
||||
virtual bool IsHolidayActive( /*EHoliday*/ int eHoliday ) const { return false; }
|
||||
|
||||
virtual bool IsManualMapChangeOkay( const char **pszReason ){ return true; }
|
||||
|
||||
#ifndef CLIENT_DLL
|
||||
private:
|
||||
float m_flNextVerboseLogOutput;
|
||||
|
@ -158,6 +158,7 @@ const char *g_pszMPConcepts[] =
|
||||
"TLK_PLAYER_CAST_MONOCULOUS", // MP_CONCEPT_PLAYER_CAST_MONOCULOUS
|
||||
"TLK_PLAYER_CAST_METEOR_SWARM", // MP_CONCEPT_PLAYER_CAST_METEOR_SWARM
|
||||
"TLK_PLAYER_CAST_SKELETON_HORDE", // MP_CONCEPT_PLAYER_CAST_SKELETON_HORDE
|
||||
"TLK_PLAYER_CAST_BOMB_HEAD_CURSE", // MP_CONCEPT_PLAYER_CAST_BOMB_HEAD_CURSE
|
||||
|
||||
"TLK_PLAYER_SPELL_FIREBALL", // MP_CONCEPT_PLAYER_SPELL_FIREBALL
|
||||
"TLK_PLAYER_SPELL_MERASMUS_ZAP", // MP_CONCEPT_PLAYER_SPELL_MERASMUS_ZAP
|
||||
@ -171,6 +172,7 @@ const char *g_pszMPConcepts[] =
|
||||
"TLK_PLAYER_SPELL_MONOCULOUS", // MP_CONCEPT_PLAYER_SPELL_MONOCULOUS
|
||||
"TLK_PLAYER_SPELL_METEOR_SWARM", // MP_CONCEPT_PLAYER_SPELL_METEOR_SWARM
|
||||
"TLK_PLAYER_SPELL_SKELETON_HORDE", // MP_CONCEPT_PLAYER_SPELL_SKELETON_HORDE
|
||||
"TLK_PLAYER_SPELL_BOMB_HEAD_CURSE", // MP_CONCEPT_PLAYER_SPELL_BOMB_HEAD_CURSE
|
||||
|
||||
// Events.
|
||||
"TLK_PLAYER_SPELL_PICKUP_COMMON", // MP_CONCEPT_PLAYER_SPELL_PICKUP_COMMON
|
||||
@ -189,6 +191,8 @@ const char *g_pszMPConcepts[] =
|
||||
"TLK_TAUNT_EUREKA_EFFECT", // MP_CONCEPT_TAUNT_EUREKA_EFFECT_TELEPORT
|
||||
|
||||
"TLK_COMBO_KILLED", // MP_CONCEPT_COMBO_KILLED
|
||||
|
||||
"TLK_PLAYER_ASK_FOR_BALL", // MP_CONCEPT_PLAYER_ASK_FOR_BALL
|
||||
};
|
||||
COMPILE_TIME_ASSERT( ARRAYSIZE( g_pszMPConcepts ) == MP_TF_CONCEPT_COUNT );
|
||||
|
||||
|
@ -167,6 +167,7 @@ enum
|
||||
MP_CONCEPT_PLAYER_CAST_MONOCULOUS, // "TLK_PLAYER_CAST_MONOCULOUS"
|
||||
MP_CONCEPT_PLAYER_CAST_METEOR_SWARM, // "TLK_PLAYER_CAST_METEOR_SWARM"
|
||||
MP_CONCEPT_PLAYER_CAST_SKELETON_HORDE, // "TLK_PLAYER_CAST_SKELETON_HORDE"
|
||||
MP_CONCEPT_PLAYER_CAST_BOMB_HEAD_CURSE, // "TLK_PLAYER_CAST_BOMB_HEAD_CURSE"
|
||||
|
||||
MP_CONCEPT_PLAYER_SPELL_FIREBALL, // "TLK_PLAYER_SPELL_FIREBALL"
|
||||
MP_CONCEPT_PLAYER_SPELL_MERASMUS_ZAP, // "TLK_PLAYER_SPELL_MERASMUS_ZAP"
|
||||
@ -180,6 +181,7 @@ enum
|
||||
MP_CONCEPT_PLAYER_SPELL_MONOCULOUS, // "TLK_PLAYER_SPELL_MONOCULOUS"
|
||||
MP_CONCEPT_PLAYER_SPELL_METEOR_SWARM, // "TLK_PLAYER_SPELL_METEOR_SWARM"
|
||||
MP_CONCEPT_PLAYER_SPELL_SKELETON_HORDE, // "TLK_PLAYER_SPELL_SKELETON_HORDE"
|
||||
MP_CONCEPT_PLAYER_SPELL_BOMB_HEAD_CURSE, // "TLK_PLAYER_SPELL_BOMB_HEAD_CURSE"
|
||||
|
||||
// Events.
|
||||
MP_CONCEPT_PLAYER_SPELL_PICKUP_COMMON, // "TLK_PLAYER_SPELL_PICKUP_COMMON"
|
||||
@ -198,6 +200,7 @@ enum
|
||||
MP_CONCEPT_TAUNT_EUREKA_EFFECT_TELEPORT,// "TLK_TAUNT_EUREKA_EFFECT"
|
||||
|
||||
MP_CONCEPT_COMBO_KILLED, // "TLK_COMBO_KILLED"
|
||||
MP_CONCEPT_PLAYER_ASK_FOR_BALL, // "TLK_PLAYER_ASK_FOR_BALL"
|
||||
|
||||
MP_TF_CONCEPT_COUNT
|
||||
|
||||
|
@ -85,7 +85,8 @@ ConVar mp_show_voice_icons( "mp_show_voice_icons", "1", FCVAR_REPLICATED, "Show
|
||||
|
||||
#ifdef GAME_DLL
|
||||
|
||||
ConVar tv_delaymapchange( "tv_delaymapchange", "0", 0, "Delays map change until broadcast is complete" );
|
||||
ConVar tv_delaymapchange( "tv_delaymapchange", "0", FCVAR_NONE, "Delays map change until broadcast is complete" );
|
||||
ConVar tv_delaymapchange_protect( "tv_delaymapchange_protect", "1", FCVAR_NONE, "Protect against doing a manual map change if HLTV is broadcasting and has not caught up with a major game event such as round_end" );
|
||||
|
||||
ConVar mp_restartgame( "mp_restartgame", "0", FCVAR_GAMEDLL, "If non-zero, game will restart in the specified number of seconds" );
|
||||
ConVar mp_restartgame_immediate( "mp_restartgame_immediate", "0", FCVAR_GAMEDLL, "If non-zero, game will restart immediately" );
|
||||
@ -278,7 +279,7 @@ CMultiplayRules::CMultiplayRules()
|
||||
|
||||
if ( cfgfile && cfgfile[0] )
|
||||
{
|
||||
char szCommand[256];
|
||||
char szCommand[MAX_PATH];
|
||||
|
||||
Log( "Executing dedicated server config file %s\n", cfgfile );
|
||||
Q_snprintf( szCommand,sizeof(szCommand), "exec %s\n", cfgfile );
|
||||
@ -292,7 +293,7 @@ CMultiplayRules::CMultiplayRules()
|
||||
|
||||
if ( cfgfile && cfgfile[0] )
|
||||
{
|
||||
char szCommand[256];
|
||||
char szCommand[MAX_PATH];
|
||||
|
||||
Log( "Executing listen server config file %s\n", cfgfile );
|
||||
Q_snprintf( szCommand,sizeof(szCommand), "exec %s\n", cfgfile );
|
||||
@ -1164,7 +1165,7 @@ ConVarRef suitcharger( "sk_suitcharger" );
|
||||
|
||||
void CMultiplayRules::GetNextLevelName( char *pszNextMap, int bufsize, bool bRandom /* = false */ )
|
||||
{
|
||||
char mapcfile[256];
|
||||
char mapcfile[MAX_PATH];
|
||||
DetermineMapCycleFilename( mapcfile, sizeof(mapcfile), false );
|
||||
|
||||
// Check the time of the mapcycle file and re-populate the list of level names if the file has been modified
|
||||
@ -1182,10 +1183,7 @@ ConVarRef suitcharger( "sk_suitcharger" );
|
||||
// If map cycle file has changed or this is the first time through ...
|
||||
if ( m_nMapCycleTimeStamp != nMapCycleTimeStamp )
|
||||
{
|
||||
// Reset map index and map cycle timestamp
|
||||
m_nMapCycleTimeStamp = nMapCycleTimeStamp;
|
||||
m_nMapCycleindex = 0;
|
||||
|
||||
// Reload
|
||||
LoadMapCycleFile();
|
||||
}
|
||||
}
|
||||
@ -1209,7 +1207,7 @@ ConVarRef suitcharger( "sk_suitcharger" );
|
||||
|
||||
void CMultiplayRules::DetermineMapCycleFilename( char *pszResult, int nSizeResult, bool bForceSpew )
|
||||
{
|
||||
static char szLastResult[ 256];
|
||||
static char szLastResult[ MAX_PATH ];
|
||||
|
||||
const char *pszVar = mapcyclefile.GetString();
|
||||
if ( *pszVar == '\0' )
|
||||
@ -1223,7 +1221,7 @@ ConVarRef suitcharger( "sk_suitcharger" );
|
||||
return;
|
||||
}
|
||||
|
||||
char szRecommendedName[ 256 ];
|
||||
char szRecommendedName[ MAX_PATH ];
|
||||
V_sprintf_safe( szRecommendedName, "cfg/%s", pszVar );
|
||||
|
||||
// First, look for a mapcycle file in the cfg directory, which is preferred
|
||||
@ -1274,7 +1272,12 @@ ConVarRef suitcharger( "sk_suitcharger" );
|
||||
}
|
||||
}
|
||||
|
||||
void CMultiplayRules::LoapMapCycleFileIntoVector( const char *pszMapCycleFile, CUtlVector<char *> &mapList )
|
||||
void CMultiplayRules::LoadMapCycleFileIntoVector( const char *pszMapCycleFile, CUtlVector<char *> &mapList )
|
||||
{
|
||||
CMultiplayRules::RawLoadMapCycleFileIntoVector( pszMapCycleFile, mapList );
|
||||
}
|
||||
|
||||
void CMultiplayRules::RawLoadMapCycleFileIntoVector( const char *pszMapCycleFile, CUtlVector<char *> &mapList )
|
||||
{
|
||||
CUtlBuffer buf;
|
||||
if ( !filesystem->ReadFile( pszMapCycleFile, "GAME", buf ) )
|
||||
@ -1293,13 +1296,6 @@ ConVarRef suitcharger( "sk_suitcharger" );
|
||||
{
|
||||
bIgnore = true;
|
||||
}
|
||||
else if ( !engine->IsMapValid( mapList[i] ) )
|
||||
{
|
||||
bIgnore = true;
|
||||
|
||||
// If the engine doesn't consider it a valid map remove it from the lists
|
||||
Warning( "Invalid map '%s' included in map cycle file. Ignored.\n", mapList[i] );
|
||||
}
|
||||
|
||||
if ( bIgnore )
|
||||
{
|
||||
@ -1321,6 +1317,27 @@ ConVarRef suitcharger( "sk_suitcharger" );
|
||||
mapList.RemoveAll();
|
||||
}
|
||||
|
||||
bool CMultiplayRules::IsManualMapChangeOkay( const char **pszReason )
|
||||
{
|
||||
if ( HLTVDirector()->IsActive() && ( HLTVDirector()->GetDelay() >= HLTV_MIN_DIRECTOR_DELAY ) )
|
||||
{
|
||||
if ( tv_delaymapchange.GetBool() && tv_delaymapchange_protect.GetBool() )
|
||||
{
|
||||
float flLastEvent = GetLastMajorEventTime();
|
||||
if ( flLastEvent > -1 )
|
||||
{
|
||||
if ( flLastEvent > ( gpGlobals->curtime - ( HLTVDirector()->GetDelay() + 3 ) ) ) // +3 second delay to prevent instant change after a major event
|
||||
{
|
||||
*pszReason = "\n***WARNING*** Map change blocked. HLTV is broadcasting and has not caught up to the last major game event yet.\nYou can disable this check by setting the value of the server convar \"tv_delaymapchange_protect\" to 0.\n";
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CMultiplayRules::IsMapInMapCycle( const char *pszName )
|
||||
{
|
||||
for ( int i = 0; i < m_MapList.Count(); i++ )
|
||||
@ -1338,7 +1355,7 @@ ConVarRef suitcharger( "sk_suitcharger" );
|
||||
{
|
||||
char szNextMap[MAX_MAP_NAME];
|
||||
|
||||
if ( nextlevel.GetString() && *nextlevel.GetString() && engine->IsMapValid( nextlevel.GetString() ) )
|
||||
if ( nextlevel.GetString() && *nextlevel.GetString() )
|
||||
{
|
||||
Q_strncpy( szNextMap, nextlevel.GetString(), sizeof( szNextMap ) );
|
||||
}
|
||||
@ -1353,13 +1370,19 @@ ConVarRef suitcharger( "sk_suitcharger" );
|
||||
|
||||
void CMultiplayRules::LoadMapCycleFile( void )
|
||||
{
|
||||
char mapcfile[256];
|
||||
int nOldCycleIndex = m_nMapCycleindex;
|
||||
m_nMapCycleindex = 0;
|
||||
|
||||
char mapcfile[MAX_PATH];
|
||||
DetermineMapCycleFilename( mapcfile, sizeof(mapcfile), false );
|
||||
|
||||
FreeMapCycleFileVector( m_MapList );
|
||||
|
||||
const int nMapCycleTimeStamp = filesystem->GetPathTime( mapcfile, "GAME" );
|
||||
m_nMapCycleTimeStamp = nMapCycleTimeStamp;
|
||||
|
||||
// Repopulate map list from mapcycle file
|
||||
LoapMapCycleFileIntoVector( mapcfile, m_MapList );
|
||||
LoadMapCycleFileIntoVector( mapcfile, m_MapList );
|
||||
|
||||
// Load server's mapcycle into network string table for client-side voting
|
||||
if ( g_pStringTableServerMapCycle )
|
||||
@ -1466,16 +1489,29 @@ ConVarRef suitcharger( "sk_suitcharger" );
|
||||
}
|
||||
#endif
|
||||
|
||||
// If the current map selection is in the list, set m_nMapCycleindex to the map that follows it.
|
||||
for ( int i = 0; i < m_MapList.Count(); i++ )
|
||||
// If the current map is in the same location in the new map cycle, keep that index. This gives better behavior
|
||||
// when reloading a map cycle that has the current map in it multiple times.
|
||||
int nOldPreviousMap = ( nOldCycleIndex == 0 ) ? ( m_MapList.Count() - 1 ) : ( nOldCycleIndex - 1 );
|
||||
if ( nOldCycleIndex >= 0 && nOldCycleIndex < m_MapList.Count() &&
|
||||
nOldPreviousMap >= 0 && nOldPreviousMap < m_MapList.Count() &&
|
||||
V_strcmp( STRING( gpGlobals->mapname ), m_MapList[ nOldPreviousMap ] ) == 0 )
|
||||
{
|
||||
if ( V_strcmp( STRING( gpGlobals->mapname ), m_MapList[i] ) == 0 )
|
||||
// The old index is still valid, and falls after our current map in the new cycle, use it
|
||||
m_nMapCycleindex = nOldCycleIndex;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Otherwise, if the current map selection is in the list, set m_nMapCycleindex to the map that follows it.
|
||||
for ( int i = 0; i < m_MapList.Count(); i++ )
|
||||
{
|
||||
m_nMapCycleindex = i;
|
||||
IncrementMapCycleIndex();
|
||||
break;
|
||||
if ( V_strcmp( STRING( gpGlobals->mapname ), m_MapList[i] ) == 0 )
|
||||
{
|
||||
m_nMapCycleindex = i;
|
||||
IncrementMapCycleIndex();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CMultiplayRules::ChangeLevelToMap( const char *pszMap )
|
||||
@ -1556,7 +1592,7 @@ ConVarRef suitcharger( "sk_suitcharger" );
|
||||
|
||||
Msg( "Skipping: %s\tNext map: %s\n", szSkippedMap, szNextMap );
|
||||
|
||||
if ( nextlevel.GetString() && *nextlevel.GetString() && engine->IsMapValid( nextlevel.GetString() ) )
|
||||
if ( nextlevel.GetString() && *nextlevel.GetString() )
|
||||
{
|
||||
Msg( "Warning! \"nextlevel\" is set to \"%s\" and will override the next map to be played.\n", nextlevel.GetString() );
|
||||
}
|
||||
@ -1624,10 +1660,6 @@ ConVarRef suitcharger( "sk_suitcharger" );
|
||||
pPlayer->OnAchievementEarned( nAchievementID );
|
||||
}
|
||||
}
|
||||
else if ( FStrEq( pszCommand, "SendServerMapCycle" ) )
|
||||
{
|
||||
LoadMapCycleFile();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -239,20 +239,26 @@ public:
|
||||
virtual void GetNextLevelName( char *szNextMap, int bufsize, bool bRandom = false );
|
||||
|
||||
static void DetermineMapCycleFilename( char *pszResult, int nSizeResult, bool bForceSpew );
|
||||
static void LoapMapCycleFileIntoVector ( const char *pszMapCycleFile, CUtlVector<char *> &mapList );
|
||||
virtual void LoadMapCycleFileIntoVector ( const char *pszMapCycleFile, CUtlVector<char *> &mapList );
|
||||
static void FreeMapCycleFileVector ( CUtlVector<char *> &mapList );
|
||||
|
||||
// LoadMapCycleFileIntoVector without the fixups inherited versions of gamerules may provide
|
||||
static void RawLoadMapCycleFileIntoVector ( const char *pszMapCycleFile, CUtlVector<char *> &mapList );
|
||||
|
||||
bool IsMapInMapCycle( const char *pszName );
|
||||
|
||||
virtual bool IsManualMapChangeOkay( const char **pszReason ) OVERRIDE;
|
||||
|
||||
protected:
|
||||
virtual bool UseSuicidePenalty() { return true; } // apply point penalty for suicide?
|
||||
virtual float GetLastMajorEventTime( void ){ return -1.0f; }
|
||||
|
||||
public:
|
||||
virtual void ChangeLevel( void );
|
||||
|
||||
protected:
|
||||
virtual void GoToIntermission( void );
|
||||
void LoadMapCycleFile( void );
|
||||
virtual void LoadMapCycleFile( void );
|
||||
void ChangeLevelToMap( const char *pszMap );
|
||||
|
||||
float m_flIntermissionEndTime;
|
||||
|
@ -567,4 +567,37 @@ void StopParticleEffects( CBaseEntity *pEntity )
|
||||
}
|
||||
static ConCommand particle_test_stop("particle_test_stop", CC_Particle_Test_Stop, "Stops all particle systems on the selected entities.\n\tArguments: {entity_name} / {class_name} / no argument picks what player is looking at ", FCVAR_CHEAT);
|
||||
|
||||
#endif //CLIENT_DLL
|
||||
#endif //!CLIENT_DLL
|
||||
|
||||
#if defined( CLIENT_DLL ) && defined( STAGING_ONLY )
|
||||
|
||||
void CC_DispatchParticle( const CCommand& args )
|
||||
{
|
||||
C_BasePlayer *pLocalPlayer = C_BasePlayer::GetLocalPlayer();
|
||||
if ( !pLocalPlayer )
|
||||
return;
|
||||
|
||||
if ( args.ArgC() < 2 )
|
||||
{
|
||||
DevMsg( "Use: dispatch_particle {particle_name} {surface_offset_distance}\n" );
|
||||
return;
|
||||
}
|
||||
|
||||
float flSurfaceOffsetDistance = 0.f;
|
||||
if ( args.ArgC() == 3 )
|
||||
{
|
||||
flSurfaceOffsetDistance = atof( args[2] );
|
||||
}
|
||||
|
||||
Vector vForward;
|
||||
pLocalPlayer->GetVectors( &vForward, NULL, NULL );
|
||||
trace_t tr;
|
||||
UTIL_TraceLine( pLocalPlayer->EyePosition(), pLocalPlayer->EyePosition() + vForward * 3000, MASK_SOLID_BRUSHONLY, NULL, &tr );
|
||||
|
||||
Vector vTargetDeathPos = tr.endpos;
|
||||
DispatchParticleEffect( args[1], vTargetDeathPos + flSurfaceOffsetDistance * tr.plane.normal, vec3_angle );
|
||||
}
|
||||
|
||||
static ConCommand dispatch_particle( "dispatch_particle", CC_DispatchParticle, "Dispatch specified particle effect 50 units away from the lookat surface normal.\n\tArguments: {particle_name} {surface_offset_distance}", FCVAR_CHEAT );
|
||||
|
||||
#endif // CLIENT_DLL && STAGING_ONLY
|
||||
|
@ -618,7 +618,9 @@ void CParticleProperty::UpdateControlPoint( ParticleEffectList_t *pEffect, int i
|
||||
if ( !pAnimating->C_BaseAnimating::GetAttachment( pPoint->iAttachmentPoint, attachmentToWorld ) )
|
||||
{
|
||||
Warning( "Cannot update control point %d for effect '%s'.\n", pPoint->iAttachmentPoint, pEffect->pParticleEffect->GetEffectName() );
|
||||
attachmentToWorld = pAnimating->RenderableToWorldTransform();
|
||||
// Remove the effect cause this warning means something is orphaned
|
||||
StopParticlesNamed( pEffect->pParticleEffect->GetEffectName() );
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
@ -627,7 +629,7 @@ void CParticleProperty::UpdateControlPoint( ParticleEffectList_t *pEffect, int i
|
||||
MatrixVectors( vMat.As3x4(), &vecForward, &vecRight, &vecUp );
|
||||
MatrixPosition( vMat.As3x4(), vecOrigin );
|
||||
|
||||
if ( pEffect->pParticleEffect->m_pDef->IsViewModelEffect() )
|
||||
if ( pEffect->pParticleEffect->GetIsViewModelEffect() )
|
||||
{
|
||||
FormatViewModelAttachment( vecOrigin, true );
|
||||
}
|
||||
|
@ -40,7 +40,7 @@ void CRagdollLowViolenceManager::SetLowViolence( const char *pMapName )
|
||||
|
||||
#if !defined( CLIENT_DLL )
|
||||
// the server doesn't worry about low violence during multiplayer games
|
||||
if ( g_pGameRules->IsMultiplayer() )
|
||||
if ( g_pGameRules && g_pGameRules->IsMultiplayer() )
|
||||
{
|
||||
m_bLowViolence = false;
|
||||
}
|
||||
@ -742,8 +742,12 @@ bool ShouldRemoveThisRagdoll( CBaseAnimating *pRagdoll )
|
||||
return false;
|
||||
*/
|
||||
|
||||
// Bail if we have a null ragdoll pointer.
|
||||
if ( !pRagdoll->m_pRagdoll )
|
||||
return true;
|
||||
|
||||
Vector vMins, vMaxs;
|
||||
|
||||
|
||||
Vector origin = pRagdoll->m_pRagdoll->GetRagdollOrigin();
|
||||
pRagdoll->m_pRagdoll->GetRagdollBounds( vMins, vMaxs );
|
||||
|
||||
|
@ -151,6 +151,8 @@ typedef enum
|
||||
VOTE_FAILED_MAP_NOT_VALID,
|
||||
VOTE_FAILED_CANNOT_KICK_FOR_TIME,
|
||||
VOTE_FAILED_CANNOT_KICK_DURING_ROUND,
|
||||
VOTE_FAILED_VOTE_IN_PROGRESS,
|
||||
VOTE_FAILED_KICK_LIMIT_REACHED,
|
||||
|
||||
// TF-specific?
|
||||
VOTE_FAILED_MODIFICATION_ALREADY_ACTIVE,
|
||||
@ -455,6 +457,7 @@ enum {
|
||||
OBS_MODE_FIXED, // view from a fixed camera position
|
||||
OBS_MODE_IN_EYE, // follow a player in first person view
|
||||
OBS_MODE_CHASE, // follow a player in third person view
|
||||
OBS_MODE_POI, // PASSTIME point of interest - game objective, big fight, anything interesting; added in the middle of the enum due to tons of hard-coded "<ROAMING" enum compares
|
||||
OBS_MODE_ROAMING, // free roaming
|
||||
|
||||
NUM_OBSERVER_MODES,
|
||||
@ -688,6 +691,7 @@ struct FireBulletsInfo_t
|
||||
m_vecDirShooting.Init( VEC_T_NAN, VEC_T_NAN, VEC_T_NAN );
|
||||
#endif
|
||||
m_bPrimaryAttack = true;
|
||||
m_bUseServerRandomSeed = false;
|
||||
}
|
||||
|
||||
FireBulletsInfo_t( int nShots, const Vector &vecSrc, const Vector &vecDir, const Vector &vecSpread, float flDistance, int nAmmoType, bool bPrimaryAttack = true )
|
||||
@ -706,6 +710,7 @@ struct FireBulletsInfo_t
|
||||
m_pAdditionalIgnoreEnt = NULL;
|
||||
m_flDamageForceScale = 1.0f;
|
||||
m_bPrimaryAttack = bPrimaryAttack;
|
||||
m_bUseServerRandomSeed = false;
|
||||
}
|
||||
|
||||
int m_iShots;
|
||||
@ -722,6 +727,7 @@ struct FireBulletsInfo_t
|
||||
CBaseEntity *m_pAttacker;
|
||||
CBaseEntity *m_pAdditionalIgnoreEnt;
|
||||
bool m_bPrimaryAttack;
|
||||
bool m_bUseServerRandomSeed;
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
@ -61,6 +61,7 @@ void CTakeDamageInfo::Init( CBaseEntity *pInflictor, CBaseEntity *pAttacker, CBa
|
||||
m_iPlayerPenetrationCount = 0;
|
||||
m_flDamageBonus = 0.f;
|
||||
m_bForceFriendlyFire = false;
|
||||
m_flDamageForForce = 0.f;
|
||||
}
|
||||
|
||||
CTakeDamageInfo::CTakeDamageInfo()
|
||||
|
@ -64,6 +64,8 @@ public:
|
||||
Vector GetDamageForce() const;
|
||||
void SetDamageForce( const Vector &damageForce );
|
||||
void ScaleDamageForce( float flScaleAmount );
|
||||
float GetDamageForForceCalc() const;
|
||||
void SetDamageForForceCalc( const float flScaleAmount );
|
||||
|
||||
Vector GetDamagePosition() const;
|
||||
void SetDamagePosition( const Vector &damagePosition );
|
||||
@ -129,6 +131,9 @@ protected:
|
||||
EHANDLE m_hDamageBonusProvider; // Who gave us the ability to do extra damage?
|
||||
bool m_bForceFriendlyFire; // Ideally this would be a dmg type, but we can't add more
|
||||
|
||||
// AlliedModders - This member only exists after the 2015 SDK update.
|
||||
float m_flDamageForForce;
|
||||
|
||||
DECLARE_SIMPLE_DATADESC();
|
||||
};
|
||||
|
||||
@ -289,6 +294,16 @@ inline void CTakeDamageInfo::ScaleDamageForce( float flScaleAmount )
|
||||
m_vecDamageForce *= flScaleAmount;
|
||||
}
|
||||
|
||||
inline float CTakeDamageInfo::GetDamageForForceCalc() const
|
||||
{
|
||||
return m_flDamageForForce;
|
||||
}
|
||||
|
||||
inline void CTakeDamageInfo::SetDamageForForceCalc( float flDamage )
|
||||
{
|
||||
m_flDamageForForce = flDamage;
|
||||
}
|
||||
|
||||
inline Vector CTakeDamageInfo::GetDamagePosition() const
|
||||
{
|
||||
return m_vecDamagePosition;
|
||||
|
@ -87,7 +87,7 @@ public:
|
||||
virtual bool TimerMayExpire( void ) { return true; }
|
||||
|
||||
// A game has been won by the specified team
|
||||
virtual void SetWinningTeam( int team, int iWinReason, bool bForceMapReset = true, bool bSwitchTeams = false, bool bDontAddScore = false ) { return; }
|
||||
virtual void SetWinningTeam( int team, int iWinReason, bool bForceMapReset = true, bool bSwitchTeams = false, bool bDontAddScore = false, bool bFinal = false ) { return; }
|
||||
virtual void SetStalemate( int iReason, bool bForceMapReset = true, bool bSwitchTeams = false ) { return; }
|
||||
|
||||
// Used to determine if all players should switch teams
|
||||
|
@ -44,6 +44,14 @@
|
||||
#define ROUND_SETUP_2SECS "Announcer.RoundBegins2Seconds"
|
||||
#define ROUND_SETUP_1SECS "Announcer.RoundBegins1Seconds"
|
||||
|
||||
#ifdef TF_CLIENT_DLL
|
||||
#define MERASMUS_SETUP_5SECS "Merasmus.RoundBegins5Seconds"
|
||||
#define MERASMUS_SETUP_4SECS "Merasmus.RoundBegins4Seconds"
|
||||
#define MERASMUS_SETUP_3SECS "Merasmus.RoundBegins3Seconds"
|
||||
#define MERASMUS_SETUP_2SECS "Merasmus.RoundBegins2Seconds"
|
||||
#define MERASMUS_SETUP_1SECS "Merasmus.RoundBegins1Seconds"
|
||||
#endif
|
||||
|
||||
#define ROUND_START_BELL "Ambient.Siren"
|
||||
|
||||
#define ROUND_TIMER_TIME_ADDED "Announcer.TimeAdded"
|
||||
@ -283,6 +291,14 @@ void CTeamRoundTimer::Precache( void )
|
||||
PrecacheScriptSound( ROUND_TIMER_TIME_ADDED_LOSER );
|
||||
PrecacheScriptSound( ROUND_TIMER_TIME_ADDED_WINNER );
|
||||
PrecacheScriptSound( ROUND_START_BELL );
|
||||
|
||||
#ifdef TF_CLIENT_DLL
|
||||
PrecacheScriptSound( MERASMUS_SETUP_5SECS );
|
||||
PrecacheScriptSound( MERASMUS_SETUP_4SECS );
|
||||
PrecacheScriptSound( MERASMUS_SETUP_3SECS );
|
||||
PrecacheScriptSound( MERASMUS_SETUP_2SECS );
|
||||
PrecacheScriptSound( MERASMUS_SETUP_1SECS );
|
||||
#endif // TF_CLIENT_DLL
|
||||
#endif // TF_DLL || TF_CLIENT_DLL
|
||||
}
|
||||
|
||||
@ -575,7 +591,16 @@ const char *CTeamRoundTimer::GetTimeWarningSound( int nWarning )
|
||||
case RT_WARNING_5SECS:
|
||||
if ( m_nState == RT_STATE_SETUP )
|
||||
{
|
||||
pszRetVal = ROUND_SETUP_5SECS;
|
||||
#ifdef TF_CLIENT_DLL
|
||||
if ( TFGameRules() && TFGameRules()->IsHalloweenScenario( CTFGameRules::HALLOWEEN_SCENARIO_DOOMSDAY ) )
|
||||
{
|
||||
pszRetVal = MERASMUS_SETUP_5SECS;
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
pszRetVal = ROUND_SETUP_5SECS;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -585,7 +610,16 @@ const char *CTeamRoundTimer::GetTimeWarningSound( int nWarning )
|
||||
case RT_WARNING_4SECS:
|
||||
if ( m_nState == RT_STATE_SETUP )
|
||||
{
|
||||
pszRetVal = ROUND_SETUP_4SECS;
|
||||
#ifdef TF_CLIENT_DLL
|
||||
if ( TFGameRules() && TFGameRules()->IsHalloweenScenario( CTFGameRules::HALLOWEEN_SCENARIO_DOOMSDAY ) )
|
||||
{
|
||||
pszRetVal = MERASMUS_SETUP_4SECS;
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
pszRetVal = ROUND_SETUP_4SECS;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -595,7 +629,16 @@ const char *CTeamRoundTimer::GetTimeWarningSound( int nWarning )
|
||||
case RT_WARNING_3SECS:
|
||||
if ( m_nState == RT_STATE_SETUP )
|
||||
{
|
||||
pszRetVal = ROUND_SETUP_3SECS;
|
||||
#ifdef TF_CLIENT_DLL
|
||||
if ( TFGameRules() && TFGameRules()->IsHalloweenScenario( CTFGameRules::HALLOWEEN_SCENARIO_DOOMSDAY ) )
|
||||
{
|
||||
pszRetVal = MERASMUS_SETUP_3SECS;
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
pszRetVal = ROUND_SETUP_3SECS;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -605,7 +648,16 @@ const char *CTeamRoundTimer::GetTimeWarningSound( int nWarning )
|
||||
case RT_WARNING_2SECS:
|
||||
if ( m_nState == RT_STATE_SETUP )
|
||||
{
|
||||
pszRetVal = ROUND_SETUP_2SECS;
|
||||
#ifdef TF_CLIENT_DLL
|
||||
if ( TFGameRules() && TFGameRules()->IsHalloweenScenario( CTFGameRules::HALLOWEEN_SCENARIO_DOOMSDAY ) )
|
||||
{
|
||||
pszRetVal = MERASMUS_SETUP_2SECS;
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
pszRetVal = ROUND_SETUP_2SECS;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -615,7 +667,16 @@ const char *CTeamRoundTimer::GetTimeWarningSound( int nWarning )
|
||||
case RT_WARNING_1SECS:
|
||||
if ( m_nState == RT_STATE_SETUP )
|
||||
{
|
||||
pszRetVal = ROUND_SETUP_1SECS;
|
||||
#ifdef TF_CLIENT_DLL
|
||||
if ( TFGameRules() && TFGameRules()->IsHalloweenScenario( CTFGameRules::HALLOWEEN_SCENARIO_DOOMSDAY ) )
|
||||
{
|
||||
pszRetVal = MERASMUS_SETUP_1SECS;
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
pszRetVal = ROUND_SETUP_1SECS;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -80,7 +80,7 @@ public:
|
||||
bool IsStopWatchTimer( void ) { return m_bStopWatchTimer; }
|
||||
float GetStopWatchTotalTime( void ) { return m_flTotalTime; }
|
||||
bool IsRoundMaxTimerSet( void ) { return m_nTimerMaxLength > 0; }
|
||||
|
||||
int GetTimerInitialLength( void ) { return m_nTimerInitialLength; }
|
||||
|
||||
private:
|
||||
void CalculateOutputMessages( void );
|
||||
|
@ -35,17 +35,15 @@
|
||||
|
||||
#if defined(TF_CLIENT_DLL) || defined(TF_DLL)
|
||||
#include "tf_gamerules.h"
|
||||
#if defined(TF_CLIENT_DLL) || defined(TF_DLL)
|
||||
#include "tf_lobby.h"
|
||||
#ifdef GAME_DLL
|
||||
#include "player_vs_environment/tf_population_manager.h"
|
||||
#include "../server/tf/tf_gc_server.h"
|
||||
#include "../server/tf/tf_objective_resource.h"
|
||||
#else
|
||||
#include "../client/tf/tf_gc_client.h"
|
||||
#include "../client/tf/c_tf_objective_resource.h"
|
||||
#endif // GAME_DLL
|
||||
#endif // #if defined(TF_CLIENT_DLL) || defined(TF_DLL)
|
||||
#include "tf_lobby.h"
|
||||
#ifdef GAME_DLL
|
||||
#include "player_vs_environment/tf_population_manager.h"
|
||||
#include "../server/tf/tf_gc_server.h"
|
||||
#include "../server/tf/tf_objective_resource.h"
|
||||
#else
|
||||
#include "../client/tf/tf_gc_client.h"
|
||||
#include "../client/tf/c_tf_objective_resource.h"
|
||||
#endif // GAME_DLL
|
||||
#endif
|
||||
|
||||
// memdbgon must be the last include file in a .cpp file!!!
|
||||
@ -196,9 +194,14 @@ ConVar mp_maxrounds( "mp_maxrounds", "0", FCVAR_REPLICATED | FCVAR_NOTIFY, "max
|
||||
ConVar mp_winlimit( "mp_winlimit", "0", FCVAR_REPLICATED | FCVAR_NOTIFY, "Max score one team can reach before server changes maps", true, 0, false, 0 );
|
||||
ConVar mp_disable_respawn_times( "mp_disable_respawn_times", "0", FCVAR_NOTIFY | FCVAR_REPLICATED );
|
||||
ConVar mp_bonusroundtime( "mp_bonusroundtime", "15", FCVAR_REPLICATED, "Time after round win until round restarts", true, 5, true, 15 );
|
||||
ConVar mp_bonusroundtime_final( "mp_bonusroundtime_final", "15", FCVAR_REPLICATED, "Time after final round ends until round restarts", true, 5, true, 300 );
|
||||
ConVar mp_stalemate_meleeonly( "mp_stalemate_meleeonly", "0", FCVAR_REPLICATED | FCVAR_NOTIFY, "Restrict everyone to melee weapons only while in Sudden Death." );
|
||||
ConVar mp_forceautoteam( "mp_forceautoteam", "0", FCVAR_REPLICATED | FCVAR_NOTIFY, "Automatically assign players to teams when joining." );
|
||||
|
||||
#if defined( _DEBUG ) || defined( STAGING_ONLY )
|
||||
ConVar mp_developer( "mp_developer", "0", FCVAR_ARCHIVE | FCVAR_REPLICATED | FCVAR_NOTIFY, "1: basic conveniences (instant respawn and class change, etc). 2: add combat conveniences (infinite ammo, buddha, etc)" );
|
||||
#endif // _DEBUG || STAGING_ONLY
|
||||
|
||||
#ifdef GAME_DLL
|
||||
ConVar mp_showroundtransitions( "mp_showroundtransitions", "0", FCVAR_CHEAT | FCVAR_DEVELOPMENTONLY, "Show gamestate round transitions." );
|
||||
ConVar mp_enableroundwaittime( "mp_enableroundwaittime", "1", FCVAR_REPLICATED, "Enable timers to wait between rounds." );
|
||||
@ -358,25 +361,21 @@ CTeamplayRoundBasedRules::CTeamplayRoundBasedRules( void )
|
||||
m_flNextRespawnWave.Set( i, 0 );
|
||||
m_TeamRespawnWaveTimes.Set( i, -1.0f );
|
||||
|
||||
m_bTeamReady.Set( i, false );
|
||||
|
||||
#ifdef GAME_DLL
|
||||
m_flOriginalTeamRespawnWaveTime[i] = -1.0f;
|
||||
#endif
|
||||
}
|
||||
|
||||
for ( int i = 0; i < MAX_PLAYERS; i++ )
|
||||
{
|
||||
m_bPlayerReady.Set( i, false );
|
||||
}
|
||||
|
||||
m_bInOvertime = false;
|
||||
m_bInSetup = false;
|
||||
m_bSwitchedTeamsThisRound = false;
|
||||
m_flStopWatchTotalTime = -1.0f;
|
||||
m_bMultipleTrains = false;
|
||||
m_bAllowBetweenRounds = true;
|
||||
|
||||
#ifdef GAME_DLL
|
||||
ListenForGameEvent( "server_changelevel_failed" );
|
||||
|
||||
m_pCurStateInfo = NULL;
|
||||
State_Transition( GR_STATE_PREGAME );
|
||||
|
||||
@ -390,8 +389,8 @@ CTeamplayRoundBasedRules::CTeamplayRoundBasedRules( void )
|
||||
SetRoundToPlayNext( NULL_STRING );
|
||||
m_bInWaitingForPlayers = false;
|
||||
m_bAwaitingReadyRestart = false;
|
||||
m_flRestartRoundTime = -1;
|
||||
m_flMapResetTime = 0;
|
||||
m_flRestartRoundTime = -1.0f;
|
||||
m_flMapResetTime = 0.0f;
|
||||
m_bPrevRoundWasWaitingForPlayers = false;
|
||||
m_iWinningTeam = TEAM_UNASSIGNED;
|
||||
|
||||
@ -400,12 +399,13 @@ CTeamplayRoundBasedRules::CTeamplayRoundBasedRules( void )
|
||||
|
||||
m_bAllowStalemateAtTimelimit = false;
|
||||
m_bChangelevelAfterStalemate = false;
|
||||
m_flRoundStartTime = 0;
|
||||
m_flNewThrottledAlertTime = 0;
|
||||
m_flStartBalancingTeamsAt = 0;
|
||||
m_flRoundStartTime = 0.0f;
|
||||
m_flNewThrottledAlertTime = 0.0f;
|
||||
m_flStartBalancingTeamsAt = 0.0f;
|
||||
m_bPrintedUnbalanceWarning = false;
|
||||
m_flFoundUnbalancedTeamsTime = -1;
|
||||
m_flFoundUnbalancedTeamsTime = -1.0f;
|
||||
m_flWaitingForPlayersTimeEnds = 0.0f;
|
||||
m_flLastTeamWin = -1.0f;
|
||||
|
||||
m_nRoundsPlayed = 0;
|
||||
m_bUseAddScoreAnim = false;
|
||||
@ -413,18 +413,20 @@ CTeamplayRoundBasedRules::CTeamplayRoundBasedRules( void )
|
||||
m_bStopWatch = false;
|
||||
m_bAwaitingReadyRestart = false;
|
||||
|
||||
if ( IsInTournamentMode() == true )
|
||||
if ( IsInTournamentMode() )
|
||||
{
|
||||
m_bAwaitingReadyRestart = true;
|
||||
}
|
||||
|
||||
m_flAutoBalanceQueueTimeEnd = -1;
|
||||
m_flAutoBalanceQueueTimeEnd = -1.0f;
|
||||
m_nAutoBalanceQueuePlayerIndex = -1;
|
||||
m_nAutoBalanceQueuePlayerScore = -1;
|
||||
|
||||
SetDefLessFunc( m_GameTeams );
|
||||
m_bCheatsEnabledDuringLevel = false;
|
||||
|
||||
ResetPlayerAndTeamReadyState();
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
@ -580,6 +582,22 @@ float CTeamplayRoundBasedRules::GetRespawnTimeScalar( int iTeam )
|
||||
return flScale;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void CTeamplayRoundBasedRules::FireGameEvent( IGameEvent * event )
|
||||
{
|
||||
#ifdef GAME_DLL
|
||||
const char *eventName = event->GetName();
|
||||
if ( g_fGameOver && !Q_strcmp( eventName, "server_changelevel_failed" ) )
|
||||
{
|
||||
Warning( "In gameover, but failed to load the next map. Trying next map in cycle.\n" );
|
||||
nextlevel.SetValue( "" );
|
||||
ChangeLevel();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef GAME_DLL
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
@ -616,7 +634,7 @@ void CTeamplayRoundBasedRules::Think( void )
|
||||
|
||||
// Don't run this code again
|
||||
m_flIntermissionEndTime = 0.f;
|
||||
}
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
@ -853,7 +871,14 @@ void CTeamplayRoundBasedRules::CheckWaitingForPlayers( void )
|
||||
mp_waitingforplayers_restart.SetValue( 0 );
|
||||
}
|
||||
|
||||
if( (mp_waitingforplayers_cancel.GetBool() || IsInItemTestingMode()) && IsInTournamentMode() == false )
|
||||
bool bCancelWait = ( mp_waitingforplayers_cancel.GetBool() || IsInItemTestingMode() ) && !IsInTournamentMode();
|
||||
|
||||
#if defined( _DEBUG ) || defined( STAGING_ONLY )
|
||||
if ( mp_developer.GetBool() )
|
||||
bCancelWait = true;
|
||||
#endif // _DEBUG || STAGING_ONLY
|
||||
|
||||
if ( bCancelWait )
|
||||
{
|
||||
// Cancel the wait period and manually Resume() the timer if
|
||||
// it's not supposed to start paused at the beginning of a round.
|
||||
@ -975,11 +1000,7 @@ void CTeamplayRoundBasedRules::CheckRestartRound( void )
|
||||
int iDelayMax = 60;
|
||||
|
||||
#if defined(TF_CLIENT_DLL) || defined(TF_DLL)
|
||||
#ifdef STAGING_ONLY
|
||||
if ( TFGameRules() && ( TFGameRules()->IsMannVsMachineMode() || TFGameRules()->IsRatedTournamentMode() ) )
|
||||
#else
|
||||
if ( TFGameRules() && TFGameRules()->IsMannVsMachineMode() )
|
||||
#endif // STAGING_ONLY
|
||||
if ( TFGameRules() && ( TFGameRules()->IsMannVsMachineMode() || TFGameRules()->IsCompetitiveMode() ) )
|
||||
{
|
||||
iDelayMax = 180;
|
||||
}
|
||||
@ -1068,7 +1089,7 @@ void CTeamplayRoundBasedRules::CheckRestartRound( void )
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
bool CTeamplayRoundBasedRules::CheckTimeLimit( void )
|
||||
bool CTeamplayRoundBasedRules::CheckTimeLimit( bool bAllowEnd /*= true*/ )
|
||||
{
|
||||
if ( IsInPreMatch() == true )
|
||||
return false;
|
||||
@ -1095,18 +1116,21 @@ bool CTeamplayRoundBasedRules::CheckTimeLimit( void )
|
||||
bSwitchDueToTime = false;
|
||||
}
|
||||
|
||||
if( GetTimeLeft() <= 0 || m_bChangelevelAfterStalemate || bSwitchDueToTime )
|
||||
if ( GetTimeLeft() <= 0 || m_bChangelevelAfterStalemate || bSwitchDueToTime )
|
||||
{
|
||||
IGameEvent *event = gameeventmanager->CreateEvent( "teamplay_game_over" );
|
||||
if ( event )
|
||||
if ( bAllowEnd )
|
||||
{
|
||||
event->SetString( "reason", "Reached Time Limit" );
|
||||
gameeventmanager->FireEvent( event );
|
||||
IGameEvent *event = gameeventmanager->CreateEvent( "teamplay_game_over" );
|
||||
if ( event )
|
||||
{
|
||||
event->SetString( "reason", "Reached Time Limit" );
|
||||
gameeventmanager->FireEvent( event );
|
||||
}
|
||||
|
||||
SendTeamScoresEvent();
|
||||
|
||||
GoToIntermission();
|
||||
}
|
||||
|
||||
SendTeamScoresEvent();
|
||||
|
||||
GoToIntermission();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@ -1145,20 +1169,23 @@ int CTeamplayRoundBasedRules::GetTimeLeft( void )
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
bool CTeamplayRoundBasedRules::CheckNextLevelCvar( void )
|
||||
bool CTeamplayRoundBasedRules::CheckNextLevelCvar( bool bAllowEnd /*= true*/ )
|
||||
{
|
||||
if ( m_bForceMapReset )
|
||||
{
|
||||
if ( nextlevel.GetString() && *nextlevel.GetString() && engine->IsMapValid( nextlevel.GetString() ) )
|
||||
if ( nextlevel.GetString() && *nextlevel.GetString() )
|
||||
{
|
||||
IGameEvent *event = gameeventmanager->CreateEvent( "teamplay_game_over" );
|
||||
if ( event )
|
||||
if ( bAllowEnd )
|
||||
{
|
||||
event->SetString( "reason", "NextLevel CVAR" );
|
||||
gameeventmanager->FireEvent( event );
|
||||
}
|
||||
IGameEvent *event = gameeventmanager->CreateEvent( "teamplay_game_over" );
|
||||
if ( event )
|
||||
{
|
||||
event->SetString( "reason", "NextLevel CVAR" );
|
||||
gameeventmanager->FireEvent( event );
|
||||
}
|
||||
|
||||
GoToIntermission();
|
||||
GoToIntermission();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@ -1169,7 +1196,7 @@ bool CTeamplayRoundBasedRules::CheckNextLevelCvar( void )
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
bool CTeamplayRoundBasedRules::CheckWinLimit( void )
|
||||
bool CTeamplayRoundBasedRules::CheckWinLimit( bool bAllowEnd /*= true*/ )
|
||||
{
|
||||
// has one team won the specified number of rounds?
|
||||
int iWinLimit = mp_winlimit.GetInt();
|
||||
@ -1183,14 +1210,17 @@ bool CTeamplayRoundBasedRules::CheckWinLimit( void )
|
||||
|
||||
if ( pTeam->GetScore() >= iWinLimit )
|
||||
{
|
||||
IGameEvent *event = gameeventmanager->CreateEvent( "teamplay_game_over" );
|
||||
if ( event )
|
||||
if ( bAllowEnd )
|
||||
{
|
||||
event->SetString( "reason", "Reached Win Limit" );
|
||||
gameeventmanager->FireEvent( event );
|
||||
}
|
||||
IGameEvent *event = gameeventmanager->CreateEvent( "teamplay_game_over" );
|
||||
if ( event )
|
||||
{
|
||||
event->SetString( "reason", "Reached Win Limit" );
|
||||
gameeventmanager->FireEvent( event );
|
||||
}
|
||||
|
||||
GoToIntermission();
|
||||
GoToIntermission();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@ -1202,20 +1232,23 @@ bool CTeamplayRoundBasedRules::CheckWinLimit( void )
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
bool CTeamplayRoundBasedRules::CheckMaxRounds()
|
||||
bool CTeamplayRoundBasedRules::CheckMaxRounds( bool bAllowEnd /*= true*/ )
|
||||
{
|
||||
if ( mp_maxrounds.GetInt() > 0 && IsInPreMatch() == false )
|
||||
{
|
||||
if ( m_nRoundsPlayed >= mp_maxrounds.GetInt() )
|
||||
{
|
||||
IGameEvent *event = gameeventmanager->CreateEvent( "teamplay_game_over" );
|
||||
if ( event )
|
||||
if ( bAllowEnd )
|
||||
{
|
||||
event->SetString( "reason", "Reached Round Limit" );
|
||||
gameeventmanager->FireEvent( event );
|
||||
}
|
||||
IGameEvent *event = gameeventmanager->CreateEvent( "teamplay_game_over" );
|
||||
if ( event )
|
||||
{
|
||||
event->SetString( "reason", "Reached Round Limit" );
|
||||
gameeventmanager->FireEvent( event );
|
||||
}
|
||||
|
||||
GoToIntermission();
|
||||
GoToIntermission();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@ -1435,17 +1468,17 @@ void CTeamplayRoundBasedRules::State_Enter_PREROUND( void )
|
||||
m_flStateTransitionTime = gpGlobals->curtime + tf_arena_preround_time.GetInt();
|
||||
}
|
||||
#if defined(TF_CLIENT_DLL) || defined(TF_DLL)
|
||||
else if ( TFGameRules() && TFGameRules()->IsMannVsMachineMode() )
|
||||
// Only allow at the very beginning of the game, or between waves in mvm
|
||||
else if ( TFGameRules() && TFGameRules()->UsePlayerReadyStatusMode() && m_bAllowBetweenRounds )
|
||||
{
|
||||
State_Transition( GR_STATE_BETWEEN_RNDS );
|
||||
TFObjectiveResource()->SetMannVsMachineBetweenWaves( true );
|
||||
m_bAllowBetweenRounds = false;
|
||||
|
||||
if ( TFGameRules()->IsMannVsMachineMode() )
|
||||
{
|
||||
TFObjectiveResource()->SetMannVsMachineBetweenWaves( true );
|
||||
}
|
||||
}
|
||||
#ifdef STAGING_ONLY
|
||||
else if ( TFGameRules() && TFGameRules()->IsRatedTournamentMode() )
|
||||
{
|
||||
State_Transition( GR_STATE_BETWEEN_RNDS );
|
||||
}
|
||||
#endif // STAGING_ONLY
|
||||
#endif // #if defined(TF_CLIENT_DLL) || defined(TF_DLL)
|
||||
else
|
||||
{
|
||||
@ -1527,28 +1560,33 @@ void CTeamplayRoundBasedRules::State_Enter_RND_RUNNING( void )
|
||||
void CTeamplayRoundBasedRules::CheckReadyRestart( void )
|
||||
{
|
||||
// check round restart
|
||||
if( m_flRestartRoundTime > 0 && m_flRestartRoundTime <= gpGlobals->curtime && !g_pServerBenchmark->IsBenchmarkRunning() )
|
||||
if ( m_flRestartRoundTime > 0 && m_flRestartRoundTime <= gpGlobals->curtime && !g_pServerBenchmark->IsBenchmarkRunning() )
|
||||
{
|
||||
m_flRestartRoundTime = -1;
|
||||
|
||||
#ifdef TF_DLL
|
||||
if ( TFGameRules() )
|
||||
{
|
||||
if ( TFGameRules()->IsMannVsMachineMode() && g_pPopulationManager )
|
||||
if ( TFGameRules()->IsMannVsMachineMode() )
|
||||
{
|
||||
if ( TFObjectiveResource()->GetMannVsMachineIsBetweenWaves() )
|
||||
if ( g_pPopulationManager && TFObjectiveResource()->GetMannVsMachineIsBetweenWaves() )
|
||||
{
|
||||
g_pPopulationManager->StartCurrentWave();
|
||||
m_bAllowBetweenRounds = true;
|
||||
return;
|
||||
}
|
||||
}
|
||||
#ifdef STAGING_ONLY
|
||||
else if ( TFGameRules()->IsRatedTournamentMode() )
|
||||
else if ( TFGameRules()->IsCompetitiveMode() )
|
||||
{
|
||||
TFGameRules()->StartRatedTournamentMatch();
|
||||
TFGameRules()->StartCompetitiveMatch();
|
||||
return;
|
||||
}
|
||||
else if ( mp_tournament.GetBool() )
|
||||
{
|
||||
// Temp
|
||||
TFGameRules()->StartCompetitiveMatch();
|
||||
return;
|
||||
}
|
||||
#endif // STAGING_ONLY
|
||||
}
|
||||
#endif // TF_DLL
|
||||
|
||||
@ -1556,34 +1594,28 @@ void CTeamplayRoundBasedRules::CheckReadyRestart( void )
|
||||
State_Transition( GR_STATE_RESTART );
|
||||
}
|
||||
|
||||
// check ready restart
|
||||
if( m_bAwaitingReadyRestart )
|
||||
{
|
||||
int nTime = 5;
|
||||
bool bTeamReady = false;
|
||||
bool bProcessReadyRestart = m_bAwaitingReadyRestart;
|
||||
|
||||
#ifdef TF_DLL
|
||||
if ( TFGameRules() )
|
||||
{
|
||||
if ( TFGameRules()->IsMannVsMachineMode() )
|
||||
{
|
||||
bTeamReady = AreDefendingPlayersReady();
|
||||
if ( bTeamReady )
|
||||
{
|
||||
nTime = 10;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
bTeamReady = m_bTeamReady[TF_TEAM_BLUE] && m_bTeamReady[TF_TEAM_RED];
|
||||
}
|
||||
}
|
||||
bProcessReadyRestart &= TFGameRules() && !TFGameRules()->UsePlayerReadyStatusMode();
|
||||
#endif // TF_DLL
|
||||
|
||||
if ( bTeamReady )
|
||||
// check ready restart
|
||||
if ( bProcessReadyRestart )
|
||||
{
|
||||
bool bTeamNotReady = false;
|
||||
for ( int i = LAST_SHARED_TEAM + 1; i < GetNumberOfTeams(); i++ )
|
||||
{
|
||||
//State_Transition( GR_STATE_RESTART );
|
||||
mp_restartgame.SetValue( nTime );
|
||||
if ( !m_bTeamReady[i] )
|
||||
{
|
||||
bTeamNotReady = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if ( !bTeamNotReady )
|
||||
{
|
||||
mp_restartgame.SetValue( 5 );
|
||||
m_bAwaitingReadyRestart = false;
|
||||
|
||||
ShouldResetScores( true, true );
|
||||
@ -1596,31 +1628,31 @@ void CTeamplayRoundBasedRules::CheckReadyRestart( void )
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
bool CTeamplayRoundBasedRules::AreDefendingPlayersReady()
|
||||
bool CTeamplayRoundBasedRules::AreLobbyPlayersOnTeamReady( int iTeam )
|
||||
{
|
||||
// Get list of defenders
|
||||
CUtlVector<LobbyPlayerInfo_t> vecMvMDefenders;
|
||||
GetMvMPotentialDefendersLobbyPlayerInfo( vecMvMDefenders );
|
||||
if ( !TFGameRules() )
|
||||
return false;
|
||||
|
||||
if ( TFGameRules()->IsMannVsMachineMode() && iTeam == TF_TEAM_PVE_INVADERS )
|
||||
return true;
|
||||
|
||||
// Scan all the players, and bail as soon as we find one person
|
||||
// worth waiting for
|
||||
bool bAtLeastOnePersonReady = false;
|
||||
for ( int i = 0; i < vecMvMDefenders.Count(); i++ )
|
||||
|
||||
CUtlVector<LobbyPlayerInfo_t> vecLobbyPlayers;
|
||||
GetPotentialPlayersLobbyPlayerInfo( vecLobbyPlayers );
|
||||
|
||||
for ( int i = 0; i < vecLobbyPlayers.Count(); i++ )
|
||||
{
|
||||
|
||||
// Are they on the red team?
|
||||
const LobbyPlayerInfo_t &p = vecMvMDefenders[i];
|
||||
if ( !p.m_bConnected || p.m_iTeam == TEAM_UNASSIGNED || p.m_nEntNum <= 0 || p.m_nEntNum >= MAX_PLAYERS )
|
||||
const LobbyPlayerInfo_t &p = vecLobbyPlayers[i];
|
||||
|
||||
// Make sure all lobby players are connected
|
||||
if ( !AreLobbyPlayersConnected() )
|
||||
{
|
||||
// They're still getting set up. We'll wait for them,
|
||||
// but only if they are in the lobby
|
||||
if ( p.m_bInLobby )
|
||||
return false;
|
||||
return false;
|
||||
}
|
||||
else if ( p.m_iTeam == TF_TEAM_PVE_DEFENDERS )
|
||||
// All are connected, make sure their team is ready
|
||||
else if ( p.m_iTeam == iTeam )
|
||||
{
|
||||
|
||||
// If he isn't ready, then we aren't ready
|
||||
if ( !m_bPlayerReady[ p.m_nEntNum ] )
|
||||
return false;
|
||||
|
||||
@ -1629,8 +1661,12 @@ bool CTeamplayRoundBasedRules::AreDefendingPlayersReady()
|
||||
}
|
||||
else
|
||||
{
|
||||
// And you may ask yourself, "How did I get here?"
|
||||
Assert( p.m_iTeam == TF_TEAM_PVE_DEFENDERS );
|
||||
// In MvM, only the red team should pass through here
|
||||
if ( TFGameRules()->IsMannVsMachineMode() )
|
||||
{
|
||||
// And you may ask yourself, "How did I get here?"
|
||||
Assert( p.m_iTeam == iTeam );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1639,6 +1675,32 @@ bool CTeamplayRoundBasedRules::AreDefendingPlayersReady()
|
||||
return bAtLeastOnePersonReady;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Is everyone in the lobby connected to the server?
|
||||
//-----------------------------------------------------------------------------
|
||||
bool CTeamplayRoundBasedRules::AreLobbyPlayersConnected( void )
|
||||
{
|
||||
CUtlVector<LobbyPlayerInfo_t> vecLobbyPlayers;
|
||||
GetPotentialPlayersLobbyPlayerInfo( vecLobbyPlayers );
|
||||
|
||||
// If you're calling this, you should have lobby members
|
||||
Assert( vecLobbyPlayers.Count() );
|
||||
|
||||
for ( int i = 0; i < vecLobbyPlayers.Count(); i++ )
|
||||
{
|
||||
const LobbyPlayerInfo_t &pLobbyPlayer = vecLobbyPlayers[i];
|
||||
if ( !pLobbyPlayer.m_bConnected ||
|
||||
pLobbyPlayer.m_nEntNum <= 0 ||
|
||||
pLobbyPlayer.m_nEntNum >= MAX_PLAYERS ||
|
||||
( TFGameRules() && TFGameRules()->IsMannVsMachineMode() && pLobbyPlayer.m_iTeam == TEAM_UNASSIGNED ) )
|
||||
{
|
||||
if ( pLobbyPlayer.m_bInLobby )
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
#endif // #if defined(TF_CLIENT_DLL) || defined(TF_DLL)
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
@ -1657,6 +1719,15 @@ void CTeamplayRoundBasedRules::State_Think_RND_RUNNING( void )
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef TF_DLL
|
||||
// Mass time-out? Clean everything up.
|
||||
if ( TFGameRules() && TFGameRules()->IsCompetitiveMode() )
|
||||
{
|
||||
TFGameRules()->EndCompetitiveMatch();
|
||||
return;
|
||||
}
|
||||
#endif // TF_DLL
|
||||
|
||||
State_Transition( GR_STATE_PREGAME );
|
||||
return;
|
||||
}
|
||||
@ -1672,9 +1743,8 @@ void CTeamplayRoundBasedRules::State_Think_RND_RUNNING( void )
|
||||
// check round restart
|
||||
CheckReadyRestart();
|
||||
|
||||
|
||||
// See if we're coming up to the server timelimit, in which case force a stalemate immediately.
|
||||
if ( State_Get() == GR_STATE_RND_RUNNING && mp_timelimit.GetInt() > 0 && IsInPreMatch() == false && GetTimeLeft() <= 0 )
|
||||
if ( mp_timelimit.GetInt() > 0 && IsInPreMatch() == false && GetTimeLeft() <= 0 )
|
||||
{
|
||||
if ( m_bAllowStalemateAtTimelimit || ( mp_match_end_at_timelimit.GetBool() && !IsValveMap() ) )
|
||||
{
|
||||
@ -1730,9 +1800,7 @@ void CTeamplayRoundBasedRules::State_Think_RND_RUNNING( void )
|
||||
//-----------------------------------------------------------------------------
|
||||
void CTeamplayRoundBasedRules::State_Enter_TEAM_WIN( void )
|
||||
{
|
||||
float flTime = GetBonusRoundTime();
|
||||
|
||||
m_flStateTransitionTime = gpGlobals->curtime + flTime;
|
||||
m_flStateTransitionTime = gpGlobals->curtime + GetBonusRoundTime();
|
||||
|
||||
// if we're forcing the map to reset it must be the end of a "full" round not a mini-round
|
||||
if ( m_bForceMapReset )
|
||||
@ -1744,18 +1812,14 @@ void CTeamplayRoundBasedRules::State_Enter_TEAM_WIN( void )
|
||||
|
||||
SendWinPanelInfo();
|
||||
|
||||
#ifdef STAGING_ONLY
|
||||
#ifdef TF_DLL
|
||||
if ( TFGameRules() && TFGameRules()->IsRatedTournamentMode() )
|
||||
// Do this now, so players don't leave before the usual CheckWinLimit() call happens
|
||||
bool bDone = ( CheckTimeLimit( false ) || CheckWinLimit( false ) || CheckMaxRounds( false ) || CheckNextLevelCvar( false ) );
|
||||
if ( TFGameRules() && TFGameRules()->IsCompetitiveMode() && bDone )
|
||||
{
|
||||
// Do this now, so players don't leave before the usual CheckWinLimit() call happens
|
||||
if ( CheckWinLimit() )
|
||||
{
|
||||
TFGameRules()->SkillRating_CalculateAdjustmentForTeams( m_iWinningTeam );
|
||||
}
|
||||
TFGameRules()->StopCompetitiveMatch( CMsgGC_Match_Result_Status_MATCH_SUCCEEDED );
|
||||
}
|
||||
#endif // TF_DLL
|
||||
#endif // STAGING_ONLY
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
@ -1773,10 +1837,10 @@ void CTeamplayRoundBasedRules::State_Think_TEAM_WIN( void )
|
||||
}
|
||||
#endif // TF_DLL
|
||||
|
||||
bool bDone = !(!CheckTimeLimit() && !CheckWinLimit() && !CheckMaxRounds() && !CheckNextLevelCvar());
|
||||
bool bDone = ( CheckTimeLimit() || CheckWinLimit() || CheckMaxRounds() || CheckNextLevelCvar() );
|
||||
|
||||
// check the win limit, max rounds, time limit and nextlevel cvar before starting the next round
|
||||
if ( bDone == false )
|
||||
if ( !bDone )
|
||||
{
|
||||
PreviousRoundEnd();
|
||||
|
||||
@ -1797,7 +1861,7 @@ void CTeamplayRoundBasedRules::State_Think_TEAM_WIN( void )
|
||||
State_Transition( GR_STATE_PREROUND );
|
||||
}
|
||||
}
|
||||
else if ( IsInTournamentMode() == true )
|
||||
else if ( IsInTournamentMode() )
|
||||
{
|
||||
for ( int i = 1; i <= MAX_PLAYERS; i++ )
|
||||
{
|
||||
@ -1811,7 +1875,7 @@ void CTeamplayRoundBasedRules::State_Think_TEAM_WIN( void )
|
||||
|
||||
RestartTournament();
|
||||
|
||||
if ( IsInArenaMode() == true )
|
||||
if ( IsInArenaMode() )
|
||||
{
|
||||
#if defined( REPLAY_ENABLED )
|
||||
if ( g_pReplay )
|
||||
@ -1823,33 +1887,43 @@ void CTeamplayRoundBasedRules::State_Think_TEAM_WIN( void )
|
||||
|
||||
State_Transition( GR_STATE_PREROUND );
|
||||
}
|
||||
else
|
||||
{
|
||||
#ifdef TF_DLL
|
||||
if ( TFGameRules() && TFGameRules()->IsMannVsMachineMode() )
|
||||
else if ( TFGameRules() && TFGameRules()->IsMannVsMachineMode() && g_pPopulationManager )
|
||||
{
|
||||
// one of the convars mp_timelimit, mp_winlimit, mp_maxrounds, or nextlevel has been triggered
|
||||
for ( int i = 1; i <= MAX_PLAYERS; i++ )
|
||||
{
|
||||
// one of the convars mp_timelimit, mp_winlimit, mp_maxrounds, or nextlevel has been triggered
|
||||
if ( g_pPopulationManager )
|
||||
{
|
||||
for ( int i = 1; i <= MAX_PLAYERS; i++ )
|
||||
{
|
||||
CBasePlayer *pPlayer = UTIL_PlayerByIndex( i );
|
||||
CBasePlayer *pPlayer = UTIL_PlayerByIndex( i );
|
||||
if ( !pPlayer )
|
||||
continue;
|
||||
|
||||
if ( !pPlayer )
|
||||
continue;
|
||||
|
||||
pPlayer->AddFlag( FL_FROZEN );
|
||||
pPlayer->ShowViewPortPanel( PANEL_SCOREBOARD );
|
||||
}
|
||||
|
||||
g_fGameOver = true;
|
||||
g_pPopulationManager->SetMapRestartTime( gpGlobals->curtime + 10.0f );
|
||||
State_Enter( GR_STATE_GAME_OVER );
|
||||
return;
|
||||
}
|
||||
pPlayer->AddFlag( FL_FROZEN );
|
||||
}
|
||||
|
||||
g_fGameOver = true;
|
||||
g_pPopulationManager->SetMapRestartTime( gpGlobals->curtime + 10.0f );
|
||||
State_Enter( GR_STATE_GAME_OVER );
|
||||
return;
|
||||
}
|
||||
else if ( TFGameRules() && TFGameRules()->UsePlayerReadyStatusMode() )
|
||||
{
|
||||
for ( int i = 1; i <= MAX_PLAYERS; i++ )
|
||||
{
|
||||
CBasePlayer *pPlayer = UTIL_PlayerByIndex( i );
|
||||
if ( !pPlayer )
|
||||
continue;
|
||||
|
||||
pPlayer->AddFlag( FL_FROZEN );
|
||||
}
|
||||
|
||||
g_fGameOver = true;
|
||||
State_Enter( GR_STATE_GAME_OVER );
|
||||
m_flStateTransitionTime = gpGlobals->curtime + GetBonusRoundTime( true );
|
||||
return;
|
||||
}
|
||||
#endif // TF_DLL
|
||||
else
|
||||
{
|
||||
State_Transition( GR_STATE_RND_RUNNING );
|
||||
}
|
||||
}
|
||||
@ -2180,7 +2254,7 @@ int TeamScoreSort( CTeam* const *pTeam1, CTeam* const *pTeam2 )
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Input for other entities to declare a round winner.
|
||||
//-----------------------------------------------------------------------------
|
||||
void CTeamplayRoundBasedRules::SetWinningTeam( int team, int iWinReason, bool bForceMapReset /* = true */, bool bSwitchTeams /* = false*/, bool bDontAddScore /* = false*/ )
|
||||
void CTeamplayRoundBasedRules::SetWinningTeam( int team, int iWinReason, bool bForceMapReset /* = true */, bool bSwitchTeams /* = false*/, bool bDontAddScore /* = false*/, bool bFinal /*= false*/ )
|
||||
{
|
||||
// Commentary doesn't let anyone win
|
||||
if ( IsInCommentaryMode() )
|
||||
@ -2224,6 +2298,8 @@ void CTeamplayRoundBasedRules::SetWinningTeam( int team, int iWinReason, bool bF
|
||||
|
||||
State_Transition( GR_STATE_TEAM_WIN );
|
||||
|
||||
m_flLastTeamWin = gpGlobals->curtime;
|
||||
|
||||
IGameEvent *event = gameeventmanager->CreateEvent( "teamplay_round_win" );
|
||||
if ( event )
|
||||
{
|
||||
@ -2438,6 +2514,10 @@ void CTeamplayRoundBasedRules::RestartTournament( void )
|
||||
m_flStopWatchTotalTime = -1.0f;
|
||||
m_bStopWatch = false;
|
||||
|
||||
// we might have had a stalemate during the last round
|
||||
// so reset this bool each time we restart the tournament
|
||||
m_bChangelevelAfterStalemate = false;
|
||||
|
||||
for ( int i = 0; i < MAX_TEAMS; i++ )
|
||||
{
|
||||
m_bTeamReady.Set( i, false );
|
||||
@ -2579,6 +2659,30 @@ void CTeamplayRoundBasedRules::HandleTimeLimitChange( void )
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void CTeamplayRoundBasedRules::ResetPlayerAndTeamReadyState( void )
|
||||
{
|
||||
for ( int i = 0; i < MAX_TEAMS; i++ )
|
||||
{
|
||||
m_bTeamReady.Set( i, false );
|
||||
}
|
||||
|
||||
for ( int i = 0; i < MAX_PLAYERS; i++ )
|
||||
{
|
||||
m_bPlayerReady.Set( i, false );
|
||||
}
|
||||
|
||||
#ifdef GAME_DLL
|
||||
// Note <= MAX_PLAYERS vs < MAX_PLAYERS above
|
||||
for ( int i = 0; i <= MAX_PLAYERS; i++ )
|
||||
{
|
||||
m_bPlayerReadyBefore[i] = false;
|
||||
}
|
||||
#endif // GAME_DLL
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
@ -2606,6 +2710,12 @@ void CTeamplayRoundBasedRules::CreateTimeLimitTimer( void )
|
||||
if ( IsInArenaMode () == true || IsInKothMode() == true )
|
||||
return;
|
||||
|
||||
// this is the same check we use in State_Think_RND_RUNNING()
|
||||
// don't show the timelimit timer if we're not going to end the map when it runs out
|
||||
bool bAllowStalemate = ( m_bAllowStalemateAtTimelimit || ( mp_match_end_at_timelimit.GetBool() && !IsValveMap() ) );
|
||||
if ( !bAllowStalemate )
|
||||
return;
|
||||
|
||||
#ifndef CSTRIKE_DLL
|
||||
if ( !m_hTimeLimitTimer )
|
||||
{
|
||||
@ -2886,6 +2996,11 @@ void CTeamplayRoundBasedRules::BalanceTeams( bool bRequireSwitcheesToBeDead )
|
||||
return;
|
||||
}
|
||||
|
||||
#if defined( _DEBUG ) || defined( STAGING_ONLY )
|
||||
if ( mp_developer.GetBool() )
|
||||
return;
|
||||
#endif // _DEBUG || STAGING_ONLY
|
||||
|
||||
if ( IsInTraining() || IsInItemTestingMode() )
|
||||
{
|
||||
return;
|
||||
@ -3314,9 +3429,12 @@ bool CTeamplayRoundBasedRules::IsInHighlanderMode( void )
|
||||
#endif
|
||||
}
|
||||
|
||||
int CTeamplayRoundBasedRules::GetBonusRoundTime( void )
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
int CTeamplayRoundBasedRules::GetBonusRoundTime( bool bFinal /*= false*/ )
|
||||
{
|
||||
return MAX( 5, mp_bonusroundtime.GetFloat() );
|
||||
return bFinal ? mp_bonusroundtime_final.GetInt() : Max( 5, mp_bonusroundtime.GetInt() );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
@ -3330,6 +3448,11 @@ bool CTeamplayRoundBasedRules::ShouldBalanceTeams( void )
|
||||
if ( IsInTraining() == true || IsInItemTestingMode() )
|
||||
return false;
|
||||
|
||||
#if defined( _DEBUG ) || defined( STAGING_ONLY )
|
||||
if ( mp_developer.GetBool() )
|
||||
return false;
|
||||
#endif // _DEBUG || STAGING_ONLY
|
||||
|
||||
if ( mp_teams_unbalance_limit.GetInt() <= 0 )
|
||||
return false;
|
||||
|
||||
@ -3349,6 +3472,11 @@ bool CTeamplayRoundBasedRules::WouldChangeUnbalanceTeams( int iNewTeam, int iCur
|
||||
if ( ShouldBalanceTeams() == false )
|
||||
return false;
|
||||
|
||||
#if defined( _DEBUG ) || defined( STAGING_ONLY )
|
||||
if ( mp_developer.GetBool() )
|
||||
return false;
|
||||
#endif // _DEBUG || STAGING_ONLY
|
||||
|
||||
// if they are joining a non-playing team, allow
|
||||
if ( iNewTeam < FIRST_GAME_TEAM )
|
||||
return false;
|
||||
@ -3524,25 +3652,30 @@ void CTeamplayRoundBasedRules::ResetTeamsRoundWinTracking( void )
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Are you now, or are you ever going to be, a member of the defending party?
|
||||
//-----------------------------------------------------------------------------
|
||||
void CTeamplayRoundBasedRules::GetMvMPotentialDefendersLobbyPlayerInfo( CUtlVector<LobbyPlayerInfo_t> &vecMvMDefenders, bool bIncludeBots /*= false*/ )
|
||||
void CTeamplayRoundBasedRules::GetPotentialPlayersLobbyPlayerInfo( CUtlVector<LobbyPlayerInfo_t> &vecLobbyPlayers, bool bIncludeBots /*= false*/ )
|
||||
{
|
||||
GetAllPlayersLobbyInfo( vecMvMDefenders, bIncludeBots );
|
||||
GetAllPlayersLobbyInfo( vecLobbyPlayers, bIncludeBots );
|
||||
|
||||
// Now scan through and remove the spectators
|
||||
for (int i = vecMvMDefenders.Count() - 1 ; i >= 0 ; --i )
|
||||
for ( int i = vecLobbyPlayers.Count() - 1; i >= 0; --i )
|
||||
{
|
||||
switch ( vecMvMDefenders[i].m_iTeam )
|
||||
switch ( vecLobbyPlayers[i].m_iTeam )
|
||||
{
|
||||
case TEAM_UNASSIGNED:
|
||||
case TF_TEAM_PVE_DEFENDERS:
|
||||
case TF_TEAM_RED:
|
||||
break;
|
||||
|
||||
case TF_TEAM_BLUE:
|
||||
if ( TFGameRules() && TFGameRules()->IsMannVsMachineMode() )
|
||||
vecLobbyPlayers.FastRemove( i );
|
||||
break;
|
||||
|
||||
case TEAM_SPECTATOR:
|
||||
vecLobbyPlayers.FastRemove( i );
|
||||
break;
|
||||
|
||||
default:
|
||||
AssertMsg1( false, "Bogus team %d", vecMvMDefenders[i].m_iTeam );
|
||||
case TF_TEAM_PVE_INVADERS:
|
||||
case TEAM_SPECTATOR:
|
||||
vecMvMDefenders.FastRemove( i );
|
||||
break;
|
||||
AssertMsg1( false, "Bogus team %d", vecLobbyPlayers[i].m_iTeam );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -12,6 +12,7 @@
|
||||
|
||||
#include "teamplay_gamerules.h"
|
||||
#include "teamplay_round_timer.h"
|
||||
#include "GameEventListener.h"
|
||||
|
||||
#ifdef GAME_DLL
|
||||
#include "team_control_point.h"
|
||||
@ -162,7 +163,7 @@ public:
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Teamplay game rules that manage a round based structure for you
|
||||
//-----------------------------------------------------------------------------
|
||||
class CTeamplayRoundBasedRules : public CTeamplayRules
|
||||
class CTeamplayRoundBasedRules : public CTeamplayRules, public CGameEventListener
|
||||
{
|
||||
DECLARE_CLASS( CTeamplayRoundBasedRules, CTeamplayRules );
|
||||
public:
|
||||
@ -248,7 +249,7 @@ public:
|
||||
void SetMultipleTrains( bool bMultipleTrains ){ m_bMultipleTrains = bMultipleTrains; }
|
||||
bool HasMultipleTrains( void ){ return m_bMultipleTrains; }
|
||||
|
||||
virtual int GetBonusRoundTime( void );
|
||||
virtual int GetBonusRoundTime( bool bFinal = false );
|
||||
|
||||
#if defined(TF_CLIENT_DLL) || defined(TF_DLL)
|
||||
|
||||
@ -258,10 +259,15 @@ public:
|
||||
|
||||
// Get list of players who are on the defending team now, or are likely
|
||||
// to end up on the defending team (not yet connected or assigned a team)
|
||||
void GetMvMPotentialDefendersLobbyPlayerInfo( CUtlVector<LobbyPlayerInfo_t> &vecMvmDefenders, bool bIncludeBots = false );
|
||||
void GetPotentialPlayersLobbyPlayerInfo( CUtlVector<LobbyPlayerInfo_t> &vecLobbyPlayers, bool bIncludeBots = false );
|
||||
|
||||
#endif
|
||||
|
||||
void SetAllowBetweenRounds( bool bValue ) { m_bAllowBetweenRounds = bValue; }
|
||||
|
||||
public: // IGameEventListener Interface
|
||||
virtual void FireGameEvent( IGameEvent * event );
|
||||
|
||||
//----------------------------------------------------------------------------------
|
||||
// Server specific
|
||||
#ifdef GAME_DLL
|
||||
@ -309,7 +315,7 @@ public:
|
||||
|
||||
virtual bool ShouldScorePerRound( void ){ return true; }
|
||||
|
||||
bool CheckNextLevelCvar( void );
|
||||
bool CheckNextLevelCvar( bool bAllowEnd = true );
|
||||
|
||||
virtual bool TimerMayExpire( void );
|
||||
|
||||
@ -332,7 +338,7 @@ public:
|
||||
bool IsPreviouslyPlayedRound ( string_t strName );
|
||||
string_t GetLastPlayedRound( void );
|
||||
|
||||
virtual void SetWinningTeam( int team, int iWinReason, bool bForceMapReset = true, bool bSwitchTeams = false, bool bDontAddScore = false );
|
||||
virtual void SetWinningTeam( int team, int iWinReason, bool bForceMapReset = true, bool bSwitchTeams = false, bool bDontAddScore = false, bool bFinal = false ) OVERRIDE;
|
||||
virtual void SetStalemate( int iReason, bool bForceMapReset = true, bool bSwitchTeams = false );
|
||||
|
||||
virtual void SetRoundOverlayDetails( void ){ return; }
|
||||
@ -365,10 +371,11 @@ public:
|
||||
{
|
||||
m_bPlayerReady.Set( iIndex, bState );
|
||||
}
|
||||
void ResetPlayerAndTeamReadyState( void );
|
||||
|
||||
virtual void PlayTrainCaptureAlert( CTeamControlPoint *pPoint, bool bFinalPointInMap ){ return; }
|
||||
|
||||
virtual void PlaySpecialCapSounds( int iCappingTeam ){ return; }
|
||||
virtual void PlaySpecialCapSounds( int iCappingTeam, CTeamControlPoint *pPoint ){ return; }
|
||||
|
||||
bool PlayThrottledAlert( int iTeam, const char *sound, float fDelayBeforeNext );
|
||||
|
||||
@ -393,14 +400,15 @@ protected:
|
||||
void CheckWaitingForPlayers( void );
|
||||
virtual bool AllowWaitingForPlayers( void ) { return true; }
|
||||
void CheckRestartRound( void );
|
||||
bool CheckTimeLimit( void );
|
||||
bool CheckTimeLimit( bool bAllowEnd = true );
|
||||
int GetTimeLeft( void );
|
||||
virtual bool CheckWinLimit( void );
|
||||
bool CheckMaxRounds( void );
|
||||
virtual bool CheckWinLimit( bool bAllowEnd = true );
|
||||
bool CheckMaxRounds( bool bAllowEnd = true );
|
||||
|
||||
void CheckReadyRestart( void );
|
||||
#if defined(TF_CLIENT_DLL) || defined(TF_DLL)
|
||||
bool AreDefendingPlayersReady();
|
||||
bool AreLobbyPlayersOnTeamReady( int iTeam );
|
||||
bool AreLobbyPlayersConnected( void );
|
||||
#endif
|
||||
|
||||
virtual bool CanChangelevelBecauseOfTimeLimit( void ) { return true; }
|
||||
@ -479,6 +487,8 @@ protected:
|
||||
bool MapHasActiveTimer( void );
|
||||
void CreateTimeLimitTimer( void );
|
||||
|
||||
virtual float GetLastMajorEventTime( void ) OVERRIDE { return m_flLastTeamWin; }
|
||||
|
||||
protected:
|
||||
CGameRulesRoundStateInfo *m_pCurStateInfo; // Per-state data
|
||||
float m_flStateTransitionTime; // Timer for round states
|
||||
@ -521,10 +531,13 @@ protected:
|
||||
|
||||
gamerules_roundstate_t m_prevState;
|
||||
|
||||
bool m_bPlayerReadyBefore[MAX_PLAYERS+1]; // Test to see if a player has hit ready before
|
||||
|
||||
float m_flLastTeamWin;
|
||||
|
||||
private:
|
||||
|
||||
CUtlMap < int, int > m_GameTeams; // Team index, Score
|
||||
|
||||
#endif
|
||||
// End server specific
|
||||
//----------------------------------------------------------------------------------
|
||||
@ -582,6 +595,9 @@ private:
|
||||
int m_nAutoBalanceQueuePlayerIndex;
|
||||
int m_nAutoBalanceQueuePlayerScore;
|
||||
|
||||
protected:
|
||||
bool m_bAllowBetweenRounds;
|
||||
|
||||
public:
|
||||
|
||||
float m_flStopWatchTotalTime;
|
||||
|
33
game/shared/triggers_shared.h
Normal file
33
game/shared/triggers_shared.h
Normal file
@ -0,0 +1,33 @@
|
||||
//====== Copyright <20> 1996-2005, Valve Corporation, All rights reserved. =======
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
#ifndef TRIGGERS_SHARED_H
|
||||
#define TRIGGERS_SHARED_H
|
||||
#ifdef _WIN32
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
//
|
||||
// Spawnflags
|
||||
//
|
||||
enum
|
||||
{
|
||||
SF_TRIGGER_ALLOW_CLIENTS = 0x01, // Players can fire this trigger
|
||||
SF_TRIGGER_ALLOW_NPCS = 0x02, // NPCS can fire this trigger
|
||||
SF_TRIGGER_ALLOW_PUSHABLES = 0x04, // Pushables can fire this trigger
|
||||
SF_TRIGGER_ALLOW_PHYSICS = 0x08, // Physics objects can fire this trigger
|
||||
SF_TRIGGER_ONLY_PLAYER_ALLY_NPCS = 0x10, // *if* NPCs can fire this trigger, this flag means only player allies do so
|
||||
SF_TRIGGER_ONLY_CLIENTS_IN_VEHICLES = 0x20, // *if* Players can fire this trigger, this flag means only players inside vehicles can
|
||||
SF_TRIGGER_ALLOW_ALL = 0x40, // Everything can fire this trigger EXCEPT DEBRIS!
|
||||
SF_TRIGGER_ONLY_CLIENTS_OUT_OF_VEHICLES = 0x200, // *if* Players can fire this trigger, this flag means only players outside vehicles can
|
||||
SF_TRIG_PUSH_ONCE = 0x80, // trigger_push removes itself after firing once
|
||||
SF_TRIG_PUSH_AFFECT_PLAYER_ON_LADDER = 0x100, // if pushed object is player on a ladder, then this disengages them from the ladder (HL2only)
|
||||
SF_TRIG_TOUCH_DEBRIS = 0x400, // Will touch physics debris objects
|
||||
SF_TRIGGER_ONLY_NPCS_IN_VEHICLES = 0X800, // *if* NPCs can fire this trigger, only NPCs in vehicles do so (respects player ally flag too)
|
||||
SF_TRIGGER_DISALLOW_BOTS = 0x1000, // Bots are not allowed to fire this trigger
|
||||
};
|
||||
|
||||
#endif // TRIGGERS_SHARED_H
|
@ -51,6 +51,9 @@ public:
|
||||
weaponselect = 0;
|
||||
weaponsubtype = 0;
|
||||
random_seed = 0;
|
||||
#ifdef GAME_DLL
|
||||
server_random_seed = 0;
|
||||
#endif
|
||||
mousedx = 0;
|
||||
mousedy = 0;
|
||||
|
||||
@ -76,6 +79,9 @@ public:
|
||||
weaponselect = src.weaponselect;
|
||||
weaponsubtype = src.weaponsubtype;
|
||||
random_seed = src.random_seed;
|
||||
#ifdef GAME_DLL
|
||||
server_random_seed = src.server_random_seed;
|
||||
#endif
|
||||
mousedx = src.mousedx;
|
||||
mousedy = src.mousedy;
|
||||
|
||||
@ -151,6 +157,10 @@ public:
|
||||
int weaponsubtype;
|
||||
|
||||
int random_seed; // For shared random functions
|
||||
#ifdef GAME_DLL
|
||||
// AlliedModders - This member only exists after the 2015 SDK update.
|
||||
int server_random_seed; // Only the server populates this seed
|
||||
#endif
|
||||
|
||||
short mousedx; // mouse accum in x from create move
|
||||
short mousedy; // mouse accum in y from create move
|
||||
|
@ -441,8 +441,8 @@ inline float DistanceToRay( const Vector &pos, const Vector &rayStart, const Vec
|
||||
public: \
|
||||
interfaceName( bool bAutoAdd = true ); \
|
||||
virtual ~interfaceName(); \
|
||||
static void Add( interfaceName *pElement ) { m_##interfaceName##AutoList.AddToTail( pElement ); } \
|
||||
static void Remove( interfaceName *pElement ) { m_##interfaceName##AutoList.FindAndFastRemove( pElement ); } \
|
||||
static void AddToAutoList( interfaceName *pElement ) { m_##interfaceName##AutoList.AddToTail( pElement ); } \
|
||||
static void RemoveFromAutoList( interfaceName *pElement ) { m_##interfaceName##AutoList.FindAndFastRemove( pElement ); } \
|
||||
static const CUtlVector< interfaceName* >& AutoList( void ) { return m_##interfaceName##AutoList; } \
|
||||
private: \
|
||||
static CUtlVector< interfaceName* > m_##interfaceName##AutoList; \
|
||||
@ -456,14 +456,28 @@ inline float DistanceToRay( const Vector &pos, const Vector &rayStart, const Vec
|
||||
{ \
|
||||
if ( bAutoAdd ) \
|
||||
{ \
|
||||
Add( this ); \
|
||||
AddToAutoList( this ); \
|
||||
} \
|
||||
} \
|
||||
interfaceName::~interfaceName() \
|
||||
{ \
|
||||
Remove( this ); \
|
||||
RemoveFromAutoList( this ); \
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------------------
|
||||
// This would do the same thing without requiring casts all over the place. Yes, it's a template, but
|
||||
// DECLARE_AUTO_LIST requires a CUtlVector<T> anyway. TODO ask about replacing the macros with this.
|
||||
//template<class T>
|
||||
//class AutoList {
|
||||
//public:
|
||||
// typedef CUtlVector<T*> AutoListType;
|
||||
// static AutoListType& All() { return m_autolist; }
|
||||
//protected:
|
||||
// AutoList() { m_autolist.AddToTail(static_cast<T*>(this)); }
|
||||
// virtual ~AutoList() { m_autolist.FindAndFastRemove(static_cast<T*>(this)); }
|
||||
//private:
|
||||
// static AutoListType m_autolist;
|
||||
//};
|
||||
|
||||
//--------------------------------------------------------------------------------------------------------------
|
||||
/**
|
||||
@ -579,7 +593,15 @@ public:
|
||||
private:
|
||||
float m_duration;
|
||||
float m_timestamp;
|
||||
float Now( void ) const; // work-around since client header doesn't like inlined gpGlobals->curtime
|
||||
virtual float Now( void ) const; // work-around since client header doesn't like inlined gpGlobals->curtime
|
||||
};
|
||||
|
||||
class RealTimeCountdownTimer : public CountdownTimer
|
||||
{
|
||||
virtual float Now( void ) const OVERRIDE
|
||||
{
|
||||
return Plat_FloatTime();
|
||||
}
|
||||
};
|
||||
|
||||
char* ReadAndAllocStringValue( KeyValues *pSub, const char *pName, const char *pFilename = NULL );
|
||||
|
@ -37,7 +37,7 @@ ConVar voice_serverdebug( "voice_serverdebug", "0" );
|
||||
|
||||
// Set game rules to allow all clients to talk to each other.
|
||||
// Muted players still can't talk to each other.
|
||||
ConVar sv_alltalk( "sv_alltalk", "0", FCVAR_NOTIFY, "Players can hear all other players, no team restrictions" );
|
||||
ConVar sv_alltalk( "sv_alltalk", "0", FCVAR_NOTIFY | FCVAR_REPLICATED, "Players can hear all other players, no team restrictions" );
|
||||
|
||||
|
||||
CVoiceGameMgr g_VoiceGameMgr;
|
||||
|
@ -70,7 +70,7 @@ itemFlags_t g_ItemFlags[8] =
|
||||
{ "ITEM_FLAG_NOITEMPICKUP", ITEM_FLAG_NOITEMPICKUP }
|
||||
};
|
||||
#else
|
||||
extern itemFlags_t g_ItemFlags[7];
|
||||
extern itemFlags_t g_ItemFlags[8];
|
||||
#endif
|
||||
|
||||
|
||||
@ -78,7 +78,7 @@ static CUtlDict< FileWeaponInfo_t*, unsigned short > m_WeaponInfoDatabase;
|
||||
|
||||
#ifdef _DEBUG
|
||||
// used to track whether or not two weapons have been mistakenly assigned the wrong slot
|
||||
bool g_bUsedWeaponSlots[MAX_WEAPON_SLOTS][MAX_WEAPON_POSITIONS] = { 0 };
|
||||
bool g_bUsedWeaponSlots[MAX_WEAPON_SLOTS][MAX_WEAPON_POSITIONS] = { { false } };
|
||||
|
||||
#endif
|
||||
|
||||
|
Reference in New Issue
Block a user