Updated the SDK with the latest code from the TF and HL2 branches.
This commit is contained in:
@@ -18,6 +18,7 @@
|
||||
abstract_class IResponseFilter
|
||||
{
|
||||
public:
|
||||
virtual ~IResponseFilter(){}
|
||||
virtual bool IsValidResponse( ResponseType_t type, const char *pszValue ) = 0;
|
||||
};
|
||||
|
||||
|
||||
@@ -925,6 +925,25 @@ void CBaseAnimatingOverlay::SetLayerCycle( int iLayer, float flCycle, float flPr
|
||||
m_AnimOverlay[iLayer].MarkActive( );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void CBaseAnimatingOverlay::SetLayerCycle( int iLayer, float flCycle, float flPrevCycle, float flLastEventCheck )
|
||||
{
|
||||
if (!IsValidLayer( iLayer ))
|
||||
return;
|
||||
|
||||
if (!m_AnimOverlay[iLayer].m_bLooping)
|
||||
{
|
||||
flCycle = clamp( flCycle, 0.0f, 1.0f );
|
||||
flPrevCycle = clamp( flPrevCycle, 0.0f, 1.0f );
|
||||
}
|
||||
m_AnimOverlay[iLayer].m_flCycle = flCycle;
|
||||
m_AnimOverlay[iLayer].m_flPrevCycle = flPrevCycle;
|
||||
m_AnimOverlay[iLayer].m_flLastEventCheck = flLastEventCheck;
|
||||
m_AnimOverlay[iLayer].MarkActive( );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
@@ -165,6 +165,7 @@ public:
|
||||
|
||||
void SetLayerCycle( int iLayer, float flCycle );
|
||||
void SetLayerCycle( int iLayer, float flCycle, float flPrevCycle );
|
||||
void SetLayerCycle( int iLayer, float flCycle, float flPrevCycle, float flLastEventCheck );
|
||||
float GetLayerCycle( int iLayer );
|
||||
|
||||
void SetLayerPlaybackRate( int iLayer, float flPlaybackRate );
|
||||
|
||||
@@ -839,7 +839,7 @@ void CC_CommentaryChanged( IConVar *pConVar, const char *pOldString, float flOld
|
||||
g_CommentarySystem.SetCommentaryMode( var.GetBool() );
|
||||
}
|
||||
}
|
||||
ConVar commentary("commentary", "0", FCVAR_ARCHIVE | FCVAR_ARCHIVE_XBOX, "Desired commentary mode state.", CC_CommentaryChanged );
|
||||
ConVar commentary( "commentary", "0", FCVAR_NONE, "Desired commentary mode state.", CC_CommentaryChanged );
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: We need to revert back any convar changes that are made by the
|
||||
|
||||
@@ -155,7 +155,7 @@ bool BasicGameStats_t::ParseFromBuffer( CUtlBuffer& buf, int iBufferStatsVersion
|
||||
for ( int i = 0; i < c; ++i )
|
||||
{
|
||||
char mapname[ 256 ];
|
||||
buf.GetString( mapname, sizeof( mapname ) );
|
||||
buf.GetString( mapname );
|
||||
|
||||
BasicGameStatsRecord_t *rec = FindOrAddRecordForMap( mapname );
|
||||
bool valid= rec->ParseFromBuffer( buf, iBufferStatsVersion );
|
||||
|
||||
@@ -1686,6 +1686,11 @@ void CAI_BaseNPC::InitDefaultActivitySR(void)
|
||||
ADD_ACTIVITY_TO_SR( ACT_MP_ATTACK_SWIM_GRENADE_ITEM2 );
|
||||
ADD_ACTIVITY_TO_SR( ACT_MP_ATTACK_AIRWALK_GRENADE_ITEM2 );
|
||||
|
||||
// Passtime
|
||||
ADD_ACTIVITY_TO_SR( ACT_MP_STAND_PASSTIME );
|
||||
ADD_ACTIVITY_TO_SR( ACT_MP_RUN_PASSTIME );
|
||||
ADD_ACTIVITY_TO_SR( ACT_MP_CROUCHWALK_PASSTIME );
|
||||
|
||||
// Flinches
|
||||
ADD_ACTIVITY_TO_SR( ACT_MP_GESTURE_FLINCH );
|
||||
ADD_ACTIVITY_TO_SR( ACT_MP_GESTURE_FLINCH_PRIMARY );
|
||||
@@ -1826,6 +1831,7 @@ void CAI_BaseNPC::InitDefaultActivitySR(void)
|
||||
ADD_ACTIVITY_TO_SR( ACT_MP_DOUBLEJUMP_CROUCH_ITEM1 );
|
||||
ADD_ACTIVITY_TO_SR( ACT_MP_DOUBLEJUMP_CROUCH_ITEM2 );
|
||||
ADD_ACTIVITY_TO_SR( ACT_MP_DOUBLEJUMP_CROUCH_LOSERSTATE );
|
||||
ADD_ACTIVITY_TO_SR( ACT_MP_DOUBLEJUMP_CROUCH_PASSTIME );
|
||||
|
||||
ADD_ACTIVITY_TO_SR( ACT_MP_GESTURE_VC_HANDMOUTH );
|
||||
ADD_ACTIVITY_TO_SR( ACT_MP_GESTURE_VC_FINGERPOINT );
|
||||
@@ -1887,6 +1893,11 @@ void CAI_BaseNPC::InitDefaultActivitySR(void)
|
||||
ADD_ACTIVITY_TO_SR( ACT_MP_STUN_MIDDLE );
|
||||
ADD_ACTIVITY_TO_SR( ACT_MP_STUN_END );
|
||||
|
||||
ADD_ACTIVITY_TO_SR( ACT_MP_PASSTIME_THROW_BEGIN );
|
||||
ADD_ACTIVITY_TO_SR( ACT_MP_PASSTIME_THROW_MIDDLE );
|
||||
ADD_ACTIVITY_TO_SR( ACT_MP_PASSTIME_THROW_END );
|
||||
ADD_ACTIVITY_TO_SR( ACT_MP_PASSTIME_THROW_CANCEL );
|
||||
|
||||
ADD_ACTIVITY_TO_SR( ACT_VM_UNUSABLE );
|
||||
ADD_ACTIVITY_TO_SR( ACT_VM_UNUSABLE_TO_USABLE );
|
||||
ADD_ACTIVITY_TO_SR( ACT_VM_USABLE_TO_UNUSABLE );
|
||||
@@ -2186,4 +2197,40 @@ void CAI_BaseNPC::InitDefaultActivitySR(void)
|
||||
ADD_ACTIVITY_TO_SR( ACT_BOT_GESTURE_FLINCH );
|
||||
ADD_ACTIVITY_TO_SR( ACT_BOT_PANIC_START );
|
||||
ADD_ACTIVITY_TO_SR( ACT_BOT_PANIC_END );
|
||||
|
||||
ADD_ACTIVITY_TO_SR( ACT_ENGINEER_REVOLVER_DRAW );
|
||||
ADD_ACTIVITY_TO_SR( ACT_ENGINEER_REVOLVER_IDLE );
|
||||
ADD_ACTIVITY_TO_SR( ACT_ENGINEER_REVOLVER_PRIMARYATTACK );
|
||||
ADD_ACTIVITY_TO_SR( ACT_ENGINEER_REVOLVER_RELOAD );
|
||||
|
||||
ADD_ACTIVITY_TO_SR( ACT_KART_IDLE );
|
||||
ADD_ACTIVITY_TO_SR( ACT_KART_ACTION_SHOOT );
|
||||
ADD_ACTIVITY_TO_SR( ACT_KART_ACTION_DASH );
|
||||
ADD_ACTIVITY_TO_SR( ACT_KART_JUMP_START );
|
||||
ADD_ACTIVITY_TO_SR( ACT_KART_JUMP_FLOAT );
|
||||
ADD_ACTIVITY_TO_SR( ACT_KART_JUMP_LAND );
|
||||
ADD_ACTIVITY_TO_SR( ACT_KART_IMPACT );
|
||||
ADD_ACTIVITY_TO_SR( ACT_KART_IMPACT_BIG );
|
||||
ADD_ACTIVITY_TO_SR( ACT_KART_GESTURE_POSITIVE );
|
||||
ADD_ACTIVITY_TO_SR( ACT_KART_GESTURE_NEGATIVE );
|
||||
|
||||
ADD_ACTIVITY_TO_SR( ACT_GRAPPLE_DRAW );
|
||||
ADD_ACTIVITY_TO_SR( ACT_GRAPPLE_IDLE );
|
||||
ADD_ACTIVITY_TO_SR( ACT_GRAPPLE_FIRE_START );
|
||||
ADD_ACTIVITY_TO_SR( ACT_GRAPPLE_FIRE_IDLE );
|
||||
ADD_ACTIVITY_TO_SR( ACT_GRAPPLE_PULL_START );
|
||||
ADD_ACTIVITY_TO_SR( ACT_GRAPPLE_PULL_IDLE );
|
||||
ADD_ACTIVITY_TO_SR( ACT_GRAPPLE_PULL_END );
|
||||
|
||||
ADD_ACTIVITY_TO_SR( ACT_PRIMARY_VM_INSPECT_START );
|
||||
ADD_ACTIVITY_TO_SR( ACT_PRIMARY_VM_INSPECT_IDLE );
|
||||
ADD_ACTIVITY_TO_SR( ACT_PRIMARY_VM_INSPECT_END );
|
||||
|
||||
ADD_ACTIVITY_TO_SR( ACT_SECONDARY_VM_INSPECT_START );
|
||||
ADD_ACTIVITY_TO_SR( ACT_SECONDARY_VM_INSPECT_IDLE );
|
||||
ADD_ACTIVITY_TO_SR( ACT_SECONDARY_VM_INSPECT_END );
|
||||
|
||||
ADD_ACTIVITY_TO_SR( ACT_MELEE_VM_INSPECT_START );
|
||||
ADD_ACTIVITY_TO_SR( ACT_MELEE_VM_INSPECT_IDLE );
|
||||
ADD_ACTIVITY_TO_SR( ACT_MELEE_VM_INSPECT_END );
|
||||
}
|
||||
|
||||
@@ -470,7 +470,6 @@ void CBaseAnimating::StudioFrameAdvanceManual( float flInterval )
|
||||
if ( !pStudioHdr )
|
||||
return;
|
||||
|
||||
UpdateModelScale();
|
||||
m_flAnimTime = gpGlobals->curtime;
|
||||
m_flPrevAnimTime = m_flAnimTime - flInterval;
|
||||
float flCycleRate = GetSequenceCycleRate( pStudioHdr, GetSequence() ) * m_flPlaybackRate;
|
||||
@@ -490,8 +489,6 @@ void CBaseAnimating::StudioFrameAdvance()
|
||||
return;
|
||||
}
|
||||
|
||||
UpdateModelScale();
|
||||
|
||||
if ( !m_flPrevAnimTime )
|
||||
{
|
||||
m_flPrevAnimTime = m_flAnimTime;
|
||||
@@ -631,7 +628,7 @@ void CBaseAnimating::InputSetModelScale( inputdata_t &inputdata )
|
||||
int CBaseAnimating::SelectWeightedSequence ( Activity activity )
|
||||
{
|
||||
Assert( activity != ACT_INVALID );
|
||||
Assert( GetModelPtr() );
|
||||
AssertMsg( GetModelPtr(), "GetModelPtr NULL. %s", STRING(GetEntityName()) ? STRING(GetEntityName()) : "" );
|
||||
return ::SelectWeightedSequence( GetModelPtr(), activity, GetSequence() );
|
||||
}
|
||||
|
||||
@@ -639,16 +636,23 @@ int CBaseAnimating::SelectWeightedSequence ( Activity activity )
|
||||
int CBaseAnimating::SelectWeightedSequence ( Activity activity, int curSequence )
|
||||
{
|
||||
Assert( activity != ACT_INVALID );
|
||||
Assert( GetModelPtr() );
|
||||
AssertMsg( GetModelPtr(), "GetModelPtr NULL. %s", STRING(GetEntityName()) ? STRING(GetEntityName()) : "" );
|
||||
return ::SelectWeightedSequence( GetModelPtr(), activity, curSequence );
|
||||
}
|
||||
|
||||
int CBaseAnimating::SelectWeightedSequenceFromModifiers( Activity activity, CUtlSymbol *pActivityModifiers, int iModifierCount )
|
||||
{
|
||||
Assert( activity != ACT_INVALID );
|
||||
AssertMsg( GetModelPtr(), "GetModelPtr NULL. %s", STRING(GetEntityName()) ? STRING(GetEntityName()) : "" );
|
||||
return GetModelPtr()->SelectWeightedSequenceFromModifiers( activity, pActivityModifiers, iModifierCount );
|
||||
}
|
||||
|
||||
//=========================================================
|
||||
// ResetActivityIndexes
|
||||
//=========================================================
|
||||
void CBaseAnimating::ResetActivityIndexes ( void )
|
||||
{
|
||||
Assert( GetModelPtr() );
|
||||
AssertMsg( GetModelPtr(), "GetModelPtr NULL. %s", STRING(GetEntityName()) ? STRING(GetEntityName()) : "" );
|
||||
::ResetActivityIndexes( GetModelPtr() );
|
||||
}
|
||||
|
||||
@@ -657,7 +661,7 @@ void CBaseAnimating::ResetActivityIndexes ( void )
|
||||
//=========================================================
|
||||
void CBaseAnimating::ResetEventIndexes ( void )
|
||||
{
|
||||
Assert( GetModelPtr() );
|
||||
AssertMsg( GetModelPtr(), "GetModelPtr NULL. %s", STRING(GetEntityName()) ? STRING(GetEntityName()) : "" );
|
||||
::ResetEventIndexes( GetModelPtr() );
|
||||
}
|
||||
|
||||
@@ -669,7 +673,7 @@ void CBaseAnimating::ResetEventIndexes ( void )
|
||||
//=========================================================
|
||||
int CBaseAnimating::SelectHeaviestSequence ( Activity activity )
|
||||
{
|
||||
Assert( GetModelPtr() );
|
||||
AssertMsg( GetModelPtr(), "GetModelPtr NULL. %s", STRING(GetEntityName()) ? STRING(GetEntityName()) : "" );
|
||||
return ::SelectHeaviestSequence( GetModelPtr(), activity );
|
||||
}
|
||||
|
||||
@@ -681,7 +685,7 @@ int CBaseAnimating::SelectHeaviestSequence ( Activity activity )
|
||||
//-----------------------------------------------------------------------------
|
||||
int CBaseAnimating::LookupActivity( const char *label )
|
||||
{
|
||||
Assert( GetModelPtr() );
|
||||
AssertMsg( GetModelPtr(), "GetModelPtr NULL. %s", STRING(GetEntityName()) ? STRING(GetEntityName()) : "" );
|
||||
return ::LookupActivity( GetModelPtr(), label );
|
||||
}
|
||||
|
||||
@@ -689,7 +693,7 @@ int CBaseAnimating::LookupActivity( const char *label )
|
||||
//=========================================================
|
||||
int CBaseAnimating::LookupSequence( const char *label )
|
||||
{
|
||||
Assert( GetModelPtr() );
|
||||
AssertMsg( GetModelPtr(), "GetModelPtr NULL. %s", STRING(GetEntityName()) ? STRING(GetEntityName()) : "" );
|
||||
return ::LookupSequence( GetModelPtr(), label );
|
||||
}
|
||||
|
||||
@@ -729,7 +733,7 @@ float CBaseAnimating::GetSequenceMoveYaw( int iSequence )
|
||||
{
|
||||
Vector vecReturn;
|
||||
|
||||
Assert( GetModelPtr() );
|
||||
AssertMsg( GetModelPtr(), "GetModelPtr NULL. %s", STRING(GetEntityName()) ? STRING(GetEntityName()) : "" );
|
||||
::GetSequenceLinearMotion( GetModelPtr(), iSequence, GetPoseParameterArray(), &vecReturn );
|
||||
|
||||
if (vecReturn.Length() > 0)
|
||||
@@ -765,7 +769,7 @@ float CBaseAnimating::GetSequenceMoveDist( CStudioHdr *pStudioHdr, int iSequence
|
||||
//-----------------------------------------------------------------------------
|
||||
void CBaseAnimating::GetSequenceLinearMotion( int iSequence, Vector *pVec )
|
||||
{
|
||||
Assert( GetModelPtr() );
|
||||
AssertMsg( GetModelPtr(), "GetModelPtr NULL. %s", STRING(GetEntityName()) ? STRING(GetEntityName()) : "" );
|
||||
::GetSequenceLinearMotion( GetModelPtr(), iSequence, GetPoseParameterArray(), pVec );
|
||||
}
|
||||
|
||||
@@ -912,7 +916,7 @@ void CBaseAnimating::ResetSequenceInfo ( )
|
||||
//=========================================================
|
||||
bool CBaseAnimating::IsValidSequence( int iSequence )
|
||||
{
|
||||
Assert( GetModelPtr() );
|
||||
AssertMsg( GetModelPtr(), "GetModelPtr NULL. %s", STRING(GetEntityName()) ? STRING(GetEntityName()) : "" );
|
||||
CStudioHdr* pstudiohdr = GetModelPtr( );
|
||||
if (iSequence < 0 || iSequence >= pstudiohdr->GetNumSeq())
|
||||
{
|
||||
@@ -1779,7 +1783,7 @@ void CBaseAnimating::SetupBones( matrix3x4_t *pBoneToWorld, int boneMask )
|
||||
|
||||
MDLCACHE_CRITICAL_SECTION();
|
||||
|
||||
Assert( GetModelPtr() );
|
||||
AssertMsg( GetModelPtr(), "GetModelPtr NULL. %s", STRING(GetEntityName()) ? STRING(GetEntityName()) : "" );
|
||||
|
||||
CStudioHdr *pStudioHdr = GetModelPtr( );
|
||||
|
||||
@@ -2087,7 +2091,7 @@ void CBaseAnimating::GetEyeballs( Vector &origin, QAngle &angles )
|
||||
//=========================================================
|
||||
int CBaseAnimating::FindTransitionSequence( int iCurrentSequence, int iGoalSequence, int *piDir )
|
||||
{
|
||||
Assert( GetModelPtr() );
|
||||
AssertMsg( GetModelPtr(), "GetModelPtr NULL. %s", STRING(GetEntityName()) ? STRING(GetEntityName()) : "" );
|
||||
|
||||
if (piDir == NULL)
|
||||
{
|
||||
@@ -2136,7 +2140,7 @@ void CBaseAnimating::SetBodygroup( int iGroup, int iValue )
|
||||
{
|
||||
// SetBodygroup is not supported on pending dynamic models. Wait for it to load!
|
||||
// XXX TODO we could buffer up the group and value if we really needed to. -henryg
|
||||
Assert( GetModelPtr() );
|
||||
AssertMsg( GetModelPtr(), "GetModelPtr NULL. %s", STRING(GetEntityName()) ? STRING(GetEntityName()) : "" );
|
||||
int newBody = m_nBody;
|
||||
::SetBodygroup( GetModelPtr( ), newBody, iGroup, iValue );
|
||||
m_nBody = newBody;
|
||||
@@ -2735,7 +2739,7 @@ void CBaseAnimating::InitBoneControllers ( void ) // FIXME: rename
|
||||
//=========================================================
|
||||
float CBaseAnimating::SetBoneController ( int iController, float flValue )
|
||||
{
|
||||
Assert( GetModelPtr() );
|
||||
AssertMsg( GetModelPtr(), "GetModelPtr NULL. %s", STRING(GetEntityName()) ? STRING(GetEntityName()) : "" );
|
||||
|
||||
CStudioHdr *pmodel = (CStudioHdr*)GetModelPtr();
|
||||
|
||||
@@ -2752,7 +2756,7 @@ float CBaseAnimating::SetBoneController ( int iController, float flValue )
|
||||
//=========================================================
|
||||
float CBaseAnimating::GetBoneController ( int iController )
|
||||
{
|
||||
Assert( GetModelPtr() );
|
||||
AssertMsg( GetModelPtr(), "GetModelPtr NULL. %s", STRING(GetEntityName()) ? STRING(GetEntityName()) : "" );
|
||||
|
||||
CStudioHdr *pmodel = (CStudioHdr*)GetModelPtr();
|
||||
|
||||
@@ -2943,7 +2947,7 @@ void CBaseAnimating::SetHitboxSet( int setnum )
|
||||
//-----------------------------------------------------------------------------
|
||||
void CBaseAnimating::SetHitboxSetByName( const char *setname )
|
||||
{
|
||||
Assert( GetModelPtr() );
|
||||
AssertMsg( GetModelPtr(), "GetModelPtr NULL. %s", STRING(GetEntityName()) ? STRING(GetEntityName()) : "" );
|
||||
m_nHitboxSet = FindHitboxSetByName( GetModelPtr(), setname );
|
||||
}
|
||||
|
||||
@@ -2962,7 +2966,7 @@ int CBaseAnimating::GetHitboxSet( void )
|
||||
//-----------------------------------------------------------------------------
|
||||
const char *CBaseAnimating::GetHitboxSetName( void )
|
||||
{
|
||||
Assert( GetModelPtr() );
|
||||
AssertMsg( GetModelPtr(), "GetModelPtr NULL. %s", STRING(GetEntityName()) ? STRING(GetEntityName()) : "" );
|
||||
return ::GetHitboxSetName( GetModelPtr(), m_nHitboxSet );
|
||||
}
|
||||
|
||||
@@ -2972,7 +2976,7 @@ const char *CBaseAnimating::GetHitboxSetName( void )
|
||||
//-----------------------------------------------------------------------------
|
||||
int CBaseAnimating::GetHitboxSetCount( void )
|
||||
{
|
||||
Assert( GetModelPtr() );
|
||||
AssertMsg( GetModelPtr(), "GetModelPtr NULL. %s", STRING(GetEntityName()) ? STRING(GetEntityName()) : "" );
|
||||
return ::GetHitboxSetCount( GetModelPtr() );
|
||||
}
|
||||
|
||||
@@ -3303,6 +3307,7 @@ void CBaseAnimating::SetModelScale( float scale, float change_duration /*= 0.0f*
|
||||
mvs->m_flModelScaleGoal = scale;
|
||||
mvs->m_flModelScaleStartTime = gpGlobals->curtime;
|
||||
mvs->m_flModelScaleFinishTime = mvs->m_flModelScaleStartTime + change_duration;
|
||||
SetContextThink( &CBaseAnimating::UpdateModelScale, gpGlobals->curtime, "UpdateModelScaleThink" );
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -3341,6 +3346,11 @@ void CBaseAnimating::UpdateModelScale()
|
||||
}
|
||||
|
||||
RefreshCollisionBounds();
|
||||
|
||||
if ( frac < 1.f )
|
||||
{
|
||||
SetContextThink( &CBaseAnimating::UpdateModelScale, gpGlobals->curtime, "UpdateModelScaleThink" );
|
||||
}
|
||||
}
|
||||
|
||||
void CBaseAnimating::RefreshCollisionBounds( void )
|
||||
|
||||
@@ -108,6 +108,7 @@ public:
|
||||
void ResetEventIndexes ( void );
|
||||
int SelectWeightedSequence ( Activity activity );
|
||||
int SelectWeightedSequence ( Activity activity, int curSequence );
|
||||
int SelectWeightedSequenceFromModifiers( Activity activity, CUtlSymbol *pActivityModifiers, int iModifierCount );
|
||||
int SelectHeaviestSequence ( Activity activity );
|
||||
int LookupActivity( const char *label );
|
||||
int LookupSequence ( const char *label );
|
||||
@@ -436,10 +437,14 @@ inline CStudioHdr *CBaseAnimating::GetModelPtr( void )
|
||||
return NULL;
|
||||
|
||||
#ifdef _DEBUG
|
||||
// GetModelPtr() is often called before OnNewModel() so go ahead and set it up first chance.
|
||||
static IDataCacheSection *pModelCache = datacache->FindSection( "ModelData" );
|
||||
AssertOnce( pModelCache->IsFrameLocking() );
|
||||
if ( !HushAsserts() )
|
||||
{
|
||||
// GetModelPtr() is often called before OnNewModel() so go ahead and set it up first chance.
|
||||
static IDataCacheSection *pModelCache = datacache->FindSection( "ModelData" );
|
||||
AssertOnce( pModelCache->IsFrameLocking() );
|
||||
}
|
||||
#endif
|
||||
|
||||
if ( !m_pStudioHdr && GetModel() )
|
||||
{
|
||||
LockStudioHdr();
|
||||
|
||||
@@ -2280,8 +2280,8 @@ CBaseCombatWeapon *CBaseCombatCharacter::Weapon_GetWpnForAmmo( int iAmmoIndex )
|
||||
//-----------------------------------------------------------------------------
|
||||
bool CBaseCombatCharacter::Weapon_CanUse( CBaseCombatWeapon *pWeapon )
|
||||
{
|
||||
acttable_t *pTable = pWeapon->ActivityList();
|
||||
int actCount = pWeapon->ActivityListCount();
|
||||
int actCount = 0;
|
||||
acttable_t *pTable = pWeapon->ActivityList( actCount );
|
||||
|
||||
if( actCount < 1 )
|
||||
{
|
||||
|
||||
@@ -86,6 +86,7 @@ bool CBaseEntity::sm_bDisableTouchFuncs = false; // Disables PhysicsTouch and Ph
|
||||
bool CBaseEntity::sm_bAccurateTriggerBboxChecks = true; // set to false for legacy behavior in ep1
|
||||
|
||||
int CBaseEntity::m_nPredictionRandomSeed = -1;
|
||||
int CBaseEntity::m_nPredictionRandomSeedServer = -1;
|
||||
CBasePlayer *CBaseEntity::m_pPredictionPlayer = NULL;
|
||||
|
||||
// Used to make sure nobody calls UpdateTransmitState directly.
|
||||
@@ -1440,10 +1441,10 @@ int CBaseEntity::OnTakeDamage( const CTakeDamageInfo &info )
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Scale damage done and call OnTakeDamage
|
||||
//-----------------------------------------------------------------------------
|
||||
void CBaseEntity::TakeDamage( const CTakeDamageInfo &inputInfo )
|
||||
int CBaseEntity::TakeDamage( const CTakeDamageInfo &inputInfo )
|
||||
{
|
||||
if ( !g_pGameRules )
|
||||
return;
|
||||
return 0;
|
||||
|
||||
bool bHasPhysicsForceDamage = !g_pGameRules->Damage_NoPhysicsForce( inputInfo.GetDamageType() );
|
||||
if ( bHasPhysicsForceDamage && inputInfo.GetDamageType() != DMG_GENERIC )
|
||||
@@ -1475,12 +1476,12 @@ void CBaseEntity::TakeDamage( const CTakeDamageInfo &inputInfo )
|
||||
// Make sure our damage filter allows the damage.
|
||||
if ( !PassesDamageFilter( inputInfo ))
|
||||
{
|
||||
return;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if( !g_pGameRules->AllowDamage(this, inputInfo) )
|
||||
{
|
||||
return;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if ( PhysIsInCallback() )
|
||||
@@ -1502,8 +1503,9 @@ void CBaseEntity::TakeDamage( const CTakeDamageInfo &inputInfo )
|
||||
|
||||
//Msg("%s took %.2f Damage, at %.2f\n", GetClassname(), info.GetDamage(), gpGlobals->curtime );
|
||||
|
||||
OnTakeDamage( info );
|
||||
return OnTakeDamage( info );
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
@@ -6089,7 +6091,7 @@ void CBaseEntity::SetLocalAngles( const QAngle& angles )
|
||||
{
|
||||
Warning( "Bad SetLocalAngles(%f,%f,%f) on %s\n", angles.x, angles.y, angles.z, GetDebugName() );
|
||||
}
|
||||
Assert( false );
|
||||
AssertMsg( false, "Bad SetLocalAngles(%f,%f,%f) on %s\n", angles.x, angles.y, angles.z, GetDebugName() );
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -904,7 +904,7 @@ public:
|
||||
virtual int OnTakeDamage( const CTakeDamageInfo &info );
|
||||
|
||||
// This is what you should call to apply damage to an entity.
|
||||
void TakeDamage( const CTakeDamageInfo &info );
|
||||
int TakeDamage( const CTakeDamageInfo &info );
|
||||
virtual void AdjustDamageDirection( const CTakeDamageInfo &info, Vector &dir, CBaseEntity *pEnt ) {}
|
||||
|
||||
virtual int TakeHealth( float flHealth, int bitsDamageType );
|
||||
@@ -1748,6 +1748,7 @@ private:
|
||||
// randon number generators to spit out the same random numbers on both sides for a particular
|
||||
// usercmd input.
|
||||
static int m_nPredictionRandomSeed;
|
||||
static int m_nPredictionRandomSeedServer;
|
||||
static CBasePlayer *m_pPredictionPlayer;
|
||||
|
||||
// FIXME: Make hierarchy a member of CBaseEntity
|
||||
@@ -1761,7 +1762,7 @@ private:
|
||||
|
||||
public:
|
||||
// Accessors for above
|
||||
static int GetPredictionRandomSeed( void );
|
||||
static int GetPredictionRandomSeed( bool bUseUnSyncedServerPlatTime = false );
|
||||
static void SetPredictionRandomSeed( const CUserCmd *cmd );
|
||||
static CBasePlayer *GetPredictionPlayer( void );
|
||||
static void SetPredictionPlayer( CBasePlayer *player );
|
||||
@@ -1799,6 +1800,8 @@ public:
|
||||
{
|
||||
return s_bAbsQueriesValid;
|
||||
}
|
||||
|
||||
virtual bool ShouldBlockNav() const { return true; }
|
||||
};
|
||||
|
||||
// Send tables exposed in this module.
|
||||
|
||||
@@ -113,7 +113,7 @@ CBaseFlex::CBaseFlex( void ) :
|
||||
CBaseFlex::~CBaseFlex( void )
|
||||
{
|
||||
m_LocalToGlobal.RemoveAll();
|
||||
Assert( m_SceneEvents.Count() == 0 );
|
||||
AssertMsg( m_SceneEvents.Count() == 0, "m_ScenesEvent.Count != 0: %d", m_SceneEvents.Count() );
|
||||
}
|
||||
|
||||
void CBaseFlex::SetModel( const char *szModelName )
|
||||
@@ -508,7 +508,7 @@ bool CBaseFlex::HandleStartSequenceSceneEvent( CSceneEventInfo *info, CChoreoSce
|
||||
float seq_duration = SequenceDuration( info->m_nSequence );
|
||||
float flCycle = dt / seq_duration;
|
||||
flCycle = flCycle - (int)flCycle; // loop
|
||||
SetLayerCycle( info->m_iLayer, flCycle, flCycle );
|
||||
SetLayerCycle( info->m_iLayer, flCycle, flCycle, 0.f );
|
||||
|
||||
SetLayerPlaybackRate( info->m_iLayer, 0.0 );
|
||||
}
|
||||
|
||||
@@ -57,6 +57,60 @@ extern bool IsInCommentaryMode( void );
|
||||
|
||||
ConVar *sv_cheats = NULL;
|
||||
|
||||
enum eAllowPointServerCommand {
|
||||
eAllowNever,
|
||||
eAllowOfficial,
|
||||
eAllowAlways
|
||||
};
|
||||
|
||||
#ifdef TF_DLL
|
||||
// The default value here should match the default of the convar
|
||||
eAllowPointServerCommand sAllowPointServerCommand = eAllowOfficial;
|
||||
#else
|
||||
eAllowPointServerCommand sAllowPointServerCommand = eAllowAlways;
|
||||
#endif // TF_DLL
|
||||
|
||||
void sv_allow_point_servercommand_changed( IConVar *pConVar, const char *pOldString, float flOldValue )
|
||||
{
|
||||
ConVarRef var( pConVar );
|
||||
if ( !var.IsValid() )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
const char *pNewValue = var.GetString();
|
||||
if ( V_strcasecmp ( pNewValue, "always" ) == 0 )
|
||||
{
|
||||
sAllowPointServerCommand = eAllowAlways;
|
||||
}
|
||||
#ifdef TF_DLL
|
||||
else if ( V_strcasecmp ( pNewValue, "official" ) == 0 )
|
||||
{
|
||||
sAllowPointServerCommand = eAllowOfficial;
|
||||
}
|
||||
#endif // TF_DLL
|
||||
else
|
||||
{
|
||||
sAllowPointServerCommand = eAllowNever;
|
||||
}
|
||||
}
|
||||
|
||||
ConVar sv_allow_point_servercommand ( "sv_allow_point_servercommand",
|
||||
#ifdef TF_DLL
|
||||
// The default value here should match the default of the convar
|
||||
"official",
|
||||
#else
|
||||
// Other games may use this in their official maps, and only TF exposes IsValveMap() currently
|
||||
"always",
|
||||
#endif // TF_DLL
|
||||
FCVAR_NONE,
|
||||
"Allow use of point_servercommand entities in map. Potentially dangerous for untrusted maps.\n"
|
||||
" disallow : Always disallow\n"
|
||||
#ifdef TF_DLL
|
||||
" official : Allowed for valve maps only\n"
|
||||
#endif // TF_DLL
|
||||
" always : Allow for all maps", sv_allow_point_servercommand_changed );
|
||||
|
||||
void ClientKill( edict_t *pEdict, const Vector &vecForce, bool bExplode = false )
|
||||
{
|
||||
CBasePlayer *pPlayer = static_cast<CBasePlayer*>( GetContainingEntity( pEdict ) );
|
||||
@@ -569,7 +623,22 @@ void CPointServerCommand::InputCommand( inputdata_t& inputdata )
|
||||
if ( !inputdata.value.String()[0] )
|
||||
return;
|
||||
|
||||
engine->ServerCommand( UTIL_VarArgs( "%s\n", inputdata.value.String() ) );
|
||||
bool bAllowed = ( sAllowPointServerCommand == eAllowAlways );
|
||||
#ifdef TF_DLL
|
||||
if ( sAllowPointServerCommand == eAllowOfficial )
|
||||
{
|
||||
bAllowed = TFGameRules() && TFGameRules()->IsValveMap();
|
||||
}
|
||||
#endif // TF_DLL
|
||||
|
||||
if ( bAllowed )
|
||||
{
|
||||
engine->ServerCommand( UTIL_VarArgs( "%s\n", inputdata.value.String() ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
Warning( "point_servercommand usage blocked by sv_allow_point_servercommand setting\n" );
|
||||
}
|
||||
}
|
||||
|
||||
BEGIN_DATADESC( CPointServerCommand )
|
||||
@@ -600,7 +669,7 @@ void CC_DrawLine( const CCommand &args )
|
||||
static ConCommand drawline("drawline", CC_DrawLine, "Draws line between two 3D Points.\n\tGreen if no collision\n\tRed is collides with something\n\tArguments: x1 y1 z1 x2 y2 z2", FCVAR_CHEAT);
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Purpose : Draw a cross at a points.
|
||||
// Purpose : Draw a cross at a points.
|
||||
// Input :
|
||||
// Output :
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
@@ -150,6 +150,8 @@ public:
|
||||
bool ShouldLoopMoveSound( void ) { return m_bLoopMoveSound; }
|
||||
bool m_bLoopMoveSound; // Move sound loops until stopped
|
||||
|
||||
virtual bool ShouldBlockNav() const OVERRIDE { return false; }
|
||||
|
||||
private:
|
||||
void ChainUse( void ); ///< Chains +use on through to m_ChainTarget
|
||||
void ChainTouch( CBaseEntity *pOther ); ///< Chains touch on through to m_ChainTarget
|
||||
|
||||
@@ -215,7 +215,7 @@ public:
|
||||
{
|
||||
Ep2LevelStats_t::EntityDeathsLump_t data;
|
||||
char npcName[ 512 ];
|
||||
LoadBuffer.GetString( npcName, sizeof( npcName ) );
|
||||
LoadBuffer.GetString( npcName );
|
||||
LoadBuffer.Get( &data, sizeof( data ) );
|
||||
pItem->m_dictEntityDeaths.Insert( npcName, data );
|
||||
}
|
||||
@@ -229,7 +229,7 @@ public:
|
||||
{
|
||||
Ep2LevelStats_t::WeaponLump_t data;
|
||||
char weaponName[ 512 ];
|
||||
LoadBuffer.GetString( weaponName, sizeof( weaponName ) );
|
||||
LoadBuffer.GetString( weaponName );
|
||||
LoadBuffer.Get( &data, sizeof( data ) );
|
||||
pItem->m_dictWeapons.Insert( weaponName, data );
|
||||
}
|
||||
@@ -240,7 +240,7 @@ public:
|
||||
Assert( pItem );
|
||||
Ep2LevelStats_t::SaveGameInfo_t *info = &pItem->m_SaveGameInfo;
|
||||
char sz[ 512 ];
|
||||
LoadBuffer.GetString( sz, sizeof( sz ) );
|
||||
LoadBuffer.GetString( sz );
|
||||
info->m_sCurrentSaveFile = sz;
|
||||
info->m_nCurrentSaveFileTime = LoadBuffer.GetInt();
|
||||
int c = LoadBuffer.GetInt();
|
||||
@@ -277,7 +277,7 @@ public:
|
||||
{
|
||||
Ep2LevelStats_t::GenericStatsLump_t data;
|
||||
char pchStatName[ 512 ];
|
||||
LoadBuffer.GetString( pchStatName, sizeof( pchStatName ) );
|
||||
LoadBuffer.GetString( pchStatName );
|
||||
LoadBuffer.Get( &data, sizeof( data ) );
|
||||
pItem->m_dictGeneric.Insert( pchStatName, data );
|
||||
}
|
||||
|
||||
@@ -817,8 +817,6 @@ void CBreakable::VPhysicsCollision( int index, gamevcollisionevent_t *pEvent )
|
||||
//-----------------------------------------------------------------------------
|
||||
int CBreakable::OnTakeDamage( const CTakeDamageInfo &info )
|
||||
{
|
||||
Vector vecTemp;
|
||||
|
||||
CTakeDamageInfo subInfo = info;
|
||||
|
||||
// If attacker can't do at least the min required damage to us, don't take any damage from them
|
||||
@@ -832,8 +830,6 @@ int CBreakable::OnTakeDamage( const CTakeDamageInfo &info )
|
||||
return 1;
|
||||
}
|
||||
|
||||
vecTemp = subInfo.GetInflictor()->GetAbsOrigin() - WorldSpaceCenter();
|
||||
|
||||
if (!IsBreakable())
|
||||
return 0;
|
||||
|
||||
|
||||
@@ -99,6 +99,7 @@
|
||||
#include "tf_gamerules.h"
|
||||
#include "tf_lobby.h"
|
||||
#include "player_vs_environment/tf_population_manager.h"
|
||||
#include "workshop/maps_workshop.h"
|
||||
|
||||
extern ConVar tf_mm_trusted;
|
||||
extern ConVar tf_mm_servermode;
|
||||
@@ -559,11 +560,11 @@ void DrawAllDebugOverlays( void )
|
||||
|
||||
CServerGameDLL g_ServerGameDLL;
|
||||
// INTERFACEVERSION_SERVERGAMEDLL_VERSION_8 is compatible with the latest since we're only adding things to the end, so expose that as well.
|
||||
EXPOSE_SINGLE_INTERFACE_GLOBALVAR(CServerGameDLL, IServerGameDLL008, INTERFACEVERSION_SERVERGAMEDLL_VERSION_8, g_ServerGameDLL );
|
||||
//EXPOSE_SINGLE_INTERFACE_GLOBALVAR(CServerGameDLL, IServerGameDLL008, INTERFACEVERSION_SERVERGAMEDLL_VERSION_8, g_ServerGameDLL );
|
||||
EXPOSE_SINGLE_INTERFACE_GLOBALVAR(CServerGameDLL, IServerGameDLL, INTERFACEVERSION_SERVERGAMEDLL, g_ServerGameDLL);
|
||||
|
||||
// When bumping the version to this interface, check that our assumption is still valid and expose the older version in the same way
|
||||
COMPILE_TIME_ASSERT( INTERFACEVERSION_SERVERGAMEDLL_INT == 9 );
|
||||
COMPILE_TIME_ASSERT( INTERFACEVERSION_SERVERGAMEDLL_INT == 10 );
|
||||
|
||||
bool CServerGameDLL::DLLInit( CreateInterfaceFn appSystemFactory,
|
||||
CreateInterfaceFn physicsFactory, CreateInterfaceFn fileSystemFactory,
|
||||
@@ -1081,9 +1082,7 @@ bool g_bCheckForChainedActivate;
|
||||
{ \
|
||||
if ( bCheck ) \
|
||||
{ \
|
||||
char msg[ 1024 ]; \
|
||||
Q_snprintf( msg, sizeof( msg ), "Entity (%i/%s/%s) failed to call base class Activate()\n", pClass->entindex(), pClass->GetClassname(), STRING( pClass->GetEntityName() ) ); \
|
||||
AssertMsg( g_bReceivedChainedActivate == true, msg ); \
|
||||
AssertMsg( g_bReceivedChainedActivate, "Entity (%i/%s/%s) failed to call base class Activate()\n", pClass->entindex(), pClass->GetClassname(), STRING( pClass->GetEntityName() ) ); \
|
||||
} \
|
||||
g_bCheckForChainedActivate = false; \
|
||||
}
|
||||
@@ -1100,7 +1099,7 @@ void CServerGameDLL::ServerActivate( edict_t *pEdictList, int edictCount, int cl
|
||||
|
||||
if ( gEntList.ResetDeleteList() != 0 )
|
||||
{
|
||||
Msg( "ERROR: Entity delete queue not empty on level start!\n" );
|
||||
Msg( "%s", "ERROR: Entity delete queue not empty on level start!\n" );
|
||||
}
|
||||
|
||||
for ( CBaseEntity *pClass = gEntList.FirstEnt(); pClass != NULL; pClass = gEntList.NextEnt(pClass) )
|
||||
@@ -1150,6 +1149,7 @@ void CServerGameDLL::ServerActivate( edict_t *pEdictList, int edictCount, int cl
|
||||
void CServerGameDLL::GameServerSteamAPIActivated( void )
|
||||
{
|
||||
#ifndef NO_STEAM
|
||||
steamgameserverapicontext->Clear();
|
||||
steamgameserverapicontext->Init();
|
||||
if ( steamgameserverapicontext->SteamGameServer() && engine->IsDedicatedServer() )
|
||||
{
|
||||
@@ -1160,6 +1160,7 @@ void CServerGameDLL::GameServerSteamAPIActivated( void )
|
||||
#ifdef TF_DLL
|
||||
GCClientSystem()->GameServerActivate();
|
||||
InventoryManager()->GameServerSteamAPIActivated();
|
||||
TFMapsWorkshop()->GameServerSteamAPIActivated();
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -1936,6 +1937,52 @@ void CServerGameDLL::Status( void (*print) (const char *fmt, ...) )
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
void CServerGameDLL::PrepareLevelResources( /* in/out */ char *pszMapName, size_t nMapNameSize,
|
||||
/* in/out */ char *pszMapFile, size_t nMapFileSize )
|
||||
{
|
||||
#ifdef TF_DLL
|
||||
TFMapsWorkshop()->PrepareLevelResources( pszMapName, nMapNameSize, pszMapFile, nMapFileSize );
|
||||
#endif // TF_DLL
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
IServerGameDLL::ePrepareLevelResourcesResult
|
||||
CServerGameDLL::AsyncPrepareLevelResources( /* in/out */ char *pszMapName, size_t nMapNameSize,
|
||||
/* in/out */ char *pszMapFile, size_t nMapFileSize,
|
||||
float *flProgress /* = NULL */ )
|
||||
{
|
||||
#ifdef TF_DLL
|
||||
return TFMapsWorkshop()->AsyncPrepareLevelResources( pszMapName, nMapNameSize, pszMapFile, nMapFileSize, flProgress );
|
||||
#endif // TF_DLL
|
||||
|
||||
if ( flProgress )
|
||||
{
|
||||
*flProgress = 1.f;
|
||||
}
|
||||
return IServerGameDLL::ePrepareLevelResources_Prepared;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
IServerGameDLL::eCanProvideLevelResult CServerGameDLL::CanProvideLevel( /* in/out */ char *pMapName, int nMapNameMax )
|
||||
{
|
||||
#ifdef TF_DLL
|
||||
return TFMapsWorkshop()->OnCanProvideLevel( pMapName, nMapNameMax );
|
||||
#endif // TF_DLL
|
||||
return IServerGameDLL::eCanProvideLevel_CannotProvide;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
bool CServerGameDLL::IsManualMapChangeOkay( const char **pszReason )
|
||||
{
|
||||
if ( GameRules() )
|
||||
{
|
||||
return GameRules()->IsManualMapChangeOkay( pszReason );
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Called during a transition, to build a map adjacency list
|
||||
//-----------------------------------------------------------------------------
|
||||
@@ -2648,7 +2695,7 @@ void CServerGameClients::ClientActive( edict_t *pEdict, bool bLoadGame )
|
||||
|
||||
#if defined( TF_DLL )
|
||||
Assert( pPlayer );
|
||||
if ( pPlayer && !pPlayer->IsFakeClient() )
|
||||
if ( pPlayer && !pPlayer->IsFakeClient() && !pPlayer->IsHLTV() && !pPlayer->IsReplay() )
|
||||
{
|
||||
CSteamID steamID;
|
||||
if ( pPlayer->GetSteamID( &steamID ) )
|
||||
@@ -2657,7 +2704,10 @@ void CServerGameClients::ClientActive( edict_t *pEdict, bool bLoadGame )
|
||||
}
|
||||
else
|
||||
{
|
||||
Log("WARNING: ClientActive, but we don't know his SteamID?\n");
|
||||
if ( !pPlayer->IsReplay() && !pPlayer->IsHLTV() )
|
||||
{
|
||||
Log("WARNING: ClientActive, but we don't know his SteamID?\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@@ -2731,7 +2781,10 @@ void CServerGameClients::ClientDisconnect( edict_t *pEdict )
|
||||
}
|
||||
else
|
||||
{
|
||||
Log("WARNING: ClientDisconnected, but we don't know his SteamID?\n");
|
||||
if ( !player->IsReplay() && !player->IsHLTV() )
|
||||
{
|
||||
Log("WARNING: ClientDisconnected, but we don't know his SteamID?\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -139,7 +139,19 @@ public:
|
||||
virtual const char *GetServerBrowserGameData() OVERRIDE;
|
||||
|
||||
// Called to add output to the status command
|
||||
virtual void Status( void (*print) (const char *fmt, ...) );
|
||||
virtual void Status( void (*print) (const char *fmt, ...) ) OVERRIDE;
|
||||
|
||||
virtual void PrepareLevelResources( /* in/out */ char *pszMapName, size_t nMapNameSize,
|
||||
/* in/out */ char *pszMapFile, size_t nMapFileSize ) OVERRIDE;
|
||||
|
||||
virtual ePrepareLevelResourcesResult AsyncPrepareLevelResources( /* in/out */ char *pszMapName, size_t nMapNameSize,
|
||||
/* in/out */ char *pszMapFile, size_t nMapFileSize,
|
||||
float *flProgress = NULL ) OVERRIDE;
|
||||
|
||||
virtual eCanProvideLevelResult CanProvideLevel( /* in/out */ char *pMapName, int nMapNameMax ) OVERRIDE;
|
||||
|
||||
// Called to see if the game server is okay with a manual changelevel or map command
|
||||
virtual bool IsManualMapChangeOkay( const char **pszReason ) OVERRIDE;
|
||||
|
||||
private:
|
||||
|
||||
|
||||
@@ -82,9 +82,10 @@ public:
|
||||
DECLARE_DATADESC();
|
||||
protected:
|
||||
virtual void ComeToRest( void );
|
||||
bool m_bActivateWhenAtRest;
|
||||
|
||||
private:
|
||||
bool m_bActivateWhenAtRest;
|
||||
|
||||
COutputEvent m_OnPlayerTouch;
|
||||
COutputEvent m_OnCacheInteraction;
|
||||
|
||||
|
||||
@@ -3707,7 +3707,7 @@ static Vector FindPositionInArea( CNavArea *area, NavCornerType corner )
|
||||
pos = cornerPos + Vector( area->GetSizeX()*0.5f*multX, area->GetSizeY()*0.5f*multY, 0.0f );
|
||||
if ( !area->IsOverlapping( pos ) )
|
||||
{
|
||||
AssertMsg( false, UTIL_VarArgs( "A Hiding Spot can't be placed on its area at (%.0f %.0f %.0f)", cornerPos.x, cornerPos.y, cornerPos.z) );
|
||||
AssertMsg( false, "A Hiding Spot can't be placed on its area at (%.0f %.0f %.0f)", cornerPos.x, cornerPos.y, cornerPos.z );
|
||||
|
||||
// Just pull the position to a small offset
|
||||
pos = cornerPos + Vector( 1.0f*multX, 1.0f*multY, 0.0f );
|
||||
@@ -4285,6 +4285,9 @@ bool CNavArea::ComputeLighting( void )
|
||||
//--------------------------------------------------------------------------------------------------------------
|
||||
CON_COMMAND_F( nav_update_lighting, "Recomputes lighting values", FCVAR_CHEAT )
|
||||
{
|
||||
if ( !UTIL_IsCommandIssuedByServerAdmin() )
|
||||
return;
|
||||
|
||||
int numComputed = 0;
|
||||
if ( args.ArgC() == 2 )
|
||||
{
|
||||
|
||||
@@ -823,14 +823,9 @@ inline bool CNavArea::IsDegenerate( void ) const
|
||||
//--------------------------------------------------------------------------------------------------------------
|
||||
inline CNavArea *CNavArea::GetAdjacentArea( NavDirType dir, int i ) const
|
||||
{
|
||||
for( int iter = 0; iter < m_connect[dir].Count(); ++iter )
|
||||
{
|
||||
if (i == 0)
|
||||
return m_connect[dir][iter].area;
|
||||
--i;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
if ( ( i < 0 ) || ( i >= m_connect[dir].Count() ) )
|
||||
return NULL;
|
||||
return m_connect[dir][i].area;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------------------
|
||||
|
||||
@@ -91,8 +91,7 @@ void CFuncNavCost::Spawn( void )
|
||||
// chop space-delimited string into individual tokens
|
||||
if ( tags )
|
||||
{
|
||||
char *buffer = new char [ strlen( tags ) + 1 ];
|
||||
Q_strcpy( buffer, tags );
|
||||
char *buffer = V_strdup ( tags );
|
||||
|
||||
for( char *token = strtok( buffer, " " ); token; token = strtok( NULL, " " ) )
|
||||
{
|
||||
|
||||
@@ -1318,12 +1318,11 @@ const CUtlVector< Place > *CNavMesh::GetPlacesFromNavFile( bool *hasUnnamedPlace
|
||||
if ( IsX360() )
|
||||
{
|
||||
// 360 has compressed NAVs
|
||||
CLZMA lzma;
|
||||
if ( lzma.IsCompressed( (unsigned char *)fileBuffer.Base() ) )
|
||||
if ( CLZMA::IsCompressed( (unsigned char *)fileBuffer.Base() ) )
|
||||
{
|
||||
int originalSize = lzma.GetActualSize( (unsigned char *)fileBuffer.Base() );
|
||||
int originalSize = CLZMA::GetActualSize( (unsigned char *)fileBuffer.Base() );
|
||||
unsigned char *pOriginalData = new unsigned char[originalSize];
|
||||
lzma.Uncompress( (unsigned char *)fileBuffer.Base(), pOriginalData );
|
||||
CLZMA::Uncompress( (unsigned char *)fileBuffer.Base(), pOriginalData );
|
||||
fileBuffer.AssumeMemory( pOriginalData, originalSize, originalSize, CUtlBuffer::READ_ONLY );
|
||||
}
|
||||
}
|
||||
@@ -1411,12 +1410,11 @@ NavErrorType CNavMesh::Load( void )
|
||||
if ( IsX360() )
|
||||
{
|
||||
// 360 has compressed NAVs
|
||||
CLZMA lzma;
|
||||
if ( lzma.IsCompressed( (unsigned char *)fileBuffer.Base() ) )
|
||||
if ( CLZMA::IsCompressed( (unsigned char *)fileBuffer.Base() ) )
|
||||
{
|
||||
int originalSize = lzma.GetActualSize( (unsigned char *)fileBuffer.Base() );
|
||||
int originalSize = CLZMA::GetActualSize( (unsigned char *)fileBuffer.Base() );
|
||||
unsigned char *pOriginalData = new unsigned char[originalSize];
|
||||
lzma.Uncompress( (unsigned char *)fileBuffer.Base(), pOriginalData );
|
||||
CLZMA::Uncompress( (unsigned char *)fileBuffer.Base(), pOriginalData );
|
||||
fileBuffer.AssumeMemory( pOriginalData, originalSize, originalSize, CUtlBuffer::READ_ONLY );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1229,9 +1229,12 @@ void CNavMesh::RemoveOverlappingObstacleTopAreas()
|
||||
|
||||
static void CommandNavCheckStairs( void )
|
||||
{
|
||||
if ( !UTIL_IsCommandIssuedByServerAdmin() )
|
||||
return;
|
||||
|
||||
TheNavMesh->MarkStairAreas();
|
||||
}
|
||||
static ConCommand nav_check_stairs( "nav_check_stairs", CommandNavCheckStairs, "Update the nav mesh STAIRS attribute" );
|
||||
static ConCommand nav_check_stairs( "nav_check_stairs", CommandNavCheckStairs, "Update the nav mesh STAIRS attribute", FCVAR_CHEAT );
|
||||
|
||||
//--------------------------------------------------------------------------------------------------------------
|
||||
/**
|
||||
@@ -1445,6 +1448,9 @@ bool CNavArea::TestStairs( void )
|
||||
//--------------------------------------------------------------------------------------------------------------
|
||||
CON_COMMAND_F( nav_test_stairs, "Test the selected set for being on stairs", FCVAR_CHEAT )
|
||||
{
|
||||
if ( !UTIL_IsCommandIssuedByServerAdmin() )
|
||||
return;
|
||||
|
||||
int count = 0;
|
||||
|
||||
const NavAreaVector &selectedSet = TheNavMesh->GetSelectedSet();
|
||||
@@ -4932,5 +4938,8 @@ void CNavMesh::PostProcessCliffAreas()
|
||||
|
||||
CON_COMMAND_F( nav_gen_cliffs_approx, "Mark cliff areas, post-processing approximation", FCVAR_CHEAT )
|
||||
{
|
||||
if ( !UTIL_IsCommandIssuedByServerAdmin() )
|
||||
return;
|
||||
|
||||
TheNavMesh->PostProcessCliffAreas();
|
||||
}
|
||||
|
||||
@@ -1700,6 +1700,9 @@ static ConCommand nav_clear_selected_set( "nav_clear_selected_set", CommandNavCl
|
||||
//----------------------------------------------------------------------------------
|
||||
CON_COMMAND_F( nav_dump_selected_set_positions, "Write the (x,y,z) coordinates of the centers of all selected nav areas to a file.", FCVAR_GAMEDLL | FCVAR_CHEAT )
|
||||
{
|
||||
if ( !UTIL_IsCommandIssuedByServerAdmin() )
|
||||
return;
|
||||
|
||||
const NavAreaVector &selectedSet = TheNavMesh->GetSelectedSet();
|
||||
|
||||
CUtlBuffer fileBuffer( 4096, 1024*1024, CUtlBuffer::TEXT_BUFFER );
|
||||
@@ -1732,6 +1735,9 @@ CON_COMMAND_F( nav_dump_selected_set_positions, "Write the (x,y,z) coordinates o
|
||||
//----------------------------------------------------------------------------------
|
||||
CON_COMMAND_F( nav_show_dumped_positions, "Show the (x,y,z) coordinate positions of the given dump file.", FCVAR_GAMEDLL | FCVAR_CHEAT )
|
||||
{
|
||||
if ( !UTIL_IsCommandIssuedByServerAdmin() )
|
||||
return;
|
||||
|
||||
CUtlBuffer fileBuffer( 4096, 1024*1024, CUtlBuffer::TEXT_BUFFER );
|
||||
|
||||
// filename is local to game dir for Steam, so we need to prepend game dir for regular file save
|
||||
@@ -1764,6 +1770,9 @@ CON_COMMAND_F( nav_show_dumped_positions, "Show the (x,y,z) coordinate positions
|
||||
//----------------------------------------------------------------------------------
|
||||
CON_COMMAND_F( nav_select_larger_than, "Select nav areas where both dimensions are larger than the given size.", FCVAR_GAMEDLL | FCVAR_CHEAT )
|
||||
{
|
||||
if ( !UTIL_IsCommandIssuedByServerAdmin() )
|
||||
return;
|
||||
|
||||
if ( args.ArgC() > 1 )
|
||||
{
|
||||
float minSize = atof( args[1] );
|
||||
@@ -2665,6 +2674,9 @@ void CNavMesh::CommandNavMarkWalkable( void )
|
||||
{
|
||||
Vector pos;
|
||||
|
||||
if ( !UTIL_IsCommandIssuedByServerAdmin() )
|
||||
return;
|
||||
|
||||
if (nav_edit.GetBool())
|
||||
{
|
||||
// we are in edit mode, use the edit cursor's location
|
||||
|
||||
@@ -28,7 +28,7 @@ class CStringTableSaveRestoreOps;
|
||||
#define MAX_CHOREO_SCENES_STRINGS ( 1 << MAX_CHOREO_SCENES_STRING_BITS )
|
||||
#define CHOREO_SCENES_INVALID_STRING ( MAX_CHOREO_SCENES_STRINGS - 1 )
|
||||
|
||||
#define MAX_PARTICLESYSTEMS_STRING_BITS 11
|
||||
#define MAX_PARTICLESYSTEMS_STRING_BITS 12
|
||||
#define MAX_PARTICLESYSTEMS_STRINGS ( 1 << MAX_PARTICLESYSTEMS_STRING_BITS )
|
||||
#define PARTICLESYSTEMS_INVALID_STRING ( MAX_PARTICLESYSTEMS_STRINGS - 1 )
|
||||
|
||||
|
||||
@@ -585,7 +585,9 @@ CBasePlayer::CBasePlayer( )
|
||||
m_bForceOrigin = false;
|
||||
m_hVehicle = NULL;
|
||||
m_pCurrentCommand = NULL;
|
||||
|
||||
m_iLockViewanglesTickNumber = 0;
|
||||
m_qangLockViewangles.Init();
|
||||
|
||||
// Setup our default FOV
|
||||
m_iDefaultFOV = g_pGameRules->DefaultFOV();
|
||||
|
||||
@@ -976,7 +978,7 @@ void CBasePlayer::DamageEffect(float flDamage, int fDamageType)
|
||||
}
|
||||
else if (fDamageType & DMG_DROWN)
|
||||
{
|
||||
//Red damage indicator
|
||||
//Blue damage indicator
|
||||
color32 blue = {0,0,128,128};
|
||||
UTIL_ScreenFade( this, blue, 1.0f, 0.1f, FFADE_IN );
|
||||
}
|
||||
@@ -2325,6 +2327,7 @@ bool CBasePlayer::SetObserverMode(int mode )
|
||||
break;
|
||||
|
||||
case OBS_MODE_CHASE :
|
||||
case OBS_MODE_POI: // PASSTIME
|
||||
case OBS_MODE_IN_EYE :
|
||||
// udpate FOV and viewmodels
|
||||
SetObserverTarget( m_hObserverTarget );
|
||||
@@ -2420,8 +2423,7 @@ void CBasePlayer::CheckObserverSettings()
|
||||
}
|
||||
|
||||
// check if our spectating target is still a valid one
|
||||
|
||||
if ( m_iObserverMode == OBS_MODE_IN_EYE || m_iObserverMode == OBS_MODE_CHASE || m_iObserverMode == OBS_MODE_FIXED )
|
||||
if ( m_iObserverMode == OBS_MODE_IN_EYE || m_iObserverMode == OBS_MODE_CHASE || m_iObserverMode == OBS_MODE_FIXED || m_iObserverMode == OBS_MODE_POI )
|
||||
{
|
||||
ValidateCurrentObserverTarget();
|
||||
|
||||
@@ -2633,7 +2635,10 @@ bool CBasePlayer::SetObserverTarget(CBaseEntity *target)
|
||||
Vector dir, end;
|
||||
Vector start = target->EyePosition();
|
||||
|
||||
AngleVectors( target->EyeAngles(), &dir );
|
||||
QAngle ang = target->EyeAngles();
|
||||
ang.z = 0; // PASSTIME no view roll when spectating ball
|
||||
|
||||
AngleVectors( ang, &dir );
|
||||
VectorNormalize( dir );
|
||||
VectorMA( start, -64.0f, dir, end );
|
||||
|
||||
@@ -2643,7 +2648,7 @@ bool CBasePlayer::SetObserverTarget(CBaseEntity *target)
|
||||
trace_t tr;
|
||||
UTIL_TraceRay( ray, MASK_PLAYERSOLID, target, COLLISION_GROUP_PLAYER_MOVEMENT, &tr );
|
||||
|
||||
JumptoPosition( tr.endpos, target->EyeAngles() );
|
||||
JumptoPosition( tr.endpos, ang );
|
||||
}
|
||||
|
||||
return true;
|
||||
@@ -3411,6 +3416,8 @@ void CBasePlayer::ForceSimulation()
|
||||
m_nSimulationTick = -1;
|
||||
}
|
||||
|
||||
ConVar sv_usercmd_custom_random_seed( "sv_usercmd_custom_random_seed", "1", FCVAR_CHEAT, "When enabled server will populate an additional random seed independent of the client" );
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
// Input : *buf -
|
||||
@@ -3437,6 +3444,16 @@ void CBasePlayer::ProcessUsercmds( CUserCmd *cmds, int numcmds, int totalcmds,
|
||||
pCmd->MakeInert();
|
||||
}
|
||||
|
||||
if ( sv_usercmd_custom_random_seed.GetBool() )
|
||||
{
|
||||
float fltTimeNow = float( Plat_FloatTime() * 1000.0 );
|
||||
pCmd->server_random_seed = *reinterpret_cast<int*>( (char*)&fltTimeNow );
|
||||
}
|
||||
else
|
||||
{
|
||||
pCmd->server_random_seed = pCmd->random_seed;
|
||||
}
|
||||
|
||||
ctx->cmds.AddToTail( *pCmd );
|
||||
}
|
||||
ctx->numcmds = numcmds;
|
||||
@@ -7875,7 +7892,7 @@ void CMovementSpeedMod::InputSpeedMod(inputdata_t &data)
|
||||
// Bring the weapon back
|
||||
if ( HasSpawnFlags( SF_SPEED_MOD_SUPPRESS_WEAPONS ) && pPlayer->GetActiveWeapon() == NULL )
|
||||
{
|
||||
pPlayer->SetActiveWeapon( pPlayer->Weapon_GetLast() );
|
||||
pPlayer->SetActiveWeapon( pPlayer->GetLastWeapon() );
|
||||
if ( pPlayer->GetActiveWeapon() )
|
||||
{
|
||||
pPlayer->GetActiveWeapon()->Deploy();
|
||||
@@ -8857,8 +8874,6 @@ void CBasePlayer::SetPlayerName( const char *name )
|
||||
Assert( strlen(name) > 0 );
|
||||
|
||||
Q_strncpy( m_szNetname, name, sizeof(m_szNetname) );
|
||||
// Be extra thorough
|
||||
Q_RemoveAllEvilCharacters( m_szNetname );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9386,4 +9401,4 @@ uint64 CBasePlayer::GetSteamIDAsUInt64( void )
|
||||
return steamIDForPlayer.ConvertToUint64();
|
||||
return 0;
|
||||
}
|
||||
#endif // NO_STEAM
|
||||
#endif // NO_STEAM
|
||||
|
||||
@@ -415,7 +415,7 @@ public:
|
||||
virtual bool Weapon_ShouldSetLast( CBaseCombatWeapon *pOldWeapon, CBaseCombatWeapon *pNewWeapon ) { return true; }
|
||||
virtual bool Weapon_ShouldSelectItem( CBaseCombatWeapon *pWeapon );
|
||||
void Weapon_DropSlot( int weaponSlot );
|
||||
CBaseCombatWeapon *Weapon_GetLast( void ) { return m_hLastWeapon.Get(); }
|
||||
CBaseCombatWeapon *GetLastWeapon( void ) { return m_hLastWeapon.Get(); }
|
||||
|
||||
virtual void OnMyWeaponFired( CBaseCombatWeapon *weapon ); // call this when this player fires a weapon to allow other systems to react
|
||||
virtual float GetTimeSinceWeaponFired( void ) const; // returns the time, in seconds, since this player fired a weapon
|
||||
@@ -735,6 +735,8 @@ public:
|
||||
bool IsPredictingWeapons( void ) const;
|
||||
int CurrentCommandNumber() const;
|
||||
const CUserCmd *GetCurrentUserCommand() const;
|
||||
int GetLockViewanglesTickNumber() const { return m_iLockViewanglesTickNumber; }
|
||||
QAngle GetLockViewanglesData() const { return m_qangLockViewangles; }
|
||||
|
||||
int GetFOV( void ); // Get the current FOV value
|
||||
int GetDefaultFOV( void ) const; // Default FOV if not specified otherwise
|
||||
@@ -891,7 +893,8 @@ public:
|
||||
|
||||
#if defined USES_ECON_ITEMS
|
||||
CEconWearable *GetWearable( int i ) { return m_hMyWearables[i]; }
|
||||
int GetNumWearables( void ) { return m_hMyWearables.Count(); }
|
||||
const CEconWearable *GetWearable( int i ) const { return m_hMyWearables[i]; }
|
||||
int GetNumWearables( void ) const { return m_hMyWearables.Count(); }
|
||||
#endif
|
||||
|
||||
private:
|
||||
@@ -1058,6 +1061,8 @@ protected:
|
||||
// Last received usercmd (in case we drop a lot of packets )
|
||||
CUserCmd m_LastCmd;
|
||||
CUserCmd *m_pCurrentCommand;
|
||||
int m_iLockViewanglesTickNumber;
|
||||
QAngle m_qangLockViewangles;
|
||||
|
||||
float m_flStepSoundTime; // time to check for next footstep sound
|
||||
|
||||
|
||||
@@ -23,6 +23,7 @@ extern CMoveData *g_pMoveData; // This is a global because it is subclassed by e
|
||||
extern ConVar sv_noclipduringpause;
|
||||
|
||||
ConVar sv_maxusrcmdprocessticks_warning( "sv_maxusrcmdprocessticks_warning", "-1", FCVAR_NONE, "Print a warning when user commands get dropped due to insufficient usrcmd ticks allocated, number of seconds to throttle, negative disabled" );
|
||||
static ConVar sv_maxusrcmdprocessticks_holdaim( "sv_maxusrcmdprocessticks_holdaim", "1", FCVAR_CHEAT, "Hold client aim for multiple server sim ticks when client-issued usrcmd contains multiple actions (0: off; 1: hold this server tick; 2+: hold multiple ticks)" );
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
@@ -442,6 +443,12 @@ void CPlayerMove::RunCommand ( CBasePlayer *player, CUserCmd *ucmd, IMoveHelper
|
||||
// Copy output
|
||||
FinishMove( player, ucmd, g_pMoveData );
|
||||
|
||||
// If we have to restore the view angle then do so right now
|
||||
if ( !player->IsBot() && ( gpGlobals->tickcount - player->GetLockViewanglesTickNumber() < sv_maxusrcmdprocessticks_holdaim.GetInt() ) )
|
||||
{
|
||||
player->pl.v_angle = player->GetLockViewanglesData();
|
||||
}
|
||||
|
||||
// Let server invoke any needed impact functions
|
||||
VPROF_SCOPE_BEGIN( "moveHelper->ProcessImpacts" );
|
||||
moveHelper->ProcessImpacts();
|
||||
|
||||
@@ -56,6 +56,7 @@ private:
|
||||
private:
|
||||
bool m_bSpotlightOn;
|
||||
bool m_bEfficientSpotlight;
|
||||
bool m_bIgnoreSolid;
|
||||
Vector m_vSpotlightTargetPos;
|
||||
Vector m_vSpotlightCurrentPos;
|
||||
Vector m_vSpotlightDir;
|
||||
@@ -88,6 +89,7 @@ BEGIN_DATADESC( CPointSpotlight )
|
||||
DEFINE_FIELD( m_vSpotlightDir, FIELD_VECTOR ),
|
||||
DEFINE_FIELD( m_nHaloSprite, FIELD_INTEGER ),
|
||||
|
||||
DEFINE_KEYFIELD( m_bIgnoreSolid, FIELD_BOOLEAN, "IgnoreSolid" ),
|
||||
DEFINE_KEYFIELD( m_flSpotlightMaxLength,FIELD_FLOAT, "SpotlightLength"),
|
||||
DEFINE_KEYFIELD( m_flSpotlightGoalWidth,FIELD_FLOAT, "SpotlightWidth"),
|
||||
DEFINE_KEYFIELD( m_flHDRColorScale, FIELD_FLOAT, "HDRColorScale" ),
|
||||
@@ -118,6 +120,7 @@ CPointSpotlight::CPointSpotlight()
|
||||
#endif
|
||||
m_flHDRColorScale = 1.0f;
|
||||
m_nMinDXLevel = 0;
|
||||
m_bIgnoreSolid = false;
|
||||
}
|
||||
|
||||
|
||||
@@ -332,12 +335,21 @@ void CPointSpotlight::SpotlightCreate(void)
|
||||
|
||||
AngleVectors( GetAbsAngles(), &m_vSpotlightDir );
|
||||
|
||||
trace_t tr;
|
||||
UTIL_TraceLine( GetAbsOrigin(), GetAbsOrigin() + m_vSpotlightDir * m_flSpotlightMaxLength, MASK_SOLID_BRUSHONLY, this, COLLISION_GROUP_NONE, &tr);
|
||||
Vector vTargetPos;
|
||||
if ( m_bIgnoreSolid )
|
||||
{
|
||||
vTargetPos = GetAbsOrigin() + m_vSpotlightDir * m_flSpotlightMaxLength;
|
||||
}
|
||||
else
|
||||
{
|
||||
trace_t tr;
|
||||
UTIL_TraceLine( GetAbsOrigin(), GetAbsOrigin() + m_vSpotlightDir * m_flSpotlightMaxLength, MASK_SOLID_BRUSHONLY, this, COLLISION_GROUP_NONE, &tr );
|
||||
vTargetPos = tr.endpos;
|
||||
}
|
||||
|
||||
m_hSpotlightTarget = (CSpotlightEnd*)CreateEntityByName( "spotlight_end" );
|
||||
m_hSpotlightTarget->Spawn();
|
||||
m_hSpotlightTarget->SetAbsOrigin( tr.endpos );
|
||||
m_hSpotlightTarget->SetAbsOrigin( vTargetPos );
|
||||
m_hSpotlightTarget->SetOwnerEntity( this );
|
||||
m_hSpotlightTarget->m_clrRender = m_clrRender;
|
||||
m_hSpotlightTarget->m_Radius = m_flSpotlightMaxLength;
|
||||
@@ -381,9 +393,17 @@ Vector CPointSpotlight::SpotlightCurrentPos(void)
|
||||
AngleVectors( GetAbsAngles(), &m_vSpotlightDir );
|
||||
|
||||
// Get beam end point. Only collide with solid objects, not npcs
|
||||
trace_t tr;
|
||||
UTIL_TraceLine( GetAbsOrigin(), GetAbsOrigin() + (m_vSpotlightDir * 2 * m_flSpotlightMaxLength), MASK_SOLID_BRUSHONLY, this, COLLISION_GROUP_NONE, &tr );
|
||||
return tr.endpos;
|
||||
Vector vEndPos = GetAbsOrigin() + ( m_vSpotlightDir * 2 * m_flSpotlightMaxLength );
|
||||
if ( m_bIgnoreSolid )
|
||||
{
|
||||
return vEndPos;
|
||||
}
|
||||
else
|
||||
{
|
||||
trace_t tr;
|
||||
UTIL_TraceLine( GetAbsOrigin(), vEndPos, MASK_SOLID_BRUSHONLY, this, COLLISION_GROUP_NONE, &tr );
|
||||
return tr.endpos;
|
||||
}
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
@@ -1811,6 +1811,8 @@ LINK_ENTITY_TO_CLASS( dynamic_prop, CDynamicProp );
|
||||
LINK_ENTITY_TO_CLASS( prop_dynamic, CDynamicProp );
|
||||
LINK_ENTITY_TO_CLASS( prop_dynamic_override, CDynamicProp );
|
||||
|
||||
IMPLEMENT_AUTO_LIST( IPhysicsPropAutoList );
|
||||
|
||||
BEGIN_DATADESC( CDynamicProp )
|
||||
|
||||
// Fields
|
||||
|
||||
@@ -327,7 +327,8 @@ protected:
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
class CPhysicsProp : public CBreakableProp
|
||||
DECLARE_AUTO_LIST( IPhysicsPropAutoList );
|
||||
class CPhysicsProp : public CBreakableProp, public IPhysicsPropAutoList
|
||||
{
|
||||
DECLARE_CLASS( CPhysicsProp, CBreakableProp );
|
||||
DECLARE_SERVERCLASS();
|
||||
|
||||
@@ -341,7 +341,7 @@ CTeamRecipientFilter::CTeamRecipientFilter( int team, bool isReliable )
|
||||
if ( pPlayer->GetTeamNumber() != team )
|
||||
{
|
||||
//If we're in the spectator team then we should be getting whatever messages the person I'm spectating gets.
|
||||
if ( pPlayer->GetTeamNumber() == TEAM_SPECTATOR && (pPlayer->GetObserverMode() == OBS_MODE_IN_EYE || pPlayer->GetObserverMode() == OBS_MODE_CHASE) )
|
||||
if ( pPlayer->GetTeamNumber() == TEAM_SPECTATOR && (pPlayer->GetObserverMode() == OBS_MODE_IN_EYE || pPlayer->GetObserverMode() == OBS_MODE_CHASE || pPlayer->GetObserverMode() == OBS_MODE_POI) )
|
||||
{
|
||||
if ( pPlayer->GetObserverTarget() )
|
||||
{
|
||||
|
||||
@@ -4951,8 +4951,9 @@ void CSceneManager::RemoveScenesInvolvingActor( CBaseFlex *pActor )
|
||||
if ( !pActor )
|
||||
return;
|
||||
|
||||
// This loop can remove items from m_ActiveScenes array, so loop through backwards.
|
||||
int c = m_ActiveScenes.Count();
|
||||
for ( int i = 0; i < c; i++ )
|
||||
for ( int i = c - 1 ; i >= 0; --i )
|
||||
{
|
||||
CSceneEntity *pScene = m_ActiveScenes[ i ].Get();
|
||||
if ( !pScene )
|
||||
|
||||
@@ -528,8 +528,8 @@ void CSlideshowDisplay::BuildSlideShowImagesList( void )
|
||||
|
||||
if ( bLoaded )
|
||||
{
|
||||
char szKeywords[ 256 ];
|
||||
Q_strcpy( szKeywords, pMaterialKeys->GetString( "%keywords", "" ) );
|
||||
char szKeywords[ 256 ] = {0};
|
||||
V_strcpy_safe( szKeywords, pMaterialKeys->GetString( "%keywords", "" ) );
|
||||
|
||||
char *pchKeyword = szKeywords;
|
||||
|
||||
@@ -562,7 +562,7 @@ void CSlideshowDisplay::BuildSlideShowImagesList( void )
|
||||
{
|
||||
// Couldn't find the list, so create it
|
||||
iList = m_SlideKeywordList.AddToTail( new SlideKeywordList_t );
|
||||
Q_strcpy( m_SlideKeywordList[ iList ]->szSlideKeyword, pchKeyword );
|
||||
V_strcpy_safe( m_SlideKeywordList[iList]->szSlideKeyword, pchKeyword );
|
||||
}
|
||||
|
||||
pchKeyword = pNextKeyword;
|
||||
@@ -581,7 +581,7 @@ void CSlideshowDisplay::BuildSlideShowImagesList( void )
|
||||
{
|
||||
// Couldn't find the generic list, so create it
|
||||
iList = m_SlideKeywordList.AddToHead( new SlideKeywordList_t );
|
||||
Q_strcpy( m_SlideKeywordList[ iList ]->szSlideKeyword, "" );
|
||||
V_strcpy_safe( m_SlideKeywordList[iList]->szSlideKeyword, "" );
|
||||
}
|
||||
|
||||
if ( IsX360() )
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
|
||||
#ifdef TF_DLL
|
||||
#include "tf_shareddefs.h"
|
||||
#include "tf_gamerules.h"
|
||||
#endif
|
||||
|
||||
#define CONTROL_POINT_UNLOCK_THINK "UnlockThink"
|
||||
@@ -269,6 +270,7 @@ void CTeamControlPoint::Precache( void )
|
||||
|
||||
#ifdef TF_DLL
|
||||
PrecacheScriptSound( "Announcer.ControlPointContested" );
|
||||
PrecacheScriptSound( "Announcer.ControlPointContested_Neutral" );
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -653,7 +655,15 @@ void CTeamControlPoint::InternalSetOwner( int iCapTeam, bool bMakeSound, int iNu
|
||||
|
||||
Assert( playerIndex > 0 && playerIndex <= gpGlobals->maxClients );
|
||||
|
||||
PlayerCapped( ToBaseMultiplayerPlayer(UTIL_PlayerByIndex( playerIndex )) );
|
||||
CBaseMultiplayerPlayer *pPlayer = ToBaseMultiplayerPlayer( UTIL_PlayerByIndex( playerIndex ) );
|
||||
PlayerCapped( pPlayer );
|
||||
|
||||
#ifdef TF_DLL
|
||||
if ( TFGameRules() && TFGameRules()->IsHolidayActive( kHoliday_EOTL ) )
|
||||
{
|
||||
TFGameRules()->DropBonusDuck( pPlayer->GetAbsOrigin(), ToTFPlayer( pPlayer ), NULL, NULL, false, true );
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
// Remap team to get first game team = 1
|
||||
@@ -733,7 +743,7 @@ void CTeamControlPoint::SendCapString( int iCapTeam, int iNumCappingPlayers, int
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void CTeamControlPoint::CaptureBlocked( CBaseMultiplayerPlayer *pPlayer )
|
||||
void CTeamControlPoint::CaptureBlocked( CBaseMultiplayerPlayer *pPlayer, CBaseMultiplayerPlayer *pVictim )
|
||||
{
|
||||
if( strlen( STRING(m_iszPrintName) ) <= 0 )
|
||||
return;
|
||||
@@ -746,6 +756,10 @@ void CTeamControlPoint::CaptureBlocked( CBaseMultiplayerPlayer *pPlayer )
|
||||
event->SetString( "cpname", STRING(m_iszPrintName) );
|
||||
event->SetInt( "blocker", pPlayer->entindex() );
|
||||
event->SetInt( "priority", 9 );
|
||||
if ( pVictim )
|
||||
{
|
||||
event->SetInt( "victim", pVictim->entindex() );
|
||||
}
|
||||
|
||||
gameeventmanager->FireEvent( event );
|
||||
}
|
||||
|
||||
@@ -82,7 +82,7 @@ public:
|
||||
|
||||
void SetCappersRequiredForTeam( int iGameTeam, int iCappers );
|
||||
|
||||
void CaptureBlocked( CBaseMultiplayerPlayer *pPlayer );
|
||||
void CaptureBlocked( CBaseMultiplayerPlayer *pPlayer, CBaseMultiplayerPlayer *pVictim );
|
||||
|
||||
int PointValue( void );
|
||||
|
||||
|
||||
@@ -1056,65 +1056,44 @@ bool CTeamControlPointMaster::IsBaseControlPoint( int iPointIndex )
|
||||
int CTeamControlPointMaster::GetBaseControlPoint( int iTeam )
|
||||
{
|
||||
int iRetVal = -1;
|
||||
int nLowestValue = 999, nHighestValue = -1;
|
||||
int iLowestIndex = 0, iHighestIndex = 0;
|
||||
int nLowestValue = 999;
|
||||
int nHighestValue = -1;
|
||||
CTeamControlPoint *pLowestPoint = NULL;
|
||||
CTeamControlPoint *pHighestPoint = NULL;
|
||||
|
||||
for( int i = 0 ; i < (int)m_ControlPoints.Count() ; i++ )
|
||||
for( unsigned int i = 0 ; i < m_ControlPoints.Count() ; i++ )
|
||||
{
|
||||
CTeamControlPoint *pPoint = m_ControlPoints[i];
|
||||
|
||||
int iPointIndex = m_ControlPoints[i]->GetPointIndex();
|
||||
|
||||
if ( PlayingMiniRounds() && iTeam > LAST_SHARED_TEAM )
|
||||
if ( !PlayingMiniRounds() || ( IsInRound( pPoint ) && ( iTeam > LAST_SHARED_TEAM ) ) )
|
||||
{
|
||||
if ( IsInRound( pPoint ) ) // is this point in the current round?
|
||||
{
|
||||
if ( iPointIndex > nHighestValue )
|
||||
{
|
||||
nHighestValue = iPointIndex;
|
||||
iHighestIndex = i;
|
||||
}
|
||||
int nTempValue = pPoint->GetPointIndex();
|
||||
|
||||
if ( iPointIndex < nLowestValue )
|
||||
{
|
||||
nLowestValue = iPointIndex;
|
||||
iLowestIndex = i;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( pPoint->GetDefaultOwner() != iTeam )
|
||||
if ( nTempValue > nHighestValue )
|
||||
{
|
||||
continue;
|
||||
nHighestValue = nTempValue;
|
||||
pHighestPoint = pPoint;
|
||||
}
|
||||
|
||||
// If it's the first or the last point, it's their base
|
||||
if ( iPointIndex == 0 || iPointIndex == (((int)m_ControlPoints.Count())-1) )
|
||||
if ( nTempValue < nLowestValue )
|
||||
{
|
||||
iRetVal = iPointIndex;
|
||||
break;
|
||||
nLowestValue = nTempValue;
|
||||
pLowestPoint = pPoint;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ( PlayingMiniRounds() && iTeam > LAST_SHARED_TEAM )
|
||||
if ( pLowestPoint && pHighestPoint )
|
||||
{
|
||||
if ( nLowestValue != 999 && nHighestValue != -1 )
|
||||
// which point is owned by this team?
|
||||
if ( ( pLowestPoint->GetDefaultOwner() == iTeam && pHighestPoint->GetDefaultOwner() == iTeam ) || // if the same team owns both, take the highest value to be the last point
|
||||
( pHighestPoint->GetDefaultOwner() == iTeam ) )
|
||||
{
|
||||
CTeamControlPoint *pLowestPoint = m_ControlPoints[iLowestIndex];
|
||||
CTeamControlPoint *pHighestPoint = m_ControlPoints[iHighestIndex];
|
||||
|
||||
// which point is owned by this team?
|
||||
if ( ( pLowestPoint->GetDefaultOwner() == iTeam && pHighestPoint->GetDefaultOwner() == iTeam ) || // if the same team owns both, take the highest value to be the last point
|
||||
( pHighestPoint->GetDefaultOwner() == iTeam ) )
|
||||
{
|
||||
iRetVal = nHighestValue;
|
||||
}
|
||||
else if ( pLowestPoint->GetDefaultOwner() == iTeam )
|
||||
{
|
||||
iRetVal = nLowestValue;
|
||||
}
|
||||
iRetVal = nHighestValue;
|
||||
}
|
||||
else if ( pLowestPoint->GetDefaultOwner() == iTeam )
|
||||
{
|
||||
iRetVal = nLowestValue;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -132,6 +132,7 @@ public:
|
||||
float GetLastOwnershipChangeTime( void ) { return m_flLastOwnershipChangeTime; }
|
||||
|
||||
int GetCurrentRoundIndex() { return m_iCurrentRoundIndex; }
|
||||
bool ShouldSwitchTeamsOnRoundWin( void ) { return m_bSwitchTeamsOnWin; }
|
||||
|
||||
private:
|
||||
void EXPORT CPMThink( void );
|
||||
|
||||
@@ -535,7 +535,7 @@ void CTriggerAreaCapture::CaptureThink( void )
|
||||
|
||||
if ( !bRepeatBlocker )
|
||||
{
|
||||
m_hPoint->CaptureBlocked( pBlockingPlayer );
|
||||
m_hPoint->CaptureBlocked( pBlockingPlayer, NULL );
|
||||
|
||||
// Add this guy to our blocker list
|
||||
int iNew = m_Blockers.AddToTail();
|
||||
@@ -882,6 +882,12 @@ void CTriggerAreaCapture::EndCapture( int team )
|
||||
m_nCapturingTeam = TEAM_UNASSIGNED;
|
||||
SetCapTimeRemaining( 0 );
|
||||
|
||||
// play any special cap sounds. need to do this before we update the owner of the point.
|
||||
if ( TeamplayRoundBasedRules() )
|
||||
{
|
||||
TeamplayRoundBasedRules()->PlaySpecialCapSounds( m_nOwningTeam, m_hPoint.Get() );
|
||||
}
|
||||
|
||||
//there may have been more than one capper, but only report this one.
|
||||
//he hasn't gotten points yet, and his name will go in the cap string if its needed
|
||||
//first capper gets name sent and points given by flag.
|
||||
@@ -912,12 +918,6 @@ void CTriggerAreaCapture::EndCapture( int team )
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// play any special cap sounds
|
||||
if ( TeamplayRoundBasedRules() )
|
||||
{
|
||||
TeamplayRoundBasedRules()->PlaySpecialCapSounds( m_nOwningTeam );
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
@@ -1140,7 +1140,7 @@ bool CTriggerAreaCapture::CheckIfDeathCausesBlock( CBaseMultiplayerPlayer *pVict
|
||||
|
||||
if ( bBreakCap )
|
||||
{
|
||||
m_hPoint->CaptureBlocked( pKiller );
|
||||
m_hPoint->CaptureBlocked( pKiller, pVictim );
|
||||
//BreakCapture( true );
|
||||
}
|
||||
|
||||
|
||||
@@ -475,6 +475,7 @@ void CBaseTrigger::StartTouch(CBaseEntity *pOther)
|
||||
{
|
||||
// First entity to touch us that passes our filters
|
||||
m_OnStartTouchAll.FireOutput( pOther, this );
|
||||
StartTouchAll();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -514,7 +515,10 @@ void CBaseTrigger::EndTouch(CBaseEntity *pOther)
|
||||
else if ( hOther->IsPlayer() && !hOther->IsAlive() )
|
||||
{
|
||||
#ifdef STAGING_ONLY
|
||||
AssertMsg( 0, CFmtStr( "Dead player [%s] is still touching this trigger at [%f %f %f]", hOther->GetEntityName().ToCStr(), XYZ( hOther->GetAbsOrigin() ) ) );
|
||||
if ( !HushAsserts() )
|
||||
{
|
||||
AssertMsg( false, "Dead player [%s] is still touching this trigger at [%f %f %f]", hOther->GetEntityName().ToCStr(), XYZ( hOther->GetAbsOrigin() ) );
|
||||
}
|
||||
Warning( "Dead player [%s] is still touching this trigger at [%f %f %f]", hOther->GetEntityName().ToCStr(), XYZ( hOther->GetAbsOrigin() ) );
|
||||
#endif
|
||||
m_hTouchingEntities.Remove( i );
|
||||
@@ -530,6 +534,7 @@ void CBaseTrigger::EndTouch(CBaseEntity *pOther)
|
||||
if ( !bFoundOtherTouchee /*&& !m_bDisabled*/ )
|
||||
{
|
||||
m_OnEndTouchAll.FireOutput(pOther, this);
|
||||
EndTouchAll();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -634,8 +639,8 @@ void CTriggerRemove::Touch( CBaseEntity *pOther )
|
||||
BEGIN_DATADESC( CTriggerHurt )
|
||||
|
||||
// Function Pointers
|
||||
DEFINE_FUNCTION( RadiationThink ),
|
||||
DEFINE_FUNCTION( HurtThink ),
|
||||
DEFINE_FUNCTION( CTriggerHurtShim::RadiationThinkShim ),
|
||||
DEFINE_FUNCTION( CTriggerHurtShim::HurtThinkShim ),
|
||||
|
||||
// Fields
|
||||
DEFINE_FIELD( m_flOriginalDamage, FIELD_FLOAT ),
|
||||
@@ -661,6 +666,7 @@ END_DATADESC()
|
||||
|
||||
LINK_ENTITY_TO_CLASS( trigger_hurt, CTriggerHurt );
|
||||
|
||||
IMPLEMENT_AUTO_LIST( ITriggerHurtAutoList );
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Called when spawning, after keyvalues have been handled.
|
||||
@@ -677,7 +683,7 @@ void CTriggerHurt::Spawn( void )
|
||||
SetThink( NULL );
|
||||
if (m_bitsDamageInflict & DMG_RADIATION)
|
||||
{
|
||||
SetThink ( &CTriggerHurt::RadiationThink );
|
||||
SetThink ( &CTriggerHurtShim::RadiationThinkShim );
|
||||
SetNextThink( gpGlobals->curtime + random->RandomFloat(0.0, 0.5) );
|
||||
}
|
||||
}
|
||||
@@ -723,6 +729,15 @@ bool CTriggerHurt::HurtEntity( CBaseEntity *pOther, float damage )
|
||||
if ( !pOther->m_takedamage || !PassesTriggerFilters(pOther) )
|
||||
return false;
|
||||
|
||||
// If player is disconnected, we're probably in this routine via the
|
||||
// PhysicsRemoveTouchedList() function to make sure all Untouch()'s are called for the
|
||||
// player. Calling TakeDamage() in this case can get into the speaking criteria, which
|
||||
// will then loop through the control points and the touched list again. We shouldn't
|
||||
// need to hurt players that are disconnected, so skip all of this...
|
||||
bool bPlayerDisconnected = pOther->IsPlayer() && ( ((CBasePlayer *)pOther)->IsConnected() == false );
|
||||
if ( bPlayerDisconnected )
|
||||
return false;
|
||||
|
||||
if ( damage < 0 )
|
||||
{
|
||||
pOther->TakeHealth( -damage, m_bitsDamageInflict );
|
||||
@@ -862,11 +877,29 @@ void CTriggerHurt::Touch( CBaseEntity *pOther )
|
||||
{
|
||||
if ( m_pfnThink == NULL )
|
||||
{
|
||||
SetThink( &CTriggerHurt::HurtThink );
|
||||
SetThink( &CTriggerHurtShim::HurtThinkShim );
|
||||
SetNextThink( gpGlobals->curtime );
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Checks if this point is in any trigger_hurt zones with positive damage
|
||||
//-----------------------------------------------------------------------------
|
||||
bool IsTakingTriggerHurtDamageAtPoint( const Vector &vecPoint )
|
||||
{
|
||||
for ( int i = 0; i < ITriggerHurtAutoList::AutoList().Count(); i++ )
|
||||
{
|
||||
// Some maps use trigger_hurt with negative values as healing triggers; don't consider those
|
||||
CTriggerHurt *pTrigger = static_cast<CTriggerHurt*>( ITriggerHurtAutoList::AutoList()[i] );
|
||||
if ( !pTrigger->m_bDisabled && pTrigger->PointIsWithin( vecPoint ) && pTrigger->m_flDamage > 0.f )
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
// ##################################################################################
|
||||
// >> TriggerMultiple
|
||||
@@ -2310,8 +2343,8 @@ class CTriggerTeleport : public CBaseTrigger
|
||||
public:
|
||||
DECLARE_CLASS( CTriggerTeleport, CBaseTrigger );
|
||||
|
||||
void Spawn( void );
|
||||
void Touch( CBaseEntity *pOther );
|
||||
virtual void Spawn( void ) OVERRIDE;
|
||||
virtual void Touch( CBaseEntity *pOther ) OVERRIDE;
|
||||
|
||||
string_t m_iLandmark;
|
||||
|
||||
@@ -2326,14 +2359,11 @@ BEGIN_DATADESC( CTriggerTeleport )
|
||||
|
||||
END_DATADESC()
|
||||
|
||||
|
||||
|
||||
void CTriggerTeleport::Spawn( void )
|
||||
{
|
||||
InitTrigger();
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Teleports the entity that touched us to the location of our target,
|
||||
// setting the toucher's angles to our target's angles if they are a
|
||||
@@ -2415,6 +2445,46 @@ void CTriggerTeleport::Touch( CBaseEntity *pOther )
|
||||
LINK_ENTITY_TO_CLASS( info_teleport_destination, CPointEntity );
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Teleport Relative trigger
|
||||
//-----------------------------------------------------------------------------
|
||||
class CTriggerTeleportRelative : public CBaseTrigger
|
||||
{
|
||||
public:
|
||||
DECLARE_CLASS(CTriggerTeleportRelative, CBaseTrigger);
|
||||
|
||||
virtual void Spawn( void ) OVERRIDE;
|
||||
virtual void Touch( CBaseEntity *pOther ) OVERRIDE;
|
||||
|
||||
Vector m_TeleportOffset;
|
||||
|
||||
DECLARE_DATADESC();
|
||||
};
|
||||
|
||||
LINK_ENTITY_TO_CLASS( trigger_teleport_relative, CTriggerTeleportRelative );
|
||||
BEGIN_DATADESC( CTriggerTeleportRelative )
|
||||
DEFINE_KEYFIELD( m_TeleportOffset, FIELD_VECTOR, "teleportoffset" )
|
||||
END_DATADESC()
|
||||
|
||||
|
||||
void CTriggerTeleportRelative::Spawn( void )
|
||||
{
|
||||
InitTrigger();
|
||||
}
|
||||
|
||||
void CTriggerTeleportRelative::Touch( CBaseEntity *pOther )
|
||||
{
|
||||
if ( !PassesTriggerFilters(pOther) )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
const Vector finalPos = m_TeleportOffset + WorldSpaceCenter();
|
||||
const Vector *momentum = &vec3_origin;
|
||||
|
||||
pOther->Teleport( &finalPos, NULL, momentum );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Saves the game when the player touches the trigger. Can be enabled or disabled
|
||||
//-----------------------------------------------------------------------------
|
||||
@@ -4822,6 +4892,78 @@ void CServerRagdollTrigger::EndTouch(CBaseEntity *pOther)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: A trigger that adds impulse to touching entities
|
||||
//-----------------------------------------------------------------------------
|
||||
class CTriggerApplyImpulse : public CBaseTrigger
|
||||
{
|
||||
public:
|
||||
DECLARE_CLASS( CTriggerApplyImpulse, CBaseTrigger );
|
||||
DECLARE_DATADESC();
|
||||
|
||||
CTriggerApplyImpulse();
|
||||
|
||||
void Spawn( void );
|
||||
|
||||
void InputApplyImpulse( inputdata_t& );
|
||||
|
||||
private:
|
||||
Vector m_vecImpulseDir;
|
||||
float m_flForce;
|
||||
};
|
||||
|
||||
|
||||
BEGIN_DATADESC( CTriggerApplyImpulse )
|
||||
DEFINE_KEYFIELD( m_vecImpulseDir, FIELD_VECTOR, "impulse_dir" ),
|
||||
DEFINE_KEYFIELD( m_flForce, FIELD_FLOAT, "force" ),
|
||||
DEFINE_INPUTFUNC( FIELD_VOID, "ApplyImpulse", InputApplyImpulse ),
|
||||
END_DATADESC()
|
||||
|
||||
|
||||
LINK_ENTITY_TO_CLASS( trigger_apply_impulse, CTriggerApplyImpulse );
|
||||
|
||||
|
||||
CTriggerApplyImpulse::CTriggerApplyImpulse()
|
||||
{
|
||||
m_flForce = 300.f;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void CTriggerApplyImpulse::Spawn()
|
||||
{
|
||||
// Convert pushdir from angles to a vector
|
||||
Vector vecAbsDir;
|
||||
QAngle angPushDir = QAngle(m_vecImpulseDir.x, m_vecImpulseDir.y, m_vecImpulseDir.z);
|
||||
AngleVectors(angPushDir, &vecAbsDir);
|
||||
|
||||
// Transform the vector into entity space
|
||||
VectorIRotate( vecAbsDir, EntityToWorldTransform(), m_vecImpulseDir );
|
||||
|
||||
BaseClass::Spawn();
|
||||
|
||||
InitTrigger();
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void CTriggerApplyImpulse::InputApplyImpulse( inputdata_t& )
|
||||
{
|
||||
Vector vecImpulse = m_flForce * m_vecImpulseDir;
|
||||
FOR_EACH_VEC( m_hTouchingEntities, i )
|
||||
{
|
||||
if ( m_hTouchingEntities[i] )
|
||||
{
|
||||
m_hTouchingEntities[i]->ApplyAbsVelocityImpulse( vecImpulse );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef HL1_DLL
|
||||
//----------------------------------------------------------------------------------
|
||||
// func_friction
|
||||
|
||||
@@ -68,6 +68,8 @@ public:
|
||||
virtual bool PassesTriggerFilters(CBaseEntity *pOther);
|
||||
virtual void StartTouch(CBaseEntity *pOther);
|
||||
virtual void EndTouch(CBaseEntity *pOther);
|
||||
virtual void StartTouchAll() {}
|
||||
virtual void EndTouchAll() {}
|
||||
bool IsTouching( CBaseEntity *pOther );
|
||||
|
||||
CBaseEntity *GetTouchedEntityOfType( const char *sClassName );
|
||||
@@ -164,7 +166,21 @@ protected:
|
||||
// Purpose: Hurts anything that touches it. If the trigger has a targetname,
|
||||
// firing it will toggle state.
|
||||
//-----------------------------------------------------------------------------
|
||||
class CTriggerHurt : public CBaseTrigger
|
||||
|
||||
// This class is to get around the fact that DEFINE_FUNCTION doesn't like multiple inheritance
|
||||
class CTriggerHurtShim : public CBaseTrigger
|
||||
{
|
||||
virtual void RadiationThink( void ) = 0;
|
||||
virtual void HurtThink( void ) = 0;
|
||||
|
||||
public:
|
||||
|
||||
void RadiationThinkShim( void ){ RadiationThink(); }
|
||||
void HurtThinkShim( void ){ HurtThink(); }
|
||||
};
|
||||
|
||||
DECLARE_AUTO_LIST( ITriggerHurtAutoList );
|
||||
class CTriggerHurt : public CTriggerHurtShim, public ITriggerHurtAutoList
|
||||
{
|
||||
public:
|
||||
CTriggerHurt()
|
||||
@@ -173,7 +189,7 @@ public:
|
||||
m_flDamageCap = 20.0f;
|
||||
}
|
||||
|
||||
DECLARE_CLASS( CTriggerHurt, CBaseTrigger );
|
||||
DECLARE_CLASS( CTriggerHurt, CTriggerHurtShim );
|
||||
|
||||
void Spawn( void );
|
||||
void RadiationThink( void );
|
||||
@@ -207,4 +223,6 @@ public:
|
||||
CUtlVector<EHANDLE> m_hurtEntities;
|
||||
};
|
||||
|
||||
bool IsTakingTriggerHurtDamageAtPoint( const Vector &vecPoint );
|
||||
|
||||
#endif // TRIGGERS_H
|
||||
|
||||
@@ -59,7 +59,7 @@ void DBG_AssertFunction( bool fExpr, const char *szExpr, const char *szFile, int
|
||||
Q_snprintf(szOut,sizeof(szOut), "ASSERT FAILED:\n %s \n(%s@%d)\n%s", szExpr, szFile, szLine, szMessage);
|
||||
else
|
||||
Q_snprintf(szOut,sizeof(szOut), "ASSERT FAILED:\n %s \n(%s@%d)\n", szExpr, szFile, szLine);
|
||||
Warning( szOut);
|
||||
Warning( "%s", szOut);
|
||||
}
|
||||
#endif // DEBUG
|
||||
|
||||
@@ -161,6 +161,11 @@ IServerNetworkable *CEntityFactoryDictionary::Create( const char *pClassName )
|
||||
IEntityFactory *pFactory = FindFactory( pClassName );
|
||||
if ( !pFactory )
|
||||
{
|
||||
#ifdef STAGING_ONLY
|
||||
static ConVarRef tf_bot_use_items( "tf_bot_use_items" );
|
||||
if ( tf_bot_use_items.IsValid() && tf_bot_use_items.GetInt() )
|
||||
return NULL;
|
||||
#endif
|
||||
Warning("Attempted to create unknown entity type %s!\n", pClassName );
|
||||
return NULL;
|
||||
}
|
||||
@@ -568,6 +573,24 @@ CBasePlayer *UTIL_PlayerByIndex( int playerIndex )
|
||||
return pPlayer;
|
||||
}
|
||||
|
||||
CBasePlayer *UTIL_PlayerBySteamID( const CSteamID &steamID )
|
||||
{
|
||||
CSteamID steamIDPlayer;
|
||||
for ( int i = 1; i <= gpGlobals->maxClients; i++ )
|
||||
{
|
||||
CBasePlayer *pPlayer = UTIL_PlayerByIndex( i );
|
||||
if ( !pPlayer )
|
||||
continue;
|
||||
|
||||
if ( !pPlayer->GetSteamID( &steamIDPlayer ) )
|
||||
continue;
|
||||
|
||||
if ( steamIDPlayer == steamID )
|
||||
return pPlayer;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
CBasePlayer* UTIL_PlayerByName( const char *name )
|
||||
{
|
||||
if ( !name || !name[0] )
|
||||
|
||||
@@ -222,6 +222,7 @@ float UTIL_GetSimulationInterval();
|
||||
// NOTENOTE: Use UTIL_GetLocalPlayer instead of UTIL_PlayerByIndex IF you're in single player
|
||||
// and you want the player.
|
||||
CBasePlayer *UTIL_PlayerByIndex( int playerIndex );
|
||||
CBasePlayer *UTIL_PlayerBySteamID( const CSteamID &steamID );
|
||||
|
||||
// NOTENOTE: Use this instead of UTIL_PlayerByIndex IF you're in single player
|
||||
// and you want the player.
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
|
||||
#ifdef TF_DLL
|
||||
#include "tf/tf_gamerules.h"
|
||||
#include "tf/tf_voteissues.h"
|
||||
#endif
|
||||
|
||||
// memdbgon must be the last include file in a .cpp file!!!
|
||||
@@ -38,15 +39,15 @@ LINK_ENTITY_TO_CLASS( vote_controller, CVoteController );
|
||||
|
||||
CVoteController *g_voteController = NULL;
|
||||
|
||||
ConVar sv_vote_timer_duration("sv_vote_timer_duration", "15", FCVAR_DEVELOPMENTONLY, "How long to allow voting on an issue");
|
||||
ConVar sv_vote_command_delay("sv_vote_command_delay", "2", FCVAR_DEVELOPMENTONLY, "How long after a vote passes until the action happens", false, 0, true, 4.5);
|
||||
ConVar sv_allow_votes("sv_allow_votes", "1", FCVAR_NONE, "Allow voting?");
|
||||
ConVar sv_vote_timer_duration( "sv_vote_timer_duration", "15", FCVAR_DEVELOPMENTONLY, "How long to allow voting on an issue" );
|
||||
ConVar sv_vote_command_delay( "sv_vote_command_delay", "2", FCVAR_DEVELOPMENTONLY, "How long after a vote passes until the action happens", false, 0.f, true, 4.5f );
|
||||
ConVar sv_allow_votes( "sv_allow_votes", "1", FCVAR_NONE, "Allow voting?" );
|
||||
ConVar sv_vote_failure_timer( "sv_vote_failure_timer", "300", FCVAR_NONE, "A vote that fails cannot be re-submitted for this long" );
|
||||
#ifdef TF_DLL
|
||||
ConVar sv_vote_failure_timer_mvm( "sv_vote_failure_timer_mvm", "120", FCVAR_NONE, "A vote that fails in MvM cannot be re-submitted for this long" );
|
||||
#endif // TF_DLL
|
||||
ConVar sv_vote_creation_timer("sv_vote_creation_timer", "120", FCVAR_DEVELOPMENTONLY, "How often someone can individually call a vote.");
|
||||
ConVar sv_vote_quorum_ratio( "sv_vote_quorum_ratio", "0.6", FCVAR_HIDDEN, "The minimum ratio of players needed to vote on an issue to resolve it.", true, 0.1, true, 1.0 );
|
||||
ConVar sv_vote_creation_timer( "sv_vote_creation_timer", "150", FCVAR_NONE, "How long before a player can attempt to call another vote (in seconds)." );
|
||||
ConVar sv_vote_quorum_ratio( "sv_vote_quorum_ratio", "0.6", FCVAR_NOTIFY, "The minimum ratio of eligible players needed to pass a vote. Min 0.5, Max 1.0.", true, 0.1f, true, 1.0f );
|
||||
ConVar sv_vote_allow_spectators( "sv_vote_allow_spectators", "0", FCVAR_NONE, "Allow spectators to vote?" );
|
||||
ConVar sv_vote_ui_hide_disabled_issues( "sv_vote_ui_hide_disabled_issues", "1", FCVAR_NONE, "Suppress listing of disabled issues in the vote setup screen." );
|
||||
|
||||
@@ -61,7 +62,9 @@ public:
|
||||
CVoteControllerSystem( char const *name ) : CAutoGameSystemPerFrame( name )
|
||||
{
|
||||
SetDefLessFunc( m_mapKickWatchList );
|
||||
SetDefLessFunc( m_mapNameLockedList );
|
||||
m_flNextKickCheckTime = 0.f;
|
||||
m_flNextNameLockCheckTime = 0.f;
|
||||
}
|
||||
|
||||
virtual void LevelInitPreEntity()
|
||||
@@ -93,24 +96,7 @@ public:
|
||||
break; // Constantly called code - resume on next pass
|
||||
}
|
||||
|
||||
CBasePlayer *pTarget = NULL;
|
||||
CSteamID steamIDPlayer;
|
||||
for ( int j = 1; j <= gpGlobals->maxClients; j++ )
|
||||
{
|
||||
CBasePlayer *pPlayer = UTIL_PlayerByIndex( j );
|
||||
if ( !pPlayer )
|
||||
continue;
|
||||
|
||||
if ( pPlayer->GetSteamID( &steamIDPlayer ) == false )
|
||||
continue;
|
||||
|
||||
if ( steamIDPlayer == m_mapKickWatchList.Key( i ) )
|
||||
{
|
||||
pTarget = pPlayer;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
CBasePlayer *pTarget = UTIL_PlayerBySteamID( m_mapKickWatchList.Key( i ) );
|
||||
if ( pTarget )
|
||||
{
|
||||
// Welcome back
|
||||
@@ -120,11 +106,44 @@ public:
|
||||
|
||||
m_flNextKickCheckTime = gpGlobals->curtime + 0.2f;
|
||||
}
|
||||
|
||||
// Name lock management
|
||||
if ( m_flNextNameLockCheckTime < gpGlobals->curtime )
|
||||
{
|
||||
FOR_EACH_MAP( m_mapNameLockedList, i )
|
||||
{
|
||||
CBasePlayer *pPlayer = UTIL_PlayerBySteamID( m_mapNameLockedList.Key( i ) );
|
||||
|
||||
// Time up?
|
||||
if ( gpGlobals->curtime > m_mapNameLockedList[i] )
|
||||
{
|
||||
// Disable the lock if they're still here
|
||||
if ( pPlayer )
|
||||
{
|
||||
engine->ServerCommand( UTIL_VarArgs( "namelockid %d %d\n", pPlayer->GetUserID(), 0 ) );
|
||||
}
|
||||
|
||||
// Remove and break - this will re-run in 1 second
|
||||
m_mapNameLockedList.RemoveAt( i );
|
||||
break;
|
||||
}
|
||||
// See if they reconnected
|
||||
else if ( pPlayer && !engine->IsPlayerNameLocked( pPlayer->edict() ) )
|
||||
{
|
||||
engine->ServerCommand( UTIL_VarArgs( "namelockid %d %d\n", pPlayer->GetUserID(), 1 ) );
|
||||
}
|
||||
}
|
||||
|
||||
m_flNextNameLockCheckTime = gpGlobals->curtime + 1.f;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void AddPlayerToKickWatchList( CSteamID steamID, float flDuration )
|
||||
{
|
||||
if ( !steamID.IsValid() || !steamID.BIndividualAccount() )
|
||||
return;
|
||||
|
||||
flDuration = clamp( flDuration, 1.f, (float)k_nKickWatchListMaxDuration );
|
||||
if ( m_mapKickWatchList.Find( steamID ) == m_mapKickWatchList.InvalidIndex() )
|
||||
{
|
||||
@@ -132,10 +151,24 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
void AddPlayerToNameLockedList( CSteamID steamID, float flDuration )
|
||||
{
|
||||
if ( !steamID.IsValid() || !steamID.BIndividualAccount() )
|
||||
return;
|
||||
|
||||
flDuration = clamp( flDuration, 1.f, (float)k_nKickWatchListMaxDuration );
|
||||
if ( m_mapNameLockedList.Find( steamID ) == m_mapNameLockedList.InvalidIndex() )
|
||||
{
|
||||
m_mapNameLockedList.Insert( steamID, ( gpGlobals->curtime + flDuration ) );
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
CUtlMap< CSteamID, float > m_mapKickWatchList;
|
||||
CUtlMap< CSteamID, float > m_mapNameLockedList;
|
||||
float m_flNextKickCheckTime;
|
||||
float m_flNextNameLockCheckTime;
|
||||
};
|
||||
|
||||
CVoteControllerSystem VoteControllerSystem( "CVoteControllerSystem" );
|
||||
@@ -185,7 +218,7 @@ CON_COMMAND( callvote, "Start a vote on an issue." )
|
||||
}
|
||||
|
||||
CBasePlayer *pVoteCaller = UTIL_GetCommandClient();
|
||||
if( !pVoteCaller )
|
||||
if ( !pVoteCaller )
|
||||
return;
|
||||
|
||||
if ( !sv_vote_allow_spectators.GetBool() )
|
||||
@@ -197,15 +230,21 @@ CON_COMMAND( callvote, "Start a vote on an issue." )
|
||||
}
|
||||
}
|
||||
|
||||
// Prevent spamming commands
|
||||
#ifndef _DEBUG
|
||||
int nCooldown = 0;
|
||||
if ( !g_voteController->CanEntityCallVote( pVoteCaller, nCooldown ) )
|
||||
if ( g_voteController->IsVoteActive() )
|
||||
{
|
||||
g_voteController->SendVoteCreationFailedMessage( VOTE_FAILED_RATE_EXCEEDED, pVoteCaller, nCooldown );
|
||||
ClientPrint( pVoteCaller, HUD_PRINTCENTER, "#GameUI_vote_failed_vote_in_progress" );
|
||||
return;
|
||||
}
|
||||
|
||||
// Ask the controller if this is allowed
|
||||
int nCooldown = 0;
|
||||
vote_create_failed_t nError = VOTE_FAILED_GENERIC;
|
||||
|
||||
if ( !g_voteController->CanEntityCallVote( pVoteCaller, nCooldown, nError ) )
|
||||
{
|
||||
g_voteController->SendVoteCreationFailedMessage( nError, pVoteCaller, nCooldown );
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
// Parameters
|
||||
char szEmptyDetails[MAX_VOTE_DETAILS_LENGTH];
|
||||
@@ -214,7 +253,7 @@ CON_COMMAND( callvote, "Start a vote on an issue." )
|
||||
const char *arg3 = args.ArgC() >= 3 ? args[2] : szEmptyDetails;
|
||||
|
||||
// If we don't have any arguments, invoke VoteSetup UI
|
||||
if( args.ArgC() < 2 )
|
||||
if ( args.ArgC() < 2 )
|
||||
{
|
||||
g_voteController->SetupVote( pVoteCaller->entindex() );
|
||||
return;
|
||||
@@ -252,7 +291,7 @@ void CVoteController::ResetData( void )
|
||||
m_acceptingVotesTimer.Invalidate();
|
||||
m_executeCommandTimer.Invalidate();
|
||||
m_iEntityHoldingVote = -1;
|
||||
m_iOnlyTeamToVote = TEAM_INVALID;
|
||||
m_iOnlyTeamToVote = TEAM_UNASSIGNED;
|
||||
m_bIsYesNoVote = true;
|
||||
|
||||
for( int voteIndex = 0; voteIndex < ARRAYSIZE( m_nVotesCast ); ++voteIndex )
|
||||
@@ -287,12 +326,25 @@ int CVoteController::UpdateTransmitState( void )
|
||||
return SetTransmitState( FL_EDICT_ALWAYS );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
bool CVoteController::IsVoteSystemEnabled( void )
|
||||
{
|
||||
#ifdef TF_DLL
|
||||
if ( TFGameRules() && TFGameRules()->IsCompetitiveMode() )
|
||||
return false;
|
||||
#endif // TF_DLL
|
||||
|
||||
return sv_allow_votes.GetBool();
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
bool CVoteController::CanTeamCastVote( int iTeam ) const
|
||||
{
|
||||
if ( m_iOnlyTeamToVote == TEAM_INVALID )
|
||||
if ( m_iOnlyTeamToVote == TEAM_UNASSIGNED )
|
||||
return true;
|
||||
|
||||
return iTeam == m_iOnlyTeamToVote;
|
||||
@@ -310,7 +362,7 @@ bool CVoteController::SetupVote( int iEntIndex )
|
||||
int nIssueCount = 0;
|
||||
|
||||
// Passing an nIssueCount of 0 triggers a "Voting disabled on server" message in the setup UI
|
||||
if ( sv_allow_votes.GetBool() )
|
||||
if ( IsVoteSystemEnabled() )
|
||||
{
|
||||
for( int iIndex = 0; iIndex < m_potentialIssues.Count(); ++iIndex )
|
||||
{
|
||||
@@ -330,28 +382,28 @@ bool CVoteController::SetupVote( int iEntIndex )
|
||||
filter.MakeReliable();
|
||||
UserMessageBegin( filter, "VoteSetup" );
|
||||
WRITE_BYTE( nIssueCount );
|
||||
int nMsgSize = 0;
|
||||
|
||||
for( int iIndex = 0; iIndex < m_potentialIssues.Count(); ++iIndex )
|
||||
{
|
||||
CBaseIssue *pCurrentIssue = m_potentialIssues[iIndex];
|
||||
if ( pCurrentIssue )
|
||||
{
|
||||
if ( pCurrentIssue->IsEnabled() )
|
||||
{
|
||||
WRITE_STRING( pCurrentIssue->GetTypeString() );
|
||||
}
|
||||
else
|
||||
{
|
||||
// Don't send/display disabled issues when set
|
||||
if ( sv_vote_ui_hide_disabled_issues.GetBool() )
|
||||
continue;
|
||||
// Don't send/display disabled issues when set
|
||||
if ( !pCurrentIssue->IsEnabled() && sv_vote_ui_hide_disabled_issues.GetBool() )
|
||||
continue;
|
||||
|
||||
char szDisabledIssueStr[MAX_COMMAND_LENGTH + 12];
|
||||
V_strcpy( szDisabledIssueStr, pCurrentIssue->GetTypeString() );
|
||||
V_strcat( szDisabledIssueStr, " (Disabled on Server)", sizeof(szDisabledIssueStr) );
|
||||
// Don't exceed MAX_USER_MSG_DATA (hack)
|
||||
nMsgSize += ( V_strlen( pCurrentIssue->GetTypeString() ) + 1 );
|
||||
nMsgSize += ( V_strlen( pCurrentIssue->GetTypeStringLocalized() ) + 1 );
|
||||
++nMsgSize;
|
||||
Assert( nMsgSize <= MAX_USER_MSG_DATA );
|
||||
if ( nMsgSize > MAX_USER_MSG_DATA )
|
||||
continue;
|
||||
|
||||
WRITE_STRING( szDisabledIssueStr );
|
||||
}
|
||||
WRITE_STRING( pCurrentIssue->GetTypeString() );
|
||||
WRITE_STRING( pCurrentIssue->GetTypeStringLocalized() );
|
||||
WRITE_BYTE( pCurrentIssue->IsEnabled() );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -368,29 +420,29 @@ bool CVoteController::CreateVote( int iEntIndex, const char *pszTypeString, cons
|
||||
// Terrible Hack: Dedicated servers pass 99 as the EntIndex
|
||||
bool bDedicatedServer = ( iEntIndex == DEDICATED_SERVER ) ? true : false;
|
||||
|
||||
if( !sv_allow_votes.GetBool() )
|
||||
if ( !IsVoteSystemEnabled() )
|
||||
return false;
|
||||
|
||||
// Already running a vote?
|
||||
if( IsVoteActive() )
|
||||
if ( IsVoteActive() )
|
||||
return false;
|
||||
|
||||
CBasePlayer *pVoteCaller = UTIL_PlayerByIndex( iEntIndex );
|
||||
if( !pVoteCaller && !bDedicatedServer )
|
||||
if ( !pVoteCaller && !bDedicatedServer )
|
||||
return false;
|
||||
|
||||
// Find the issue the user is asking for
|
||||
for( int issueIndex = 0; issueIndex < m_potentialIssues.Count(); ++issueIndex )
|
||||
for ( int issueIndex = 0; issueIndex < m_potentialIssues.Count(); ++issueIndex )
|
||||
{
|
||||
CBaseIssue *pCurrentIssue = m_potentialIssues[issueIndex];
|
||||
if ( !pCurrentIssue )
|
||||
return false;
|
||||
|
||||
if( FStrEq( pszTypeString, pCurrentIssue->GetTypeString() ) )
|
||||
if ( FStrEq( pszTypeString, pCurrentIssue->GetTypeString() ) )
|
||||
{
|
||||
vote_create_failed_t nErrorCode = VOTE_FAILED_GENERIC;
|
||||
int nTime = 0;
|
||||
if( pCurrentIssue->CanCallVote( iEntIndex, pszDetailString, nErrorCode, nTime ) )
|
||||
if ( pCurrentIssue->CanCallVote( iEntIndex, pszDetailString, nErrorCode, nTime ) )
|
||||
{
|
||||
// Establish a bunch of data on this particular issue
|
||||
pCurrentIssue->SetIssueDetails( pszDetailString );
|
||||
@@ -399,14 +451,7 @@ bool CVoteController::CreateVote( int iEntIndex, const char *pszTypeString, cons
|
||||
m_iEntityHoldingVote = iEntIndex;
|
||||
if ( !bDedicatedServer )
|
||||
{
|
||||
if( pCurrentIssue->IsAllyRestrictedVote() )
|
||||
{
|
||||
m_iOnlyTeamToVote = GetVoterTeam( pVoteCaller );
|
||||
}
|
||||
else
|
||||
{
|
||||
m_iOnlyTeamToVote = TEAM_INVALID;
|
||||
}
|
||||
m_iOnlyTeamToVote = ( pCurrentIssue->IsTeamRestrictedVote() ) ? GetVoterTeam( pVoteCaller ) : TEAM_UNASSIGNED;
|
||||
}
|
||||
|
||||
// Now get our choices
|
||||
@@ -442,10 +487,10 @@ bool CVoteController::CreateVote( int iEntIndex, const char *pszTypeString, cons
|
||||
|
||||
// Now the vote handling and UI
|
||||
m_nPotentialVotes = pCurrentIssue->CountPotentialVoters();
|
||||
m_acceptingVotesTimer.Start( sv_vote_timer_duration.GetFloat() );
|
||||
m_acceptingVotesTimer.Start( sv_vote_timer_duration.GetFloat() + random->RandomFloat( -1.f, 1.f ) );
|
||||
|
||||
// Force the vote holder to agree with a Yes/No vote
|
||||
if ( m_bIsYesNoVote && !bDedicatedServer )
|
||||
if ( pCurrentIssue->IsYesNoVote() && !bDedicatedServer )
|
||||
{
|
||||
TryCastVote( iEntIndex, "Option1" );
|
||||
}
|
||||
@@ -458,7 +503,7 @@ bool CVoteController::CreateVote( int iEntIndex, const char *pszTypeString, cons
|
||||
WRITE_BYTE( m_iEntityHoldingVote );
|
||||
WRITE_STRING( pCurrentIssue->GetDisplayString() );
|
||||
WRITE_STRING( pCurrentIssue->GetDetailsString() );
|
||||
WRITE_BOOL( m_bIsYesNoVote );
|
||||
WRITE_BOOL( pCurrentIssue->IsYesNoVote() );
|
||||
MessageEnd();
|
||||
|
||||
if ( !bDedicatedServer )
|
||||
@@ -506,11 +551,7 @@ void CVoteController::SendVoteFailedToPassMessage( vote_create_failed_t nReason
|
||||
{
|
||||
Assert( m_potentialIssues[m_iActiveIssueIndex] );
|
||||
|
||||
// See if we have a player target.
|
||||
CBasePlayer *pVoteTarget = m_potentialIssues[m_iActiveIssueIndex]->m_hPlayerTarget;
|
||||
bool bFakeClient = ( pVoteTarget && ( pVoteTarget->IsFakeClient() || pVoteTarget->IsHLTV() || pVoteTarget->IsReplay() ) );
|
||||
|
||||
UTIL_LogPrintf( "Vote failed \"%s %s\" with code %i (proxy: %i) \n", m_potentialIssues[m_iActiveIssueIndex]->GetTypeString(), m_potentialIssues[m_iActiveIssueIndex]->GetDetailsString(), (int)nReason, bFakeClient );
|
||||
UTIL_LogPrintf( "Vote failed \"%s %s\" with code %i\n", m_potentialIssues[m_iActiveIssueIndex]->GetTypeString(), m_potentialIssues[m_iActiveIssueIndex]->GetDetailsString(), (int)nReason );
|
||||
|
||||
CBroadcastRecipientFilter filter;
|
||||
filter.MakeReliable();
|
||||
@@ -526,24 +567,24 @@ void CVoteController::SendVoteFailedToPassMessage( vote_create_failed_t nReason
|
||||
//-----------------------------------------------------------------------------
|
||||
CVoteController::TryCastVoteResult CVoteController::TryCastVote( int iEntIndex, const char *pszVoteString )
|
||||
{
|
||||
if( !sv_allow_votes.GetBool() )
|
||||
if ( !IsVoteSystemEnabled() )
|
||||
return CAST_FAIL_SERVER_DISABLE;
|
||||
|
||||
if( iEntIndex >= ARRAYSIZE( m_nVotesCast ) )
|
||||
if ( iEntIndex >= ARRAYSIZE( m_nVotesCast ) )
|
||||
return CAST_FAIL_SYSTEM_ERROR;
|
||||
|
||||
if( !IsVoteActive() )
|
||||
if ( !IsVoteActive() )
|
||||
return CAST_FAIL_NO_ACTIVE_ISSUE;
|
||||
|
||||
if( m_executeCommandTimer.HasStarted() )
|
||||
if ( m_executeCommandTimer.HasStarted() )
|
||||
return CAST_FAIL_VOTE_CLOSED;
|
||||
|
||||
if( m_potentialIssues[m_iActiveIssueIndex] && m_potentialIssues[m_iActiveIssueIndex]->IsAllyRestrictedVote() )
|
||||
if ( m_potentialIssues[m_iActiveIssueIndex] && m_potentialIssues[m_iActiveIssueIndex]->IsTeamRestrictedVote() )
|
||||
{
|
||||
CBaseEntity *pVoteHolder = UTIL_EntityByIndex( m_iEntityHoldingVote );
|
||||
CBaseEntity *pVoter = UTIL_EntityByIndex( iEntIndex );
|
||||
|
||||
if( ( pVoteHolder == NULL ) || ( pVoter == NULL ) || ( GetVoterTeam( pVoteHolder ) != GetVoterTeam( pVoter ) ) )
|
||||
if ( ( pVoteHolder == NULL ) || ( pVoter == NULL ) || ( GetVoterTeam( pVoteHolder ) != GetVoterTeam( pVoter ) ) )
|
||||
{
|
||||
return CAST_FAIL_TEAM_RESTRICTED;
|
||||
}
|
||||
@@ -552,7 +593,7 @@ CVoteController::TryCastVoteResult CVoteController::TryCastVote( int iEntIndex,
|
||||
// Look for a previous vote
|
||||
int nOldVote = m_nVotesCast[iEntIndex];
|
||||
#ifndef DEBUG
|
||||
if( nOldVote != VOTE_UNCAST )
|
||||
if ( nOldVote != VOTE_UNCAST )
|
||||
{
|
||||
return CAST_FAIL_NO_CHANGES;
|
||||
}
|
||||
@@ -644,67 +685,54 @@ void CVoteController::VoteControllerThink( void )
|
||||
}
|
||||
|
||||
// Vote time is up - process the result
|
||||
if( m_acceptingVotesTimer.HasStarted() && m_acceptingVotesTimer.IsElapsed() )
|
||||
if ( m_acceptingVotesTimer.HasStarted() && m_acceptingVotesTimer.IsElapsed() )
|
||||
{
|
||||
m_acceptingVotesTimer.Invalidate();
|
||||
|
||||
int nVoteTally = 0;
|
||||
for ( int index = 0; index < MAX_VOTE_OPTIONS; index++ )
|
||||
{
|
||||
nVoteTally += m_nVoteOptionCount.Get( index );
|
||||
}
|
||||
|
||||
bool bVotePassed = true;
|
||||
|
||||
// for record-keeping
|
||||
// For GC record-keeping
|
||||
if ( m_potentialIssues[m_iActiveIssueIndex]->IsYesNoVote() )
|
||||
{
|
||||
m_potentialIssues[m_iActiveIssueIndex]->SetYesNoVoteCount( m_nVoteOptionCount[VOTE_OPTION1], m_nVoteOptionCount[VOTE_OPTION2], m_nPotentialVotes );
|
||||
}
|
||||
|
||||
// Have we exceeded the required ratio of Voted-vs-Abstained?
|
||||
if ( nVoteTally >= m_nPotentialVotes * sv_vote_quorum_ratio.GetFloat() )
|
||||
{
|
||||
int nWinningVoteOption = GetWinningVoteOption();
|
||||
Assert( nWinningVoteOption >= 0 && nWinningVoteOption < m_VoteOptions.Count() );
|
||||
bool bVotePassed = false;
|
||||
|
||||
if ( nWinningVoteOption >= 0 && nWinningVoteOption < MAX_VOTE_OPTIONS )
|
||||
if ( GetNumVotesCast() >= ( m_nPotentialVotes * m_potentialIssues[m_iActiveIssueIndex]->GetQuorumRatio() ) )
|
||||
{
|
||||
int nPassingVoteOptionIndex = GetVoteIssueIndexWithHighestCount();
|
||||
if ( nPassingVoteOptionIndex >= 0 && nPassingVoteOptionIndex < MAX_VOTE_OPTIONS )
|
||||
{
|
||||
// YES/NO VOTES
|
||||
// YES/NO VOTES - hard-wired to VOTE_OPTION1 (Yes)
|
||||
if ( m_potentialIssues[m_iActiveIssueIndex]->IsYesNoVote() )
|
||||
{
|
||||
// Option1 is Yes
|
||||
if ( nWinningVoteOption != VOTE_OPTION1 )
|
||||
if ( nPassingVoteOptionIndex == VOTE_OPTION1 )
|
||||
{
|
||||
SendVoteFailedToPassMessage( VOTE_FAILED_YES_MUST_EXCEED_NO );
|
||||
bVotePassed = false;
|
||||
}
|
||||
bVotePassed = true;
|
||||
}
|
||||
}
|
||||
// GENERAL VOTES:
|
||||
// We set the details string after the vote, since that's when
|
||||
// we finally have a parameter to pass along and execute
|
||||
else if ( nWinningVoteOption < m_VoteOptions.Count() )
|
||||
// GENERAL VOTES - as long as there's a quorum, go with the most popular choice
|
||||
else
|
||||
{
|
||||
m_potentialIssues[m_iActiveIssueIndex]->SetIssueDetails( m_VoteOptions[nWinningVoteOption] );
|
||||
bVotePassed = true;
|
||||
|
||||
// We set the details string after the vote, since that's when
|
||||
// we finally have a parameter to pass along and execute
|
||||
m_potentialIssues[m_iActiveIssueIndex]->SetIssueDetails( m_VoteOptions[nPassingVoteOptionIndex] );
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
SendVoteFailedToPassMessage( VOTE_FAILED_QUORUM_FAILURE );
|
||||
bVotePassed = false;
|
||||
}
|
||||
|
||||
if ( bVotePassed )
|
||||
if ( bVotePassed )
|
||||
{
|
||||
m_executeCommandTimer.Start( sv_vote_command_delay.GetFloat() );
|
||||
m_resetVoteTimer.Start( 5.0 );
|
||||
|
||||
// Target is not always a player (changelevel, etc)
|
||||
// Always NULL check, as some votes don't target players (i.e. ChangeLevel)
|
||||
CBasePlayer *pVoteTarget = m_potentialIssues[m_iActiveIssueIndex]->m_hPlayerTarget;
|
||||
bool bFakeClient = ( pVoteTarget && ( pVoteTarget->IsFakeClient() || pVoteTarget->IsHLTV() || pVoteTarget->IsReplay() ) );
|
||||
|
||||
UTIL_LogPrintf( "Vote succeeded \"%s %s\" (proxy: %i) \n", m_potentialIssues[m_iActiveIssueIndex]->GetTypeString(), m_potentialIssues[m_iActiveIssueIndex]->GetDetailsString(), bFakeClient );
|
||||
// Don't delay successful kick votes
|
||||
float flDelay = IsPlayerBeingKicked( pVoteTarget ) ? 0.f : sv_vote_command_delay.GetFloat();
|
||||
m_executeCommandTimer.Start( flDelay );
|
||||
m_resetVoteTimer.Start( 5.f );
|
||||
|
||||
UTIL_LogPrintf( "Vote succeeded \"%s %s\"\n", m_potentialIssues[m_iActiveIssueIndex]->GetTypeString(), m_potentialIssues[m_iActiveIssueIndex]->GetDetailsString() );
|
||||
|
||||
CBroadcastRecipientFilter filter;
|
||||
filter.MakeReliable();
|
||||
@@ -717,8 +745,10 @@ void CVoteController::VoteControllerThink( void )
|
||||
}
|
||||
else
|
||||
{
|
||||
vote_create_failed_t nReason = m_potentialIssues[m_iActiveIssueIndex]->IsYesNoVote() ? VOTE_FAILED_YES_MUST_EXCEED_NO : VOTE_FAILED_QUORUM_FAILURE;
|
||||
SendVoteFailedToPassMessage( nReason );
|
||||
m_potentialIssues[m_iActiveIssueIndex]->OnVoteFailed( m_iEntityHoldingVote );
|
||||
m_resetVoteTimer.Start( 5.0 );
|
||||
m_resetVoteTimer.Start( 5.f );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -768,12 +798,15 @@ void CVoteController::CheckForEarlyVoteClose( void )
|
||||
//-----------------------------------------------------------------------------
|
||||
bool CVoteController::IsValidVoter( CBasePlayer *pWhom )
|
||||
{
|
||||
if ( pWhom == NULL )
|
||||
if ( !pWhom )
|
||||
return false;
|
||||
|
||||
if ( !pWhom->IsConnected() )
|
||||
return false;
|
||||
|
||||
if ( pWhom->GetTeamNumber() == TEAM_UNASSIGNED )
|
||||
return false;
|
||||
|
||||
if ( !sv_vote_allow_spectators.GetBool() )
|
||||
{
|
||||
if ( pWhom->GetTeamNumber() == TEAM_SPECTATOR )
|
||||
@@ -818,7 +851,7 @@ void CVoteController::RegisterIssue( CBaseIssue *pszNewIssue )
|
||||
//-----------------------------------------------------------------------------
|
||||
void CVoteController::ListIssues( CBasePlayer *pForWhom )
|
||||
{
|
||||
if( !sv_allow_votes.GetBool() )
|
||||
if ( !IsVoteSystemEnabled() )
|
||||
return;
|
||||
|
||||
ClientPrint( pForWhom, HUD_PRINTCONSOLE, "---Vote commands---\n" );
|
||||
@@ -832,45 +865,34 @@ void CVoteController::ListIssues( CBasePlayer *pForWhom )
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
// Purpose: -1 when invalid
|
||||
//-----------------------------------------------------------------------------
|
||||
int CVoteController::GetWinningVoteOption( void )
|
||||
int CVoteController::GetVoteIssueIndexWithHighestCount( void )
|
||||
{
|
||||
if ( m_potentialIssues[m_iActiveIssueIndex]->IsYesNoVote() )
|
||||
int nMaxIndex = -1;
|
||||
|
||||
// Legacy Yes/No system
|
||||
if ( m_iActiveIssueIndex != INVALID_ISSUE && m_potentialIssues[m_iActiveIssueIndex]->IsYesNoVote() )
|
||||
{
|
||||
return ( m_nVoteOptionCount[VOTE_OPTION1] > m_nVoteOptionCount[VOTE_OPTION2] ) ? VOTE_OPTION1 : VOTE_OPTION2;
|
||||
}
|
||||
// Which option had the most votes?
|
||||
else
|
||||
{
|
||||
CUtlVector <int> pVoteCounts;
|
||||
int nMaxCount = 0;
|
||||
|
||||
// Which option had the most votes?
|
||||
// driller: Need to handle ties
|
||||
int nHighest = m_nVoteOptionCount[0];
|
||||
// TODO: Handle ties
|
||||
for ( int iIndex = 0; iIndex < m_nVoteOptionCount.Count(); iIndex ++ )
|
||||
{
|
||||
nHighest = ( ( nHighest < m_nVoteOptionCount[iIndex] ) ? m_nVoteOptionCount[iIndex] : nHighest );
|
||||
pVoteCounts.AddToTail( m_nVoteOptionCount[iIndex] );
|
||||
}
|
||||
|
||||
m_nHighestCountIndex = -1;
|
||||
for ( int iIndex = 0; iIndex < m_nVoteOptionCount.Count(); iIndex++ )
|
||||
{
|
||||
if ( m_nVoteOptionCount[iIndex] == nHighest )
|
||||
if ( m_nVoteOptionCount[iIndex] && m_nVoteOptionCount[iIndex] > nMaxCount )
|
||||
{
|
||||
m_nHighestCountIndex = iIndex;
|
||||
// henryg: break on first match, not last. this avoids a crash
|
||||
// if we are all tied at zero and we pick something beyond the
|
||||
// last vote option. this code really ought to ignore attempts
|
||||
// to tally votes for options beyond the last valid one!
|
||||
break;
|
||||
nMaxCount = m_nVoteOptionCount[iIndex];
|
||||
nMaxIndex = iIndex;
|
||||
}
|
||||
}
|
||||
|
||||
return m_nHighestCountIndex;
|
||||
}
|
||||
|
||||
return -1;
|
||||
return nMaxIndex;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
@@ -898,11 +920,12 @@ void CVoteController::TrackVoteCaller( CBasePlayer *pPlayer )
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Check the history of steamIDs that called votes and test against a timer
|
||||
//-----------------------------------------------------------------------------
|
||||
bool CVoteController::CanEntityCallVote( CBasePlayer *pPlayer, int &nCooldown )
|
||||
bool CVoteController::CanEntityCallVote( CBasePlayer *pPlayer, int &nCooldown, vote_create_failed_t &nErrorCode )
|
||||
{
|
||||
if ( !pPlayer )
|
||||
return false;
|
||||
|
||||
|
||||
#ifndef _DEBUG
|
||||
CSteamID steamID;
|
||||
pPlayer->GetSteamID( &steamID );
|
||||
|
||||
@@ -913,15 +936,34 @@ bool CVoteController::CanEntityCallVote( CBasePlayer *pPlayer, int &nCooldown )
|
||||
// Timer elapsed?
|
||||
nCooldown = (int)( m_VoteCallers[ iIdx ] - gpGlobals->curtime );
|
||||
if ( nCooldown > 0 )
|
||||
{
|
||||
nErrorCode = VOTE_FAILED_RATE_EXCEEDED;
|
||||
return false;
|
||||
}
|
||||
|
||||
// Expired
|
||||
m_VoteCallers.Remove( iIdx );
|
||||
}
|
||||
#endif
|
||||
|
||||
return true;
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
int CVoteController::GetNumVotesCast( void )
|
||||
{
|
||||
int nVoteTally = 0;
|
||||
|
||||
for ( int index = 0; index < MAX_VOTE_OPTIONS; index++ )
|
||||
{
|
||||
nVoteTally += m_nVoteOptionCount.Get( index );
|
||||
}
|
||||
|
||||
return nVoteTally;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
@@ -930,12 +972,41 @@ void CVoteController::AddPlayerToKickWatchList( CSteamID steamID, float flDurati
|
||||
VoteControllerSystem.AddPlayerToKickWatchList( steamID, flDuration );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void CVoteController::AddPlayerToNameLockedList( CSteamID steamID, float flDuration, int nUserID )
|
||||
{
|
||||
engine->ServerCommand( UTIL_VarArgs( "namelockid %d %d\n", nUserID, 1 ) );
|
||||
|
||||
VoteControllerSystem.AddPlayerToNameLockedList( steamID, flDuration );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
bool CVoteController::IsPlayerBeingKicked( CBasePlayer *pPlayer )
|
||||
{
|
||||
#ifdef TF_DLL
|
||||
if ( pPlayer && m_iActiveIssueIndex != INVALID_ISSUE )
|
||||
{
|
||||
CKickIssue *pKickIssue = dynamic_cast< CKickIssue* >( m_potentialIssues[m_iActiveIssueIndex] );
|
||||
if ( pKickIssue )
|
||||
{
|
||||
return pKickIssue->m_hPlayerTarget == pPlayer;
|
||||
}
|
||||
}
|
||||
#endif // TF_DLL
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: BaseIssue
|
||||
//-----------------------------------------------------------------------------
|
||||
CBaseIssue::CBaseIssue( const char *pszTypeString )
|
||||
{
|
||||
Q_strcpy( m_szTypeString, pszTypeString );
|
||||
V_strcpy_safe( m_szTypeString, pszTypeString );
|
||||
|
||||
m_iNumYesVotes = 0;
|
||||
m_iNumNoVotes = 0;
|
||||
@@ -979,13 +1050,13 @@ const char *CBaseIssue::GetDetailsString( void )
|
||||
//-----------------------------------------------------------------------------
|
||||
void CBaseIssue::SetIssueDetails( const char *pszDetails )
|
||||
{
|
||||
Q_strcpy( m_szDetailsString, pszDetails );
|
||||
V_strcpy_safe( m_szDetailsString, pszDetails );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
bool CBaseIssue::IsAllyRestrictedVote( void )
|
||||
bool CBaseIssue::IsTeamRestrictedVote( void )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
@@ -1030,7 +1101,7 @@ void CBaseIssue::OnVoteFailed( int iEntityHoldingVote )
|
||||
// Need to create a new one
|
||||
FailedVote *pNewFailedVote = new FailedVote;
|
||||
int iIndex = m_FailedVotes.AddToTail( pNewFailedVote );
|
||||
Q_strcpy( m_FailedVotes[iIndex]->szFailedVoteParameter, GetDetailsString() );
|
||||
V_strcpy_safe( m_FailedVotes[iIndex]->szFailedVoteParameter, GetDetailsString() );
|
||||
m_FailedVotes[iIndex]->flLockoutTime = gpGlobals->curtime + sv_vote_failure_timer.GetFloat();
|
||||
}
|
||||
}
|
||||
@@ -1184,4 +1255,12 @@ bool CBaseIssue::GetVoteOptions( CUtlVector <const char*> &vecNames )
|
||||
return true;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
float CBaseIssue::GetQuorumRatio( void )
|
||||
{
|
||||
return sv_vote_quorum_ratio.GetFloat();
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -20,17 +20,18 @@
|
||||
class CBaseIssue // Base class concept for vote issues (i.e. Kick Player). Created per level-load and destroyed by CVoteController's dtor.
|
||||
{
|
||||
public:
|
||||
CBaseIssue(const char *typeString);
|
||||
virtual ~CBaseIssue();
|
||||
CBaseIssue( const char *typeString );
|
||||
virtual ~CBaseIssue();
|
||||
const char *GetTypeString( void ); // Connection between console command and specific type of issue
|
||||
virtual const char *GetDetailsString();
|
||||
virtual const char *GetTypeStringLocalized( void ) { return ""; } // When empty, the client uses the classname string and prepends "#Vote_"
|
||||
virtual const char *GetDetailsString( void );
|
||||
virtual void SetIssueDetails( const char *pszDetails ); // We need to know the details part of the con command for later
|
||||
virtual void OnVoteFailed( int iEntityHoldingVote ); // The moment the vote fails, also has some time for feedback before the window goes away
|
||||
virtual void OnVoteStarted( void ) {} // Called as soon as the vote starts
|
||||
virtual bool IsEnabled( void ) { return false; } // Query the issue to see if it's enabled
|
||||
virtual bool CanTeamCallVote( int iTeam ) const; // Can someone on the given team call this vote?
|
||||
virtual bool CanCallVote( int nEntIndex, const char *pszDetails, vote_create_failed_t &nFailCode, int &nTime ); // Can this guy hold a vote on this issue?
|
||||
virtual bool IsAllyRestrictedVote( void ); // Can only members of the same team vote on this?
|
||||
virtual bool IsTeamRestrictedVote( void ); // Restrict access and visibility of this vote to a specific team?
|
||||
virtual const char *GetDisplayString( void ) = 0; // The string that will be passed to the client for display
|
||||
virtual void ExecuteCommand( void ) = 0; // Where the magic happens. Do your thing.
|
||||
virtual void ListIssueDetails( CBasePlayer *pForWhom ) = 0; // Someone would like to know all your valid details
|
||||
@@ -42,6 +43,7 @@ public:
|
||||
virtual bool GetVoteOptions( CUtlVector <const char*> &vecNames ); // We use this to generate options for voting
|
||||
virtual bool BRecordVoteFailureEventForEntity( int iVoteCallingEntityIndex ) const { return iVoteCallingEntityIndex != DEDICATED_SERVER; }
|
||||
void SetIssueCooldownDuration( float flDuration ) { m_flNextCallTime = gpGlobals->curtime + flDuration; } // The issue can not be raised again for this period of time (in seconds)
|
||||
virtual float GetQuorumRatio( void ); // Each issue can decide the required ratio of voted-vs-abstained
|
||||
|
||||
CHandle< CBasePlayer > m_hPlayerTarget; // If the target of the issue is a player, we should store them here
|
||||
|
||||
@@ -54,11 +56,9 @@ protected:
|
||||
float flLockoutTime;
|
||||
};
|
||||
|
||||
CUtlVector<FailedVote *> m_FailedVotes;
|
||||
|
||||
char m_szTypeString[MAX_COMMAND_LENGTH];
|
||||
char m_szDetailsString[MAX_VOTE_DETAILS_LENGTH];
|
||||
|
||||
CUtlVector< FailedVote* > m_FailedVotes;
|
||||
char m_szTypeString[MAX_COMMAND_LENGTH];
|
||||
char m_szDetailsString[MAX_VOTE_DETAILS_LENGTH];
|
||||
int m_iNumYesVotes;
|
||||
int m_iNumNoVotes;
|
||||
int m_iNumPotentialVotes;
|
||||
@@ -89,6 +89,7 @@ public:
|
||||
|
||||
virtual void Spawn( void );
|
||||
virtual int UpdateTransmitState( void );
|
||||
virtual bool IsVoteSystemEnabled( void );
|
||||
|
||||
bool SetupVote( int iEntIndex ); // This creates a list of issues for the UI
|
||||
bool CreateVote( int iEntIndex, const char *pszTypeString, const char *pszDetailString ); // This is what the UI passes in
|
||||
@@ -101,12 +102,15 @@ public:
|
||||
void SendVoteFailedToPassMessage( vote_create_failed_t nReason );
|
||||
void VoteChoice_Increment( int nVoteChoice );
|
||||
void VoteChoice_Decrement( int nVoteChoice );
|
||||
int GetWinningVoteOption( void );
|
||||
int GetVoteIssueIndexWithHighestCount( void );
|
||||
void TrackVoteCaller( CBasePlayer *pPlayer );
|
||||
bool CanEntityCallVote( CBasePlayer *pPlayer, int &nCooldown );
|
||||
bool CanEntityCallVote( CBasePlayer *pPlayer, int &nCooldown, vote_create_failed_t &nErrorCode );
|
||||
bool IsVoteActive( void ) { return m_iActiveIssueIndex != INVALID_ISSUE; }
|
||||
int GetNumVotesCast( void );
|
||||
|
||||
void AddPlayerToKickWatchList( CSteamID steamID, float flDuration );
|
||||
void AddPlayerToKickWatchList( CSteamID steamID, float flDuration ); // Band-aid until we figure out how player's avoid kick votes
|
||||
void AddPlayerToNameLockedList( CSteamID steamID, float flDuration, int nUserID );
|
||||
bool IsPlayerBeingKicked( CBasePlayer *pPlayer );
|
||||
|
||||
protected:
|
||||
void ResetData( void );
|
||||
@@ -123,7 +127,6 @@ protected:
|
||||
CountdownTimer m_resetVoteTimer; // when the current vote will end
|
||||
int m_nVotesCast[MAX_PLAYERS + 1]; // arrays are zero-based and player indices are one-based
|
||||
int m_iEntityHoldingVote;
|
||||
int m_nHighestCountIndex;
|
||||
|
||||
CUtlVector <CBaseIssue *> m_potentialIssues;
|
||||
CUtlVector <const char *> m_VoteOptions;
|
||||
|
||||
Reference in New Issue
Block a user