1
0
mirror of https://github.com/alliedmodders/hl2sdk.git synced 2025-09-19 12:06:07 +08:00

Sync with latest source-sdk-2013.

This commit is contained in:
Nicholas Hastings
2014-10-30 12:30:57 -04:00
parent 6abc7fddca
commit aa5841f220
407 changed files with 6784 additions and 10498 deletions

View File

@ -1199,6 +1199,7 @@ void CBaseGameStats_Driver::ResetData()
pKV->SetInt( "Height", dest_height );
const MaterialSystem_Config_t &config = materials->GetCurrentConfigForVideoCard();
pKV->SetInt( "Windowed", config.Windowed() == true );
pKV->SetInt( "MaxDxLevel", g_pMaterialSystemHardwareConfig->GetMaxDXSupportLevel() );
engine->SetGamestatsData( m_pGamestatsData );
#endif

View File

@ -358,16 +358,21 @@ void CMultiPlayerAnimState::PlayFlinchGesture( Activity iActivity )
//-----------------------------------------------------------------------------
bool CMultiPlayerAnimState::InitGestureSlots( void )
{
// Get the base player.
CBasePlayer *pPlayer = GetBasePlayer();
if( pPlayer )
// Setup the number of gesture slots.
m_aGestureSlots.AddMultipleToTail( GESTURE_SLOT_COUNT );
// Assign all of the the CAnimationLayer pointers to null early in case we bail.
for ( int iGesture = 0; iGesture < GESTURE_SLOT_COUNT; ++iGesture )
{
// Set the number of animation overlays we will use.
pPlayer->SetNumAnimOverlays( GESTURE_SLOT_COUNT );
m_aGestureSlots[iGesture].m_pAnimLayer = NULL;
}
// Setup the number of gesture slots.
m_aGestureSlots.AddMultipleToTail( GESTURE_SLOT_COUNT );
// Get the base player.
CBasePlayer *pPlayer = GetBasePlayer();
// Set the number of animation overlays we will use.
pPlayer->SetNumAnimOverlays( GESTURE_SLOT_COUNT );
for ( int iGesture = 0; iGesture < GESTURE_SLOT_COUNT; ++iGesture )
{
m_aGestureSlots[iGesture].m_pAnimLayer = pPlayer->GetAnimOverlay( iGesture );
@ -409,6 +414,9 @@ void CMultiPlayerAnimState::ResetGestureSlot( int iGestureSlot )
// Sanity Check
Assert( iGestureSlot >= 0 && iGestureSlot < GESTURE_SLOT_COUNT );
if ( !VerifyAnimLayerInSlot( iGestureSlot ) )
return;
GestureSlot_t *pGestureSlot = &m_aGestureSlots[iGestureSlot];
if ( pGestureSlot )
{
@ -486,6 +494,36 @@ bool CMultiPlayerAnimState::IsGestureSlotActive( int iGestureSlot )
return m_aGestureSlots[iGestureSlot].m_bActive;
}
//-----------------------------------------------------------------------------
// Purpose: Track down a crash
//-----------------------------------------------------------------------------
bool CMultiPlayerAnimState::VerifyAnimLayerInSlot( int iGestureSlot )
{
if ( iGestureSlot < 0 || iGestureSlot >= GESTURE_SLOT_COUNT )
{
return false;
}
if ( GetBasePlayer()->GetNumAnimOverlays() < iGestureSlot + 1 )
{
AssertMsg2( false, "Player %d doesn't have gesture slot %d any more.", GetBasePlayer()->entindex(), iGestureSlot );
Msg( "Player %d doesn't have gesture slot %d any more.\n", GetBasePlayer()->entindex(), iGestureSlot );
m_aGestureSlots[iGestureSlot].m_pAnimLayer = NULL;
return false;
}
CAnimationLayer *pExpected = GetBasePlayer()->GetAnimOverlay( iGestureSlot );
if ( m_aGestureSlots[iGestureSlot].m_pAnimLayer != pExpected )
{
AssertMsg3( false, "Gesture slot %d pointing to wrong address %p. Updating to new address %p.", iGestureSlot, m_aGestureSlots[iGestureSlot].m_pAnimLayer, pExpected );
Msg( "Gesture slot %d pointing to wrong address %p. Updating to new address %p.\n", iGestureSlot, m_aGestureSlots[iGestureSlot].m_pAnimLayer, pExpected );
m_aGestureSlots[iGestureSlot].m_pAnimLayer = pExpected;
}
return true;
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
@ -509,6 +547,9 @@ void CMultiPlayerAnimState::RestartGesture( int iGestureSlot, Activity iGestureA
// Sanity Check
Assert( iGestureSlot >= 0 && iGestureSlot < GESTURE_SLOT_COUNT );
if ( !VerifyAnimLayerInSlot( iGestureSlot ) )
return;
if ( !IsGestureSlotPlaying( iGestureSlot, iGestureActivity ) )
{
#ifdef CLIENT_DLL
@ -549,6 +590,9 @@ void CMultiPlayerAnimState::AddToGestureSlot( int iGestureSlot, Activity iGestur
if ( !m_aGestureSlots[iGestureSlot].m_pAnimLayer )
return;
if ( !VerifyAnimLayerInSlot( iGestureSlot ) )
return;
// Get the sequence.
int iGestureSequence = pPlayer->SelectWeightedSequence( iGestureActivity );
if ( iGestureSequence <= 0 )
@ -623,6 +667,9 @@ void CMultiPlayerAnimState::AddVCDSequenceToGestureSlot( int iGestureSlot, int i
if ( !m_aGestureSlots[iGestureSlot].m_pAnimLayer )
return;
if ( !VerifyAnimLayerInSlot( iGestureSlot ) )
return;
// Set the activity.
Activity iGestureActivity = ACT_MP_VCD;
@ -1154,6 +1201,9 @@ void CMultiPlayerAnimState::ComputeGestureSequence( CStudioHdr *pStudioHdr )
if ( !m_aGestureSlots[iGesture].m_bActive )
continue;
if ( !VerifyAnimLayerInSlot( iGesture ) )
continue;
UpdateGestureLayer( pStudioHdr, &m_aGestureSlots[iGesture] );
}
}

View File

@ -200,6 +200,7 @@ public:
void AddVCDSequenceToGestureSlot( int iGestureSlot, int iGestureSequence, float flCycle = 0.0f, bool bAutoKill = true );
CAnimationLayer* GetGestureSlotLayer( int iGestureSlot );
bool IsGestureSlotActive( int iGestureSlot );
bool VerifyAnimLayerInSlot( int iGestureSlot );
// Feet.
bool m_bForceAimYaw;

View File

@ -465,7 +465,6 @@ public:
{
return;
}
#endif // STAGING_ONLY
if ( !Q_strncasecmp( params.soundname, "vo", 2 ) &&
!( params.channel == CHAN_STREAM ||
@ -475,6 +474,7 @@ public:
DevMsg( "EmitSound: Voice wave file %s doesn't specify CHAN_VOICE, CHAN_VOICE2 or CHAN_STREAM for sound %s\n",
params.soundname, ep.m_pSoundName );
}
#endif // STAGING_ONLY
// handle SND_CHANGEPITCH/SND_CHANGEVOL and other sound flags.etc.
if( ep.m_nFlags & SND_CHANGE_PITCH )

View File

@ -2275,6 +2275,35 @@ void ActivityList_RegisterSharedActivities( void )
REGISTER_SHARED_ACTIVITY( ACT_SPELL_VM_ARM );
REGISTER_SHARED_ACTIVITY( ACT_SPELL_VM_FIRE );
REGISTER_SHARED_ACTIVITY( ACT_BREADSAPPER_VM_DRAW );
REGISTER_SHARED_ACTIVITY( ACT_BREADSAPPER_VM_IDLE );
REGISTER_SHARED_ACTIVITY( ACT_BREADGLOVES_VM_HITLEFT );
REGISTER_SHARED_ACTIVITY( ACT_BREADGLOVES_VM_HITRIGHT );
REGISTER_SHARED_ACTIVITY( ACT_BREADGLOVES_VM_SWINGHARD );
REGISTER_SHARED_ACTIVITY( ACT_BREADGLOVES_VM_IDLE );
REGISTER_SHARED_ACTIVITY( ACT_BREADGLOVES_VM_DRAW );
REGISTER_SHARED_ACTIVITY( ACT_BREADMONSTER_GLOVES_IDLE );
REGISTER_SHARED_ACTIVITY( ACT_BREADMONSTER_GLOVES_HITRIGHT );
REGISTER_SHARED_ACTIVITY( ACT_BREADMONSTER_GLOVES_HITUP );
REGISTER_SHARED_ACTIVITY( ACT_BREADMONSTER_VM_DRAW );
REGISTER_SHARED_ACTIVITY( ACT_BREADMONSTER_VM_IDLE );
REGISTER_SHARED_ACTIVITY( ACT_BREADMONSTER_VM_PRIMARYATTACK );
REGISTER_SHARED_ACTIVITY( ACT_PARACHUTE_DEPLOY );
REGISTER_SHARED_ACTIVITY( ACT_PARACHUTE_DEPLOY_IDLE );
REGISTER_SHARED_ACTIVITY( ACT_PARACHUTE_RETRACT );
REGISTER_SHARED_ACTIVITY( ACT_PARACHUTE_RETRACT_IDLE );
REGISTER_SHARED_ACTIVITY( ACT_BOT_SPAWN );
REGISTER_SHARED_ACTIVITY( ACT_BOT_PANIC );
REGISTER_SHARED_ACTIVITY( ACT_BOT_PRIMARY_MOVEMENT );
REGISTER_SHARED_ACTIVITY( ACT_BOT_GESTURE_FLINCH );
REGISTER_SHARED_ACTIVITY( ACT_BOT_PANIC_START );
REGISTER_SHARED_ACTIVITY( ACT_BOT_PANIC_END );
AssertMsg( g_HighestActivity == LAST_SHARED_ACTIVITY - 1, "Not all activities from ai_activity.h registered in activitylist.cpp" );
}

View File

@ -2107,6 +2107,37 @@ typedef enum
ACT_SPELL_VM_ARM,
ACT_SPELL_VM_FIRE,
// Bread Monster Sapper
ACT_BREADSAPPER_VM_DRAW,
ACT_BREADSAPPER_VM_IDLE,
// Bread Gloves
ACT_BREADGLOVES_VM_HITLEFT,
ACT_BREADGLOVES_VM_HITRIGHT,
ACT_BREADGLOVES_VM_SWINGHARD,
ACT_BREADGLOVES_VM_IDLE,
ACT_BREADGLOVES_VM_DRAW,
ACT_BREADMONSTER_GLOVES_IDLE,
ACT_BREADMONSTER_GLOVES_HITRIGHT,
ACT_BREADMONSTER_GLOVES_HITUP,
ACT_BREADMONSTER_VM_DRAW,
ACT_BREADMONSTER_VM_IDLE,
ACT_BREADMONSTER_VM_PRIMARYATTACK,
ACT_PARACHUTE_DEPLOY,
ACT_PARACHUTE_DEPLOY_IDLE,
ACT_PARACHUTE_RETRACT,
ACT_PARACHUTE_RETRACT_IDLE,
ACT_BOT_SPAWN,
ACT_BOT_PANIC,
ACT_BOT_PRIMARY_MOVEMENT,
ACT_BOT_GESTURE_FLINCH,
ACT_BOT_PANIC_START,
ACT_BOT_PANIC_END,
// this is the end of the global activities, private per-monster activities start here.
LAST_SHARED_ACTIVITY,
} Activity;

View File

@ -46,9 +46,10 @@ template< class T, class Functor=CDefaultCalcDistance<T> >
class CApparentVelocity
{
public:
CApparentVelocity()
CApparentVelocity(const T& t0)
{
m_LastTime = -1;
m_LastValue = t0;
}
float AddSample( float time, T value )

View File

@ -65,7 +65,7 @@ CBasePlayerAnimState::CBasePlayerAnimState()
m_flEyePitch = 0.0f;
m_bCurrentFeetYawInitialized = false;
m_flCurrentTorsoYaw = 0.0f;
m_flCurrentTorsoYaw = TURN_NONE;
m_nTurningInPlace = TURN_NONE;
m_flMaxGroundSpeed = 0.0f;
m_flStoredCycle = 0.0f;

View File

@ -427,13 +427,7 @@ void CBaseAchievement::EnsureComponentBitSetAndEvaluate( int iBitNumber )
// new component, set the bit and increment the count
SetComponentBits( m_iComponentBits | iBitMask );
Assert( m_iCount <= m_iGoal );
if ( m_iCount == m_iGoal )
{
// all components found, award the achievement (and save state)
AwardAchievement();
}
else
if ( m_iCount != m_iGoal )
{
// save our state at the next good opportunity
m_pAchievementMgr->SetDirty( true );
@ -453,6 +447,15 @@ void CBaseAchievement::EnsureComponentBitSetAndEvaluate( int iBitNumber )
Msg( "Component %d for achievement %s found, but already had that component\n", iBitNumber, GetName() );
}
}
// Check to see if we've achieved our goal even if the bit is already set
// (this fixes some older achievements that are stuck in the 9/9 state and could never be evaluated)
Assert( m_iCount <= m_iGoal );
if ( m_iCount == m_iGoal )
{
// all components found, award the achievement (and save state)
AwardAchievement();
}
}
//-----------------------------------------------------------------------------

View File

@ -105,6 +105,9 @@ public:
virtual void Think( void ) { return; }
const char *GetMapNameFilter( void ){ return m_pMapNameFilter; }
CAchievementMgr *GetAchievementMgr( void ){ return m_pAchievementMgr; }
protected:
virtual void FireGameEvent( IGameEvent *event );
virtual void FireGameEvent_Internal( IGameEvent *event ) {};

View File

@ -38,6 +38,8 @@
#endif
#include "vprof.h"
// memdbgon must be the last include file in a .cpp file!!!
#include "tier0/memdbgon.h"
@ -164,8 +166,20 @@ void CBaseCombatWeapon::GiveDefaultAmmo( void )
//-----------------------------------------------------------------------------
void CBaseCombatWeapon::Spawn( void )
{
bool bPrecacheAllowed = CBaseEntity::IsPrecacheAllowed();
if (!bPrecacheAllowed)
{
tmEnter( TELEMETRY_LEVEL1, TMZF_NONE, "LateWeaponPrecache" );
}
Precache();
if (!bPrecacheAllowed)
{
tmLeave( TELEMETRY_LEVEL1 );
}
BaseClass::Spawn();
SetSolid( SOLID_BBOX );
@ -1643,6 +1657,11 @@ void CBaseCombatWeapon::ItemPreFrame( void )
#endif
}
bool CBaseCombatWeapon::CanPerformSecondaryAttack() const
{
return m_flNextSecondaryAttack <= gpGlobals->curtime;
}
//====================================================================================
// WEAPON BEHAVIOUR
//====================================================================================
@ -1667,7 +1686,7 @@ void CBaseCombatWeapon::ItemPostFrame( void )
bool bFired = false;
// Secondary attack has priority
if ((pOwner->m_nButtons & IN_ATTACK2) && (m_flNextSecondaryAttack <= gpGlobals->curtime))
if ((pOwner->m_nButtons & IN_ATTACK2) && CanPerformSecondaryAttack() )
{
if (UsesSecondaryAmmo() && pOwner->GetAmmoCount(m_iSecondaryAmmoType)<=0 )
{

View File

@ -247,6 +247,7 @@ public:
virtual void HandleFireOnEmpty(); // Called when they have the attack button down
// but they are out of ammo. The default implementation
// either reloads, switches weapons, or plays an empty sound.
virtual bool CanPerformSecondaryAttack() const;
virtual bool ShouldBlockPrimaryFire() { return false; }

View File

@ -2250,6 +2250,15 @@ int CBaseEntity::GetTracerAttachment( void )
return iAttachment;
}
float CBaseEntity::HealthFraction() const
{
if ( GetMaxHealth() == 0 )
return 1.0f;
float flFraction = ( float )GetHealth() / ( float )GetMaxHealth();
flFraction = clamp( flFraction, 0.0f, 1.0f );
return flFraction;
}
int CBaseEntity::BloodColor()
{

View File

@ -12,6 +12,11 @@
IMPLEMENT_NETWORKCLASS_ALIASED( BaseProjectile, DT_BaseProjectile )
BEGIN_NETWORK_TABLE( CBaseProjectile, DT_BaseProjectile )
#if !defined( CLIENT_DLL )
SendPropEHandle( SENDINFO( m_hOriginalLauncher ) ),
#else
RecvPropEHandle( RECVINFO( m_hOriginalLauncher ) ),
#endif // CLIENT_DLL
END_NETWORK_TABLE()
@ -22,5 +27,63 @@ CBaseProjectile::CBaseProjectile()
{
#ifdef GAME_DLL
m_iDestroyableHitCount = 0;
m_bCanCollideWithTeammates = false;
#endif
m_hOriginalLauncher = NULL;
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CBaseProjectile::SetLauncher( CBaseEntity *pLauncher )
{
if ( m_hOriginalLauncher == NULL )
{
m_hOriginalLauncher = pLauncher;
}
#ifdef GAME_DLL
ResetCollideWithTeammates();
#endif // GAME_DLL
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CBaseProjectile::Spawn()
{
BaseClass::Spawn();
#ifdef GAME_DLL
ResetCollideWithTeammates();
#endif // GAME_DLL
}
#ifdef GAME_DLL
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CBaseProjectile::CollideWithTeammatesThink()
{
m_bCanCollideWithTeammates = true;
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CBaseProjectile::ResetCollideWithTeammates()
{
// Don't collide with players on the owner's team for the first bit of our life
m_bCanCollideWithTeammates = false;
SetContextThink( &CBaseProjectile::CollideWithTeammatesThink, gpGlobals->curtime + GetCollideWithTeammatesDelay(), "CollideWithTeammates" );
}
#endif // GAME_DLL

View File

@ -36,18 +36,37 @@ public:
CBaseProjectile();
virtual void Spawn();
#ifdef GAME_DLL
virtual int GetDestroyableHitCount( void ) const { return m_iDestroyableHitCount; }
void IncrementDestroyableHitCount( void ) { ++m_iDestroyableHitCount; }
bool CanCollideWithTeammates() const { return m_bCanCollideWithTeammates; }
virtual float GetCollideWithTeammatesDelay() const { return 0.25f; }
#endif // GAME_DLL
virtual bool IsDestroyable( void ) { return false; }
virtual void Destroy( bool bBlinkOut = true, bool bBreakRocket = false ) {}
virtual void SetLauncher( CBaseEntity *pLauncher );
CBaseEntity *GetOriginalLauncher() const { return m_hOriginalLauncher; }
protected:
#ifdef GAME_DLL
void CollideWithTeammatesThink();
int m_iDestroyableHitCount;
#endif // GAME_DLL
private:
#ifdef GAME_DLL
void ResetCollideWithTeammates();
bool m_bCanCollideWithTeammates;
#endif // GAME_DLL
CNetworkHandle( CBaseEntity, m_hOriginalLauncher );
};
#endif // BASEPROJECTILE_H

View File

@ -2076,8 +2076,8 @@ public:
{
if ( ARRAYSIZE( g_NameMap ) != CChoreoEvent::NUM_TYPES )
{
Error( "g_NameMap contains %i entries, CChoreoEvent::NUM_TYPES == %i!",
ARRAYSIZE( g_NameMap ), CChoreoEvent::NUM_TYPES );
Error( "g_NameMap contains %llu entries, CChoreoEvent::NUM_TYPES == %i!",
(uint64)(ARRAYSIZE( g_NameMap )), CChoreoEvent::NUM_TYPES );
}
for ( int i = 0; i < CChoreoEvent::NUM_TYPES; ++i )
{
@ -2158,8 +2158,8 @@ public:
{
if ( ARRAYSIZE( g_CCNameMap ) != CChoreoEvent::NUM_CC_TYPES )
{
Error( "g_CCNameMap contains %i entries, CChoreoEvent::NUM_CC_TYPES == %i!",
ARRAYSIZE( g_CCNameMap ), CChoreoEvent::NUM_CC_TYPES );
Error( "g_CCNameMap contains %llu entries, CChoreoEvent::NUM_CC_TYPES == %i!",
(uint64)(ARRAYSIZE( g_CCNameMap )), CChoreoEvent::NUM_CC_TYPES );
}
for ( int i = 0; i < CChoreoEvent::NUM_CC_TYPES; ++i )
{

View File

@ -158,6 +158,7 @@ CChoreoScene& CChoreoScene::operator=( const CChoreoScene& src )
m_pTokenizer = src.m_pTokenizer;
m_flCurrentTime = src.m_flCurrentTime;
m_flStartLoopTime = src.m_flStartLoopTime;
m_flStartTime = src.m_flStartTime;
m_flEndTime = src.m_flEndTime;
m_flSoundSystemLatency = src.m_flSoundSystemLatency;
@ -236,6 +237,7 @@ void CChoreoScene::Init( IChoreoEventCallback *callback )
m_szMapname[ 0 ] = 0;
m_flCurrentTime = 0.0f;
m_flStartLoopTime = -1.f;
m_flStartTime = 0.0f;
m_flEndTime = 0.0f;
m_flSoundSystemLatency = 0.0f;
@ -2314,6 +2316,8 @@ void CChoreoScene::ResetSimulation( bool forward /*= true*/, float starttime /*=
m_flCurrentTime = forward ? m_flEarliestTime : m_flLatestTime;
m_flStartLoopTime = -1.f;
// choreoprintf( 0, "Start time %f\n", m_flCurrentTime );
m_flLastActiveTime = 0.0f;
@ -2475,6 +2479,15 @@ int CChoreoScene::EventThink( CChoreoEvent *e, float frame_start_time, float fra
}
}
*/
if ( !suppressed )
{
// if this SPEAK event starts before the beginning of the current loop, don't play the SPEAK event again in the loop
if ( m_flStartLoopTime >= 0.f && starttime < m_flStartLoopTime )
{
return iret;
}
}
}
break;
case CChoreoEvent::SUBSCENE:
@ -2838,6 +2851,8 @@ void CChoreoScene::SetTime( float t )
void CChoreoScene::LoopToTime( float t )
{
m_flCurrentTime = t;
m_flStartLoopTime = t;
}
//-----------------------------------------------------------------------------

View File

@ -326,6 +326,8 @@ private:
// Current simulation time
float m_flCurrentTime;
float m_flStartLoopTime;
float m_flStartTime;
float m_flEndTime;

View File

@ -33,10 +33,10 @@ enum
// Commander mode table
static colorentry_t commandercolors[] =
{
{ COMMAND_POINT_RED, 1.0, 0.0, 0.0 },
{ COMMAND_POINT_BLUE, 0.0, 0.0, 1.0 },
{ COMMAND_POINT_GREEN, 0.0, 1.0, 0.0 },
{ COMMAND_POINT_YELLOW, 1.0, 1.0, 0.0 },
{ COMMAND_POINT_RED, 1, 0, 0 },
{ COMMAND_POINT_BLUE, 0, 0, 1 },
{ COMMAND_POINT_GREEN, 0, 1, 0 },
{ COMMAND_POINT_YELLOW, 1, 1, 0 },
};
static colorentry_t bloodcolors[] =

View File

@ -248,4 +248,5 @@ void EventList_RegisterSharedEvents( void )
REGISTER_SHARED_ANIMEVENT( AE_WPN_UNHIDE, AE_TYPE_CLIENT | AE_TYPE_SERVER );
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 );
}

View File

@ -85,6 +85,8 @@ typedef enum
AE_WPN_PLAYWPNSOUND, // Play a weapon sound from the weapon script file
AE_RD_ROBOT_POP_PANELS_OFF,
LAST_SHARED_ANIMEVENT,
} Animevent;

View File

@ -518,7 +518,7 @@ void CGameMovement::DiffPrint( char const *fmt, ... )
#endif // !PREDICTION_ERROR_CHECK_LEVEL
#ifndef _XBOX
void COM_Log( char *pszFile, const char *fmt, ...)
void COM_Log( const char *pszFile, const char *fmt, ...)
{
va_list argptr;
char string[1024];

View File

@ -205,6 +205,8 @@ public:
#else
virtual void Status( void (*print) (const char *fmt, ...) ) {}
virtual void GetTaggedConVarList( KeyValues *pCvarTagList ) {}
// NVNT see if the client of the player entered is using a haptic device.

View File

@ -125,7 +125,7 @@ const char *MapEntity_ParseToken( const char *data, char *newToken )
for ( const char *c = s_BraceChars; *c; c++ )
{
s_BraceCharacters[*c] = true;
s_BraceCharacters[(unsigned)*c] = true;
}
}

View File

@ -185,6 +185,10 @@ const char *g_pszMPConcepts[] =
"TLK_MVM_LOOT_RARE", // MP_CONCEPT_MVM_LOOT_RARE
"TLK_MVM_LOOT_ULTRARARE", // MP_CONCEPT_MVM_LOOT_ULTRARARE
"TLK_MEDIC_HEAL_SHIELD", // MP_CONCEPT_MEDIC_HEAL_SHIELD
"TLK_TAUNT_EUREKA_EFFECT", // MP_CONCEPT_TAUNT_EUREKA_EFFECT_TELEPORT
"TLK_COMBO_KILLED", // MP_CONCEPT_COMBO_KILLED
};
COMPILE_TIME_ASSERT( ARRAYSIZE( g_pszMPConcepts ) == MP_TF_CONCEPT_COUNT );

View File

@ -195,6 +195,10 @@ enum
MP_CONCEPT_MVM_LOOT_ULTRARARE, // "TLK_MVM_LOOT_ULTRARARE"
MP_CONCEPT_MEDIC_HEAL_SHIELD, // "TLK_MEDIC_HEAL_SHIELD"
MP_CONCEPT_TAUNT_EUREKA_EFFECT_TELEPORT,// "TLK_TAUNT_EUREKA_EFFECT"
MP_CONCEPT_COMBO_KILLED, // "TLK_COMBO_KILLED"
MP_TF_CONCEPT_COUNT
// Other MP_CONCEPT_* start he using MP_TF_CONCEPT_COUNT + 1 as start.

View File

@ -857,9 +857,9 @@ ConVarRef suitcharger( "sk_suitcharger" );
{
killer_weapon_name += 7;
}
else if ( strncmp( killer_weapon_name, "NPC_", 8 ) == 0 )
else if ( strncmp( killer_weapon_name, "NPC_", 4 ) == 0 )
{
killer_weapon_name += 8;
killer_weapon_name += 4;
}
else if ( strncmp( killer_weapon_name, "func_", 5 ) == 0 )
{
@ -1149,14 +1149,17 @@ ConVarRef suitcharger( "sk_suitcharger" );
}
}
void StripChar(char *szBuffer, const char cWhiteSpace )
// Strip ' ' and '\n' characters from string.
static void StripWhitespaceChars( char *szBuffer )
{
char *szOut = szBuffer;
while ( char *pSpace = strchr( szBuffer, cWhiteSpace ) )
for ( char *szIn = szOut; *szIn; szIn++ )
{
char *pNextChar = pSpace + sizeof(char);
V_strcpy( pSpace, pNextChar );
if ( *szIn != ' ' && *szIn != '\r' )
*szOut++ = *szIn;
}
*szOut = '\0';
}
void CMultiplayRules::GetNextLevelName( char *pszNextMap, int bufsize, bool bRandom /* = false */ )
@ -1283,9 +1286,8 @@ ConVarRef suitcharger( "sk_suitcharger" );
{
bool bIgnore = false;
// Strip out the spaces in the name
StripChar( mapList[i] , '\r');
StripChar( mapList[i] , ' ');
// Strip out ' ' and '\r' chars.
StripWhitespaceChars( mapList[i] );
if ( !Q_strncmp( mapList[i], "//", 2 ) || mapList[i][0] == '\0' )
{

View File

@ -309,7 +309,7 @@ void DispatchParticleEffect( const char *pszParticleName, ParticleAttachment_t i
if ( ( data.m_fFlags & PARTICLE_DISPATCH_FROM_ENTITY ) != 0 &&
( iAttachType == PATTACH_ABSORIGIN_FOLLOW || iAttachType == PATTACH_POINT_FOLLOW || iAttachType == PATTACH_ROOTBONE_FOLLOW ) )
{
CReliableBroadcastRecipientFilter filter;
CBroadcastRecipientFilter filter;
DispatchEffect( "ParticleEffect", data, filter );
}
else

View File

@ -200,8 +200,23 @@ void CParticleProperty::AddControlPoint( int iEffectIndex, int iPoint, C_BaseEnt
ParticleEffectList_t *pEffect = &m_ParticleEffects[iEffectIndex];
Assert( pEffect->pControlPoints.Count() < MAX_PARTICLE_CONTROL_POINTS );
int iIndex = pEffect->pControlPoints.AddToTail();
ParticleControlPoint_t *pNewPoint = &pEffect->pControlPoints[iIndex];
// If the control point is already used, override it
ParticleControlPoint_t *pNewPoint = NULL;
int iIndex = iPoint;
FOR_EACH_VEC( pEffect->pControlPoints, i )
{
if ( pEffect->pControlPoints[i].iControlPoint == iPoint )
{
pNewPoint = &pEffect->pControlPoints[i];
}
}
if ( !pNewPoint )
{
iIndex = pEffect->pControlPoints.AddToTail();
pNewPoint = &pEffect->pControlPoints[iIndex];
}
pNewPoint->iControlPoint = iPoint;
pNewPoint->hEntity = pEntity;
pNewPoint->iAttachType = iAttachType;
@ -350,7 +365,7 @@ void CParticleProperty::StopParticlesInvolving( CBaseEntity *pEntity )
// Purpose: Stop all effects that were created using the given definition
// name.
//-----------------------------------------------------------------------------
void CParticleProperty::StopParticlesNamed( const char *pszEffectName, bool bForceRemoveInstantly /* =false */ )
void CParticleProperty::StopParticlesNamed( const char *pszEffectName, bool bForceRemoveInstantly /* =false */, bool bInverse /*= false*/ )
{
CParticleSystemDefinition *pDef = g_pParticleSystemMgr->FindParticleSystem( pszEffectName );
AssertMsg1(pDef, "Could not find particle definition %s", pszEffectName );
@ -369,13 +384,15 @@ void CParticleProperty::StopParticlesNamed( const char *pszEffectName, bool bFor
{
// for each effect...
CNewParticleEffect *pParticleEffect = m_ParticleEffects[i].pParticleEffect.GetObject();
if (pParticleEffect->m_pDef() == pDef)
bool bMatches = pParticleEffect->m_pDef() == pDef;
if ( bMatches == !bInverse )
{
pParticleEffect->StopEmission( false, bRemoveInstantly );
}
}
}
void CParticleProperty::StopParticlesWithNameAndAttachment( const char *pszEffectName, int iAttachmentPoint, bool bForceRemoveInstantly /* =false */ )
{
CParticleSystemDefinition *pDef = g_pParticleSystemMgr->FindParticleSystem( pszEffectName );
@ -547,13 +564,13 @@ void CParticleProperty::UpdateControlPoint( ParticleEffectList_t *pEffect, int i
#ifdef TF_CLIENT_DLL
CBaseEntity *pWearable = (CBaseEntity*) pPoint->hEntity.Get();
if ( pWearable && dynamic_cast<IHasAttributes*>( pWearable ) && !pWearable->IsPlayer() )
if ( pWearable && GetAttribInterface( pWearable ) && !pWearable->IsPlayer() )
{
C_BaseAnimating *pAnimating = pPoint->hEntity->GetBaseAnimating();
if ( pAnimating )
{
int bUseHeadOrigin = 0;
CALL_ATTRIB_HOOK_INT_ON_OTHER( pPoint->hEntity.Get(), bUseHeadOrigin, particle_effect_use_head_origin );
CALL_ATTRIB_HOOK_INT_ON_OTHER( pAnimating, bUseHeadOrigin, particle_effect_use_head_origin );
if ( bUseHeadOrigin > 0 )
{
int iBone = Studio_BoneIndexByName( pAnimating->GetModelPtr(), "bip_head" );
@ -565,15 +582,17 @@ void CParticleProperty::UpdateControlPoint( ParticleEffectList_t *pEffect, int i
iBone = Studio_BoneIndexByName( pAnimating->GetModelPtr(), "prp_hat" );
}
}
if ( iBone >= 0 )
if ( iBone < 0 )
{
bUsingHeadOrigin = true;
const matrix3x4_t headBone = pAnimating->GetBone( iBone );
MatrixVectors( headBone, &vecForward, &vecRight, &vecUp );
MatrixPosition( headBone, vecOrigin );
CALL_ATTRIB_HOOK_FLOAT_ON_OTHER( pPoint->hEntity.Get(), flOffset, particle_effect_vertical_offset );
iBone = 0;
}
bUsingHeadOrigin = true;
const matrix3x4_t headBone = pAnimating->GetBone( iBone );
MatrixVectors( headBone, &vecForward, &vecRight, &vecUp );
MatrixPosition( headBone, vecOrigin );
CALL_ATTRIB_HOOK_FLOAT_ON_OTHER( pAnimating, flOffset, particle_effect_vertical_offset );
}
}
}

View File

@ -90,7 +90,7 @@ public:
// kill all particle systems involving a given entity for their control points
void StopParticlesInvolving( CBaseEntity *pEntity );
void StopParticlesNamed( const char *pszEffectName, bool bForceRemoveInstantly = false ); ///< kills all particles using the given definition name
void StopParticlesNamed( const char *pszEffectName, bool bForceRemoveInstantly = false, bool bInverse = false ); ///< kills all particles using the given definition name
void StopParticlesWithNameAndAttachment( const char *pszEffectName, int iAttachmentPoint, bool bForceRemoveInstantly = false ); ///< kills all particles using the given definition name
// Particle System hooks

View File

@ -231,7 +231,7 @@ void CParticleSystemQuery::GetRandomPointsOnControllingObjectHitBox(
{
bSucesss = true;
Vector vecWorldPosition;
Vector vecWorldPosition(0, 0, 0);
float u = 0, v = 0, w = 0;
int nHitbox = 0;
int nNumIters = nNumTrysToGetAPointInsideTheModel;
@ -308,7 +308,7 @@ void CParticleSystemQuery::GetRandomPointsOnControllingObjectHitBox(
Vector vecWorldPosition;
Vector vecWorldPosition(0, 0, 0);
float u = 0, v = 0, w = 0;
int nHitbox = 0;
int nNumIters = nNumTrysToGetAPointInsideTheModel;

View File

@ -514,7 +514,7 @@ void CPredictionCopy::DescribeQuaternion( difftype_t dt, Quaternion* outValue, c
for ( int j = 0; j < 4; j++ )
{
delta[i] = outValue[i][j] - inValue[i][j];
delta[j] = outValue[i][j] - inValue[i][j];
}
ReportFieldsDiffer( "quaternion[] differs (1st diff) (net %f %f %f %f - pred %f %f %f %f) delta(%f %f %f %f)\n",
@ -933,7 +933,7 @@ CPredictionCopy::difftype_t CPredictionCopy::CompareQuaternion( Quaternion* outV
for ( int j = 0; j < 4; j++ )
{
delta[i] = outValue[i][j] - inValue[i][j];
delta[j] = outValue[i][j] - inValue[i][j];
}
if ( tolerance > 0.0f )

View File

@ -600,6 +600,10 @@ public:
pModel->mpBreakMode = MULTIPLAYER_BREAK_CLIENTSIDE;
}
}
else if ( !strcmpi( pKey, "velocity" ) )
{
UTIL_StringToVector( pModel->velocity.Base(), pValue );
}
}
virtual void SetDefaults( void *pData )
{
@ -617,6 +621,7 @@ public:
pModel->placementName[0] = 0;
pModel->placementIsBone = false;
pModel->mpBreakMode = MULTIPLAYER_BREAK_DEFAULT;
pModel->velocity = vec3_origin;
m_wroteCollisionGroup = false;
}
@ -626,7 +631,7 @@ private:
bool m_wroteCollisionGroup;
};
void BreakModelList( CUtlVector<breakmodel_t> &list, int modelindex, float defBurstScale, int defCollisionGroup )
void BuildPropList( const char *pszBlockName, CUtlVector<breakmodel_t> &list, int modelindex, float defBurstScale, int defCollisionGroup )
{
vcollide_t *pCollide = modelinfo->GetVCollide( modelindex );
if ( !pCollide )
@ -638,7 +643,7 @@ void BreakModelList( CUtlVector<breakmodel_t> &list, int modelindex, float defBu
CBreakParser breakParser( defBurstScale, defCollisionGroup );
const char *pBlock = pParse->GetCurrentBlockName();
if ( !strcmpi( pBlock, "break" ) )
if ( !strcmpi( pBlock, pszBlockName ) )
{
int index = list.AddToTail();
breakmodel_t &breakModel = list[index];
@ -652,6 +657,11 @@ void BreakModelList( CUtlVector<breakmodel_t> &list, int modelindex, float defBu
physcollision->VPhysicsKeyParserDestroy( pParse );
}
void BreakModelList( CUtlVector<breakmodel_t> &list, int modelindex, float defBurstScale, int defCollisionGroup )
{
BuildPropList( "break", list, modelindex, defBurstScale, defCollisionGroup );
}
#if !defined(_STATIC_LINKED) || defined(CLIENT_DLL)
int GetAutoMultiplayerPhysicsMode( Vector size, float mass )
{
@ -1226,9 +1236,8 @@ void PropBreakableCreateAll( int modelindex, IPhysicsObject *pPhysics, const Vec
// Purpose:
// Input : modelindex -
//-----------------------------------------------------------------------------
void PrecacheGibsForModel( int iModel )
void PrecachePropsForModel( int iModel, const char *pszBlockName )
{
VPROF_BUDGET( "PrecacheGibsForModel", VPROF_BUDGETGROUP_PLAYER );
vcollide_t *pCollide = modelinfo->GetVCollide( iModel );
if ( !pCollide )
return;
@ -1241,7 +1250,7 @@ void PrecacheGibsForModel( int iModel )
while ( !pParse->Finished() )
{
const char *pBlock = pParse->GetCurrentBlockName();
if ( !strcmpi( pBlock, "break" ) )
if ( !strcmpi( pBlock, pszBlockName ) )
{
breakmodel_t breakModel;
pParse->ParseCustom( &breakModel, &breakParser );
@ -1257,6 +1266,12 @@ void PrecacheGibsForModel( int iModel )
physcollision->VPhysicsKeyParserDestroy( pParse );
}
void PrecacheGibsForModel( int iModel )
{
VPROF_BUDGET( "PrecacheGibsForModel", VPROF_BUDGETGROUP_PLAYER );
PrecachePropsForModel( iModel, "break" );
}
//-----------------------------------------------------------------------------
// Purpose:
// Input : &list -
@ -1448,12 +1463,21 @@ CBaseEntity *CreateGibsFromList( CUtlVector<breakmodel_t> &list, int modelindex,
}
Vector objectVelocity = params.velocity;
float flScale = VectorNormalize( objectVelocity );
objectVelocity.x += RandomFloat( -1.f, 1.0f );
objectVelocity.y += RandomFloat( -1.0f, 1.0f );
objectVelocity.z += RandomFloat( 0.0f, 1.0f );
VectorNormalize( objectVelocity );
objectVelocity *= flScale;
Vector gibVelocity = vec3_origin;
if ( !list[i].velocity.IsZero() )
{
VectorRotate( list[i].velocity, matrix, gibVelocity );
objectVelocity = gibVelocity;
}
else
{
float flScale = VectorNormalize( objectVelocity );
objectVelocity.x += RandomFloat( -1.f, 1.0f );
objectVelocity.y += RandomFloat( -1.0f, 1.0f );
objectVelocity.z += RandomFloat( 0.0f, 1.0f );
VectorNormalize( objectVelocity );
objectVelocity *= flScale;
}
if (pPhysics)
{

View File

@ -217,6 +217,7 @@ struct breakmodel_t
bool placementIsBone;
bool isMotionDisabled;
mp_break_t mpBreakMode;
Vector velocity;
};
struct breakablepropparams_t
@ -242,11 +243,13 @@ struct breakablepropparams_t
const char *GetMassEquivalent(float flMass);
int GetAutoMultiplayerPhysicsMode( Vector size, float mass );
void BuildPropList( const char *pszBlockName, CUtlVector<breakmodel_t> &list, int modelindex, float defBurstScale, int defCollisionGroup );
void BreakModelList( CUtlVector<breakmodel_t> &list, int modelindex, float defBurstScale, int defCollisionGroup );
void PropBreakableCreateAll( int modelindex, IPhysicsObject *pPhysics, const breakablepropparams_t &params, CBaseEntity *pEntity, int iPrecomputedBreakableCount, bool bIgnoreGibLImit, bool defaultLocation = true );
void PropBreakableCreateAll( int modelindex, IPhysicsObject *pPhysics, const Vector &origin, const QAngle &angles, const Vector &velocity, const AngularImpulse &angularVelocity, float impactEnergyScale, float burstScale, int collisionGroup, CBaseEntity *pEntity = NULL, bool defaultLocation = true );
// Player gibs.
void PrecachePropsForModel( int iModel, const char *pszBlockName );
void PrecacheGibsForModel( int iModel );
void BuildGibList( CUtlVector<breakmodel_t> &list, int modelindex, float defBurstScale, int defCollisionGroup );
CBaseEntity *CreateGibsFromList( CUtlVector<breakmodel_t> &list, int modelindex, IPhysicsObject *pPhysics, const breakablepropparams_t &params, CBaseEntity *pEntity, int iPrecomputedBreakableCount, bool bIgnoreGibLImit, bool defaultLocation = true, CUtlVector<EHANDLE> *pGibList = NULL, bool bBurning = false );

View File

@ -368,7 +368,7 @@ bool CSceneImage::CreateSceneImageFile( CUtlBuffer &targetBuffer, char const *pc
if ( !bQuiet )
{
Msg( "Scenes: String Table: %d bytes\n", stringOffsets.Count() * sizeof( int ) );
Msg( "Scenes: String Table: %llu bytes\n", (uint64)(stringOffsets.Count() * sizeof( int )) );
Msg( "Scenes: String Pool: %d bytes\n", stringPool.TellMaxPut() );
}

View File

@ -140,7 +140,7 @@ typedef enum
VOTE_FAILED_ISSUE_DISABLED,
VOTE_FAILED_MAP_NOT_FOUND,
VOTE_FAILED_MAP_NAME_REQUIRED,
VOTE_FAILED_FAILED_RECENTLY,
VOTE_FAILED_ON_COOLDOWN,
VOTE_FAILED_TEAM_CANT_CALL,
VOTE_FAILED_WAITINGFORPLAYERS,
VOTE_FAILED_PLAYERNOTFOUND,

View File

@ -55,7 +55,8 @@ public:
void AddDamage( float flAddAmount );
void SubtractDamage( float flSubtractAmount );
float GetDamageBonus() const;
void SetDamageBonus( float flBonus );
CBaseEntity *GetDamageBonusProvider() const;
void SetDamageBonus( float flBonus, CBaseEntity *pProvider = NULL );
float GetBaseDamage() const;
bool BaseDamageIsValid() const;
@ -125,6 +126,7 @@ protected:
int m_iDamagedOtherPlayers;
int m_iPlayerPenetrationCount;
float m_flDamageBonus; // Anything that increases damage (crit) - store the delta
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
DECLARE_SIMPLE_DATADESC();
@ -247,9 +249,15 @@ inline float CTakeDamageInfo::GetDamageBonus() const
return m_flDamageBonus;
}
inline void CTakeDamageInfo::SetDamageBonus( float flBonus )
inline CBaseEntity *CTakeDamageInfo::GetDamageBonusProvider() const
{
return m_hDamageBonusProvider;
}
inline void CTakeDamageInfo::SetDamageBonus( float flBonus, CBaseEntity *pProvider /*= NULL*/ )
{
m_flDamageBonus = flBonus;
m_hDamageBonusProvider = pProvider;
}
inline float CTakeDamageInfo::GetBaseDamage() const

View File

@ -245,6 +245,7 @@ CTeamRoundTimer::CTeamRoundTimer( void )
m_bResetTimeOnRoundStart = false;
m_nTimeToUseAfterSetupFinished = 0;
m_flNextOvertimeNag = 0;
m_flLastTime = 0.f;
#endif
}
@ -781,6 +782,9 @@ void CTeamRoundTimer::SetTimerThink( int nType )
//-----------------------------------------------------------------------------
void CTeamRoundTimer::RoundTimerSetupThink( void )
{
float flLastTime = m_flLastTime;
m_flLastTime = GetTimeRemaining();
if ( TeamplayRoundBasedRules()->IsInPreMatch() == true && IsDisabled() == false )
{
inputdata_t data;
@ -797,6 +801,22 @@ void CTeamRoundTimer::RoundTimerSetupThink( void )
float flTime = GetTimeRemaining();
TeamplayRoundBasedRules()->SetOvertime( false );
if ( m_flLastTime > 0.f )
{
int nLastSecond = floor( flLastTime );
int nThisSecond = floor( flTime );
if ( nLastSecond != nThisSecond )
{
IGameEvent *event = gameeventmanager->CreateEvent( "teamplay_pre_round_time_left" );
if ( event )
{
event->SetInt( "time", nThisSecond );
gameeventmanager->FireEvent( event );
}
}
}
if ( flTime <= 0.0f && m_bFireFinished )
{
IGameEvent *event = gameeventmanager->CreateEvent( "teamplay_setup_finished" );
@ -1291,14 +1311,14 @@ void CTeamRoundTimer::InputAddTeamTime( inputdata_t &input )
// get the team
p = nexttoken( token, p, ' ' );
if ( token )
if ( token[0] )
{
nTeam = Q_atoi( token );
}
// get the time
p = nexttoken( token, p, ' ' );
if ( token )
if ( token[0] )
{
nSeconds = Q_atoi( token );
}

View File

@ -158,6 +158,7 @@ private:
COutputEvent m_OnSetupFinished;
float m_flNextOvertimeNag;
float m_flLastTime;
DECLARE_DATADESC();

View File

@ -90,6 +90,7 @@ BEGIN_NETWORK_TABLE_NOBASE( CTeamplayRoundBasedRules, DT_TeamplayRoundBasedRules
RecvPropBool( RECVINFO( m_bStopWatch ) ),
RecvPropBool( RECVINFO( m_bMultipleTrains ) ),
RecvPropArray3( RECVINFO_ARRAY(m_bPlayerReady), RecvPropBool( RECVINFO(m_bPlayerReady[0]) ) ),
RecvPropBool( RECVINFO( m_bCheatsEnabledDuringLevel ) ),
#else
SendPropInt( SENDINFO( m_iRoundState ), 5 ),
@ -107,6 +108,7 @@ BEGIN_NETWORK_TABLE_NOBASE( CTeamplayRoundBasedRules, DT_TeamplayRoundBasedRules
SendPropBool( SENDINFO( m_bStopWatch ) ),
SendPropBool( SENDINFO( m_bMultipleTrains ) ),
SendPropArray3( SENDINFO_ARRAY3(m_bPlayerReady), SendPropBool( SENDINFO_ARRAY(m_bPlayerReady) ) ),
SendPropBool( SENDINFO( m_bCheatsEnabledDuringLevel ) ),
#endif
END_NETWORK_TABLE()
@ -184,7 +186,7 @@ ConVar tf_arena_round_time( "tf_arena_round_time", "0", FCVAR_NOTIFY | FCVAR_REP
ConVar tf_arena_max_streak( "tf_arena_max_streak", "3", FCVAR_NOTIFY | FCVAR_REPLICATED, "Teams will be scrambled if one team reaches this streak" );
ConVar tf_arena_use_queue( "tf_arena_use_queue", "1", FCVAR_REPLICATED | FCVAR_NOTIFY, "Enables the spectator queue system for Arena." );
ConVar mp_teams_unbalance_limit( "mp_teams_unbalance_limit", "1", FCVAR_REPLICATED | FCVAR_NOTIFY,
ConVar mp_teams_unbalance_limit( "mp_teams_unbalance_limit", "1", FCVAR_REPLICATED,
"Teams are unbalanced when one team has this many more players than the other team. (0 disables check)",
true, 0, // min value
true, 30 // max value
@ -421,6 +423,7 @@ CTeamplayRoundBasedRules::CTeamplayRoundBasedRules( void )
m_nAutoBalanceQueuePlayerScore = -1;
SetDefLessFunc( m_GameTeams );
m_bCheatsEnabledDuringLevel = false;
#endif
}
@ -551,6 +554,18 @@ float CTeamplayRoundBasedRules::GetMinTimeWhenPlayerMaySpawn( CBasePlayer *pPlay
return pPlayer->GetDeathTime() + fMinDelay;
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CTeamplayRoundBasedRules::LevelInitPostEntity( void )
{
BaseClass::LevelInitPostEntity();
#ifdef GAME_DLL
m_bCheatsEnabledDuringLevel = sv_cheats && sv_cheats->GetBool();
#endif // GAME_DLL
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
@ -631,6 +646,12 @@ void CTeamplayRoundBasedRules::Think( void )
m_flNextPeriodicThink = gpGlobals->curtime + 1.0;
}
// Watch dog for cheats ever being enabled during a level
if ( !m_bCheatsEnabledDuringLevel && sv_cheats && sv_cheats->GetBool() )
{
m_bCheatsEnabledDuringLevel = true;
}
// Bypass teamplay think.
CGameRules::Think();
}
@ -954,7 +975,11 @@ 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
{
iDelayMax = 180;
}
@ -1415,6 +1440,12 @@ void CTeamplayRoundBasedRules::State_Enter_PREROUND( void )
State_Transition( GR_STATE_BETWEEN_RNDS );
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
{
@ -1501,14 +1532,23 @@ void CTeamplayRoundBasedRules::CheckReadyRestart( void )
m_flRestartRoundTime = -1;
#ifdef TF_DLL
if ( TFGameRules() && TFGameRules()->IsMannVsMachineMode() && g_pPopulationManager )
if ( TFGameRules() )
{
if ( TFObjectiveResource()->GetMannVsMachineIsBetweenWaves() )
if ( TFGameRules()->IsMannVsMachineMode() && g_pPopulationManager )
{
g_pPopulationManager->StartCurrentWave();
if ( TFObjectiveResource()->GetMannVsMachineIsBetweenWaves() )
{
g_pPopulationManager->StartCurrentWave();
return;
}
}
return;
#ifdef STAGING_ONLY
else if ( TFGameRules()->IsRatedTournamentMode() )
{
TFGameRules()->StartRatedTournamentMatch();
return;
}
#endif // STAGING_ONLY
}
#endif // TF_DLL
@ -1703,6 +1743,19 @@ void CTeamplayRoundBasedRules::State_Enter_TEAM_WIN( void )
InternalHandleTeamWin( m_iWinningTeam );
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
if ( CheckWinLimit() )
{
TFGameRules()->SkillRating_CalculateAdjustmentForTeams( m_iWinningTeam );
}
}
#endif // TF_DLL
#endif // STAGING_ONLY
}
//-----------------------------------------------------------------------------
@ -1710,8 +1763,16 @@ void CTeamplayRoundBasedRules::State_Enter_TEAM_WIN( void )
//-----------------------------------------------------------------------------
void CTeamplayRoundBasedRules::State_Think_TEAM_WIN( void )
{
if( gpGlobals->curtime > m_flStateTransitionTime )
if ( gpGlobals->curtime > m_flStateTransitionTime )
{
#ifdef TF_DLL
IGameEvent *event = gameeventmanager->CreateEvent( "scorestats_accumulated_update" );
if ( event )
{
gameeventmanager->FireEvent( event );
}
#endif // TF_DLL
bool bDone = !(!CheckTimeLimit() && !CheckWinLimit() && !CheckMaxRounds() && !CheckNextLevelCvar());
// check the win limit, max rounds, time limit and nextlevel cvar before starting the next round
@ -2632,6 +2693,10 @@ void CTeamplayRoundBasedRules::RoundRespawn( void )
}
#endif
// Free any edicts that were marked deleted. This should hopefully clear some out
// so the below function can use the now freed ones.
engine->AllowImmediateEdictReuse();
RespawnPlayers( true );
// reset per-round scores for each player
@ -3020,6 +3085,14 @@ void CTeamplayRoundBasedRules::ResetScores( void )
m_bResetPlayerScores = true;
m_bResetRoundsPlayed = true;
//m_flStopWatchTime = -1.0f;
#ifdef TF_DLL
IGameEvent *event = gameeventmanager->CreateEvent( "scorestats_accumulated_reset" );
if ( event )
{
gameeventmanager->FireEvent( event );
}
#endif // TF_DLL
}
//-----------------------------------------------------------------------------

View File

@ -88,6 +88,11 @@ enum {
WINREASON_TIMELIMIT,
WINREASON_WINLIMIT,
WINREASON_WINDIFFLIMIT,
#if defined(TF_CLIENT_DLL) || defined(TF_DLL)
WINREASON_RD_REACTOR_CAPTURED,
WINREASON_RD_CORES_COLLECTED,
WINREASON_RD_REACTOR_RETURNED,
#endif
};
enum stalemate_reasons_t
@ -183,6 +188,7 @@ public:
virtual float GetNextRespawnWave( int iTeam, CBasePlayer *pPlayer );
virtual bool HasPassedMinRespawnTime( CBasePlayer *pPlayer );
virtual void LevelInitPostEntity( void );
virtual float GetRespawnTimeScalar( int iTeam );
virtual float GetRespawnWaveMaxLength( int iTeam, bool bScaleWithNumPlayers = true );
virtual bool ShouldRespawnQuickly( CBasePlayer *pPlayer ) { return false; }
@ -541,6 +547,7 @@ private:
public:
bool WouldChangeUnbalanceTeams( int iNewTeam, int iCurrentTeam );
bool AreTeamsUnbalanced( int &iHeaviestTeam, int &iLightestTeam );
virtual bool HaveCheatsBeenEnabledDuringLevel( void ) { return m_bCheatsEnabledDuringLevel; }
protected:
CNetworkVar( gamerules_roundstate_t, m_iRoundState );
@ -557,10 +564,11 @@ protected:
CNetworkVar( float, m_flMapResetTime ); // Time that the map was reset
CNetworkArray( float, m_flNextRespawnWave, MAX_TEAMS ); // Minor waste, but cleaner code
CNetworkArray( bool, m_bTeamReady, MAX_TEAMS );
CNetworkVar( bool, m_bStopWatch );
CNetworkVar( bool, m_bMultipleTrains ); // two trains in this map?
CNetworkVar( bool, m_bStopWatch );
CNetworkVar( bool, m_bMultipleTrains ); // two trains in this map?
CNetworkArray( bool, m_bPlayerReady, MAX_PLAYERS );
CNetworkVar( bool, m_bCheatsEnabledDuringLevel );
public:
CNetworkArray( float, m_TeamRespawnWaveTimes, MAX_TEAMS ); // Time between each team's respawn wave

View File

@ -48,6 +48,7 @@ CVoiceGameMgr g_VoiceGameMgr;
// ------------------------------------------------------------------------ //
// Find a player with a case-insensitive name search.
#if 0
static CBasePlayer* FindPlayerByName(const char *pTestName)
{
for(int i=1; i <= gpGlobals->maxClients; i++)
@ -69,6 +70,7 @@ static CBasePlayer* FindPlayerByName(const char *pTestName)
return NULL;
}
#endif
static void VoiceServerDebug( const char *pFmt, ... )
{