Updated the SDK with the latest code from the TF and HL2 branches

* Adds support for Visual Studio 2012 and 2013
* VR Mode:
. Switches from headtrack.dll to sourcevr.dll
. Improved readability of the UI in VR
. Removed the IPD calibration tool. TF2 will now obey the Oculus
configuration file. Use the Oculus calibration tool in your SDK or
install and run "OpenVR" under Tools in Steam to calibrate your IPD.
. Added dropdown to enable VR mode in the Video options. Removed the -vr
command line option.
. Added the ability to switch in and out of VR mode without quitting the
game
. By default VR mode will run full screen. To switch back to a
borderless window set the vr_force_windowed convar.
. Added support for VR mode on Linux
* Many assorted bug fixes and other changes from Team Fortress in
various shared files
This commit is contained in:
Joe Ludwig
2013-12-03 08:54:16 -08:00
parent 2861c3fbfc
commit beaae8ac45
424 changed files with 11412 additions and 11273 deletions

View File

@@ -2153,4 +2153,8 @@ void CAI_BaseNPC::InitDefaultActivitySR(void)
ADD_ACTIVITY_TO_SR( ACT_THROWABLE_VM_IDLE );
ADD_ACTIVITY_TO_SR( ACT_THROWABLE_VM_FIRE );
ADD_ACTIVITY_TO_SR( ACT_SPELL_VM_DRAW );
ADD_ACTIVITY_TO_SR( ACT_SPELL_VM_IDLE );
ADD_ACTIVITY_TO_SR( ACT_SPELL_VM_ARM );
ADD_ACTIVITY_TO_SR( ACT_SPELL_VM_FIRE );
}

View File

@@ -15,7 +15,7 @@
//-----------------------------------------------------------------------------
inline float round( float f )
inline float V_round( float f )
{
return (float)( (int)( f + 0.5 ) );
}
@@ -133,7 +133,7 @@ bool CAI_MoveSolver::Solve( const AI_MoveSuggestion_t *pSuggestions, int nSugges
// Convert arc values to solution indices relative to right post. Right is angle down, left is angle up.
float halfSpan = current.arc.span * 0.5;
int center = round( ( halfSpan * NUM_SOLUTIONS ) / 360 );
int center = V_round( ( halfSpan * NUM_SOLUTIONS ) / 360 );
int left = ( current.arc.span * NUM_SOLUTIONS ) / 360;
float angRight = current.arc.center - halfSpan;

View File

@@ -983,7 +983,7 @@ bool CAI_NetworkManager::IsAIFileCurrent ( const char *szMapName )
Q_strncpy( szLoweredGameDir, pGameDir, sizeof( szLoweredGameDir ) );
Q_strlower( szLoweredGameDir );
if ( !V_stricmp( szLoweredGameDir, "hl2" ) || !V_stricmp( szLoweredGameDir, "episodic" ) || !V_stricmp( szLoweredGameDir, "ep2" ) || !V_stricmp( szLoweredGameDir, "portal" ) || !V_stricmp( szLoweredGameDir, "lostcoast" ) )
if ( !V_stricmp( szLoweredGameDir, "hl2" ) || !V_stricmp( szLoweredGameDir, "episodic" ) || !V_stricmp( szLoweredGameDir, "ep2" ) || !V_stricmp( szLoweredGameDir, "portal" ) || !V_stricmp( szLoweredGameDir, "lostcoast" ) || !V_stricmp( szLoweredGameDir, "hl1" ) )
{
// we shipped good node graphs for our games
return true;

View File

@@ -210,6 +210,9 @@ BEGIN_DATADESC( CBaseAnimating )
DEFINE_INPUT( m_fadeMaxDist, FIELD_FLOAT, "fademaxdist" ),
DEFINE_KEYFIELD( m_flFadeScale, FIELD_FLOAT, "fadescale" ),
DEFINE_KEYFIELD( m_flModelScale, FIELD_FLOAT, "modelscale" ),
DEFINE_INPUTFUNC( FIELD_VECTOR, "SetModelScale", InputSetModelScale ),
DEFINE_FIELD( m_fBoneCacheFlags, FIELD_SHORT ),
END_DATADESC()
@@ -441,7 +444,7 @@ void CBaseAnimating::StudioFrameAdvanceInternal( CStudioHdr *pStudioHdr, float f
m_flAnimTime.Get(), m_flPrevAnimTime, flInterval, GetCycle() );
*/
m_flGroundSpeed = GetSequenceGroundSpeed( pStudioHdr, GetSequence() );
m_flGroundSpeed = GetSequenceGroundSpeed( pStudioHdr, GetSequence() ) * GetModelScale();
// Msg("%s : %s : %5.1f\n", GetClassname(), GetSequenceName( GetSequence() ), GetCycle() );
InvalidatePhysicsRecursive( ANIMATION_CHANGED );
@@ -610,6 +613,17 @@ void CBaseAnimating::InputSetLightingOrigin( inputdata_t &inputdata )
SetLightingOrigin( strLightingOrigin );
}
//-----------------------------------------------------------------------------
// Purpose: SetModelScale input handler
//-----------------------------------------------------------------------------
void CBaseAnimating::InputSetModelScale( inputdata_t &inputdata )
{
Vector vecScale;
inputdata.value.Vector3D( vecScale );
SetModelScale( vecScale.x, vecScale.y );
}
//=========================================================
// SelectWeightedSequence
@@ -877,7 +891,7 @@ void CBaseAnimating::ResetSequenceInfo ( )
}
CStudioHdr *pStudioHdr = GetModelPtr();
m_flGroundSpeed = GetSequenceGroundSpeed( pStudioHdr, GetSequence() );
m_flGroundSpeed = GetSequenceGroundSpeed( pStudioHdr, GetSequence() ) * GetModelScale();
m_bSequenceLoops = ((GetSequenceFlags( pStudioHdr, GetSequence() ) & STUDIO_LOOPING) != 0);
// m_flAnimTime = gpGlobals->time;
m_flPlaybackRate = 1.0;

View File

@@ -338,6 +338,7 @@ private:
void StudioFrameAdvanceInternal( CStudioHdr *pStudioHdr, float flInterval );
void InputSetLightingOriginRelative( inputdata_t &inputdata );
void InputSetLightingOrigin( inputdata_t &inputdata );
void InputSetModelScale( inputdata_t &inputdata );
bool CanSkipAnimation( void );

View File

@@ -4524,6 +4524,17 @@ void CBaseEntity::Teleport( const Vector *newPosition, const QAngle *newAngles,
teleportList[i].pEntity->CollisionRulesChanged();
}
if ( IsPlayer() )
{
// Tell the client being teleported
IGameEvent *event = gameeventmanager->CreateEvent( "base_player_teleported" );
if ( event )
{
event->SetInt( "entindex", entindex() );
gameeventmanager->FireEventClientSide( event );
}
}
Assert( g_TeleportStack[index] == this );
g_TeleportStack.FastRemove( index );

View File

@@ -132,7 +132,15 @@ bool CBaseMultiplayerPlayer::CanHearAndReadChatFrom( CBasePlayer *pPlayer )
//-----------------------------------------------------------------------------
bool CBaseMultiplayerPlayer::ShouldRunRateLimitedCommand( const CCommand &args )
{
const char *pcmd = args[0];
return ShouldRunRateLimitedCommand( args[0] );
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
bool CBaseMultiplayerPlayer::ShouldRunRateLimitedCommand( const char *pszCommand )
{
const char *pcmd = pszCommand;
int i = m_RateLimitLastCommandTimes.Find( pcmd );
if ( i == m_RateLimitLastCommandTimes.InvalidIndex() )

View File

@@ -89,6 +89,7 @@ public:
// Command rate limiting.
bool ShouldRunRateLimitedCommand( const CCommand &args );
bool ShouldRunRateLimitedCommand( const char *pszCommand );
protected:
virtual CAI_Expresser *CreateExpresser( void );

View File

@@ -1,136 +0,0 @@
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
//=============================================================================
#include "cbase.h"
#include "baseprojectile.h"
BEGIN_DATADESC( CBaseProjectile )
DEFINE_FIELD( m_flDamage, FIELD_FLOAT ),
DEFINE_FIELD( m_iDamageType, FIELD_INTEGER ),
DEFINE_FIELD( m_flDamageScale, FIELD_FLOAT ),
DEFINE_FUNCTION( ProjectileTouch ),
DEFINE_THINKFUNC( FlyThink ),
END_DATADESC()
LINK_ENTITY_TO_CLASS( proj_base, CBaseProjectile );
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CBaseProjectile::Spawn( void )
{
Precache();
SetModel( STRING( GetModelName() ) );
SetSolid( SOLID_BBOX );
SetMoveType( MOVETYPE_FLYGRAVITY, MOVECOLLIDE_FLY_CUSTOM );
AddFlag( FL_OBJECT );
UTIL_SetSize( this, -Vector( 1.0f, 1.0f, 1.0f ), Vector( 1.0f, 1.0f, 1.0f ) );
// Setup attributes.
SetGravity( 0.001f );
m_takedamage = DAMAGE_NO;
// Setup the touch and think functions.
SetTouch( &CBaseProjectile::ProjectileTouch );
SetThink( &CBaseProjectile::FlyThink );
SetNextThink( gpGlobals->curtime );
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CBaseProjectile::Precache( void )
{
BaseClass::Precache();
PrecacheModel( STRING( GetModelName() ) );
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
CBaseProjectile *CBaseProjectile::Create( baseprojectilecreate_t &pCreate )
{
CBaseProjectile *pProjectile = static_cast<CBaseProjectile*>( CBaseEntity::CreateNoSpawn( "proj_base", pCreate.vecOrigin, vec3_angle, pCreate.pOwner ) );
if ( !pProjectile )
return NULL;
pProjectile->SetModelName( pCreate.iszModel );
pProjectile->SetDamage( pCreate.flDamage );
pProjectile->SetDamageType( pCreate.iDamageType );
pProjectile->SetDamageScale( pCreate.flDamageScale );
pProjectile->SetAbsVelocity( pCreate.vecVelocity );
// Setup the initial angles.
QAngle angles;
VectorAngles( -pCreate.vecVelocity, angles );
pProjectile->SetAbsAngles( angles );
// Spawn & Activate
DispatchSpawn( pProjectile );
pProjectile->Activate();
return pProjectile;
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
unsigned int CBaseProjectile::PhysicsSolidMaskForEntity( void ) const
{
return BaseClass::PhysicsSolidMaskForEntity() | CONTENTS_HITBOX;
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CBaseProjectile::ProjectileTouch( CBaseEntity *pOther )
{
// Verify a correct "other."
Assert( pOther );
if ( !pOther->IsSolid() || pOther->IsSolidFlagSet( FSOLID_VOLUME_CONTENTS ) )
return;
// Handle hitting skybox (disappear).
const trace_t *pTrace = &CBaseEntity::GetTouchTrace();
trace_t *pNewTrace = const_cast<trace_t*>( pTrace );
if( pTrace->surface.flags & SURF_SKY )
{
UTIL_Remove( this );
return;
}
CTakeDamageInfo info;
info.SetAttacker( GetOwnerEntity() );
info.SetInflictor( this );
info.SetDamage( GetDamage() );
info.SetDamageType( GetDamageType() );
CalculateMeleeDamageForce( &info, GetAbsVelocity(), GetAbsOrigin(), GetDamageScale() );
Vector dir;
AngleVectors( GetAbsAngles(), &dir );
pOther->DispatchTraceAttack( info, dir, pNewTrace );
ApplyMultiDamage();
UTIL_Remove( this );
}
//-----------------------------------------------------------------------------
// Purpose: Orient the projectile along its velocity
//-----------------------------------------------------------------------------
void CBaseProjectile::FlyThink( void )
{
QAngle angles;
VectorAngles( -(GetAbsVelocity()), angles );
SetAbsAngles( angles );
SetNextThink( gpGlobals->curtime + 0.1f );
}

View File

@@ -1,61 +0,0 @@
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
//=============================================================================
#ifndef BASEPROJECTILE_H
#define BASEPROJECTILE_H
#ifdef _WIN32
#pragma once
#endif
// Creation.
struct baseprojectilecreate_t
{
Vector vecOrigin;
Vector vecVelocity;
CBaseEntity *pOwner;
string_t iszModel;
float flDamage;
int iDamageType;
float flDamageScale;
};
//=============================================================================
//
// Generic projectile
//
class CBaseProjectile : public CBaseAnimating
{
DECLARE_CLASS( CBaseProjectile, CBaseAnimating );
public:
DECLARE_DATADESC();
void Spawn( void );
void Precache( void );
static CBaseProjectile *Create( baseprojectilecreate_t &pCreate );
void SetDamage( float flDamage ) { m_flDamage = flDamage; }
void SetDamageScale( float &flScale ) { m_flDamageScale = flScale; }
void SetDamageType( int iType ) { m_iDamageType = iType; }
private:
// Damage
virtual float GetDamage() { return m_flDamage; }
virtual float GetDamageScale( void ) { return m_flDamageScale; }
virtual int GetDamageType( void ) { return m_iDamageType; }
unsigned int PhysicsSolidMaskForEntity( void ) const;
virtual void ProjectileTouch( CBaseEntity *pOther );
void FlyThink( void );
protected:
float m_flDamage;
int m_iDamageType;
float m_flDamageScale;
};
#endif // BASEPROJECTILE_H

View File

@@ -118,7 +118,7 @@ void CBaseTempEntity::PrecacheTempEnts( void )
void CBaseTempEntity::Create( IRecipientFilter& filter, float delay )
{
// temp entities can't be reliable or part of the signon message, use real entities instead
Assert( !filter.IsInitMessage() && !filter.IsInitMessage() );
Assert( !filter.IsReliable() && !filter.IsInitMessage() );
Assert( delay >= -1 && delay <= 1); // 1 second max delay
engine->PlaybackTempEntity( filter, delay,

View File

@@ -409,13 +409,39 @@ void CC_Ent_Keyvalue( const CCommand &args )
return;
}
int nID = atoi( args[1] );
CBaseEntity *pEnt = g_ServerTools.FindEntityByHammerID( nID );
if ( !pEnt )
CBasePlayer *pPlayer = ToBasePlayer( UTIL_GetCommandClient() );
CBaseEntity *pEnt;
if ( FStrEq( args[1], "" ) || FStrEq( args[1], "!picker" ) )
{
Msg( "Entity ID %d not found.\n", nID );
return;
if (!pPlayer)
return;
extern CBaseEntity *FindPickerEntity( CBasePlayer *pPlayer );
pEnt = FindPickerEntity( pPlayer );
if ( !pEnt )
{
ClientPrint( pPlayer, HUD_PRINTCONSOLE, "No entity in front of player.\n" );
return;
}
}
else if ( FStrEq( args[1], "!self" ) || FStrEq( args[1], "!caller" ) || FStrEq( args[1], "!activator" ) )
{
if (!pPlayer)
return;
pEnt = pPlayer;
}
else
{
int nID = atoi( args[1] );
pEnt = g_ServerTools.FindEntityByHammerID( nID );
if ( !pEnt )
{
Msg( "Entity ID %d not found.\n", nID );
return;
}
}
int nArg = 2;

View File

@@ -84,7 +84,7 @@ public:
int OnTakeDamage_Alive( const CTakeDamageInfo &info );
void TraceAttack( const CTakeDamageInfo &info, const Vector &vecDir, trace_t *ptr );
void TraceAttack( const CTakeDamageInfo &info, const Vector &vecDir, trace_t *ptr, CDmgAccumulator *pAccumulator );
virtual bool FireGun( void );

View File

@@ -169,7 +169,7 @@ bool Flashlight_UseLegacyVersion( void )
g_bUseLegacyFlashlight = ( !Q_strcmp( modDir, "hl2" ) ||
!Q_strcmp( modDir, "episodic" ) ||
!Q_strcmp( modDir, "lostcoast" ));
!Q_strcmp( modDir, "lostcoast" ) || !Q_strcmp( modDir, "hl1" ));
g_bCacheLegacyFlashlightStatus = false;
}

View File

@@ -36,6 +36,8 @@ public:
// Outputs
COutputEvent m_OnTrigger;
COutputEvent m_OnSpawn;
bool IsDisabled( void ){ return m_bDisabled; }
private:

View File

@@ -630,9 +630,10 @@ void CNavMesh::OnRoundRestart( void )
}
// attach prerequisites
CFuncNavPrerequisite *prereq = NULL;
while( ( prereq = (CFuncNavPrerequisite *)gEntList.FindEntityByClassname( prereq, "func_nav_prerequisite" ) ) != NULL )
for ( int i=0; i<IFuncNavPrerequisiteAutoList::AutoList().Count(); ++i )
{
CFuncNavPrerequisite *prereq = static_cast< CFuncNavPrerequisite* >( IFuncNavPrerequisiteAutoList::AutoList()[i] );
Extent prereqExtent;
prereqExtent.Init( prereq );

View File

@@ -442,6 +442,7 @@ BEGIN_DATADESC( CBasePlayer )
DEFINE_INPUTFUNC( FIELD_INTEGER, "SetHealth", InputSetHealth ),
DEFINE_INPUTFUNC( FIELD_BOOLEAN, "SetHUDVisibility", InputSetHUDVisibility ),
DEFINE_INPUTFUNC( FIELD_STRING, "SetFogController", InputSetFogController ),
DEFINE_INPUTFUNC( FIELD_STRING, "HandleMapEvent", InputHandleMapEvent ),
DEFINE_FIELD( m_nNumCrouches, FIELD_INTEGER ),
DEFINE_FIELD( m_bDuckToggled, FIELD_BOOLEAN ),
@@ -911,7 +912,7 @@ void CBasePlayer::TraceAttack( const CTakeDamageInfo &inputInfo, const Vector &v
// Prevent team damage here so blood doesn't appear
if ( info.GetAttacker()->IsPlayer() )
{
if ( !g_pGameRules->FPlayerCanTakeDamage( this, info.GetAttacker() ) )
if ( !g_pGameRules->FPlayerCanTakeDamage( this, info.GetAttacker(), info ) )
return;
}
}
@@ -1121,7 +1122,7 @@ int CBasePlayer::OnTakeDamage( const CTakeDamageInfo &inputInfo )
// go take the damage first
if ( !g_pGameRules->FPlayerCanTakeDamage( this, info.GetAttacker() ) )
if ( !g_pGameRules->FPlayerCanTakeDamage( this, info.GetAttacker(), inputInfo ) )
{
// Refuse the damage
return 0;
@@ -3311,7 +3312,8 @@ void CBasePlayer::PhysicsSimulate( void )
}
#endif // _DEBUG
if ( int numUsrCmdProcessTicksMax = sv_maxusrcmdprocessticks.GetInt() )
int numUsrCmdProcessTicksMax = sv_maxusrcmdprocessticks.GetInt();
if ( gpGlobals->maxClients != 1 && numUsrCmdProcessTicksMax ) // don't apply this filter in SP games
{
// Grant the client some time buffer to execute user commands
m_flMovementTimeForUserCmdProcessingRemaining += TICK_INTERVAL;
@@ -8641,6 +8643,14 @@ void CBasePlayer::InputSetHealth( inputdata_t &inputdata )
}
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CBasePlayer::InputHandleMapEvent( inputdata_t &inputdata )
{
Internal_HandleMapEvent( inputdata );
}
//-----------------------------------------------------------------------------
// Purpose: Hides or displays the HUD
// Input : &inputdata -

View File

@@ -765,6 +765,7 @@ public:
//---------------------------------
void InputSetHealth( inputdata_t &inputdata );
void InputSetHUDVisibility( inputdata_t &inputdata );
void InputHandleMapEvent( inputdata_t &inputdata );
surfacedata_t *GetSurfaceData( void ) { return m_pSurfaceData; }
void SetLadderNormal( Vector vecLadderNormal ) { m_vecLadderNormal = vecLadderNormal; }
@@ -903,6 +904,8 @@ protected:
void CalcObserverView( Vector& eyeOrigin, QAngle& eyeAngles, float& fov );
void CalcViewModelView( const Vector& eyeOrigin, const QAngle& eyeAngles);
virtual void Internal_HandleMapEvent( inputdata_t &inputdata ){}
// FIXME: Make these private! (tf_player uses them)
// Secondary point to derive PVS from when zoomed in with binoculars/sniper rifle. The PVS is

View File

@@ -770,10 +770,12 @@ void CLagCompensationManager::FinishLagCompensation( CBasePlayer *player )
// Restore it
pPlayer->SetSize( restore->m_vecMinsPreScaled, restore->m_vecMaxsPreScaled );
}
#ifdef STAGING_ONLY
else
{
Warning( "Should we really not restore the size?\n" );
}
#endif
}
if ( restore->m_fFlags & LC_ANGLES_CHANGED )

View File

@@ -245,6 +245,8 @@ $Project
$File "$SRCDIR\game\shared\baseparticleentity.h"
$File "$SRCDIR\game\shared\baseplayer_shared.cpp"
$File "$SRCDIR\game\shared\baseplayer_shared.h"
$File "$SRCDIR\game\shared\baseprojectile.cpp"
$File "$SRCDIR\game\shared\baseprojectile.h"
$File "BasePropDoor.h"
$File "basetoggle.h"
$File "baseviewmodel.cpp"

View File

@@ -841,16 +841,6 @@ void CTeamControlPointMaster::InputRoundSpawn( inputdata_t &input )
FindControlPointRounds();
SetBaseControlPoints();
// init the ClientAreas
int index = 0;
for ( int i=0; i<ITriggerAreaCaptureAutoList::AutoList().Count(); ++i )
{
CTriggerAreaCapture *pArea = static_cast< CTriggerAreaCapture * >( ITriggerAreaCaptureAutoList::AutoList()[i] );
pArea->SetAreaIndex( index );
index++;
}
ObjectiveResource()->ResetControlPoints();
}

View File

@@ -72,6 +72,7 @@ BEGIN_DATADESC( CTeamTrainWatcher )
DEFINE_INPUTFUNC( FIELD_VOID, "Disable", InputDisable ),
DEFINE_INPUTFUNC( FIELD_FLOAT, "SetSpeedForwardModifier", InputSetSpeedForwardModifier ),
DEFINE_INPUTFUNC( FIELD_INTEGER, "SetTrainRecedeTime", InputSetTrainRecedeTime ),
DEFINE_INPUTFUNC( FIELD_BOOLEAN, "SetTrainCanRecede", InputSetTrainCanRecede ),
// Outputs
DEFINE_OUTPUT( m_OnTrainStartRecede, "OnTrainStartRecede" ),
@@ -141,6 +142,9 @@ END_SEND_TABLE()
LINK_ENTITY_TO_CLASS( team_train_watcher, CTeamTrainWatcher );
IMPLEMENT_AUTO_LIST( ITFTeamTrainWatcher );
/*
LINK_ENTITY_TO_CLASS( team_train_watcher_master, CTeamTrainWatcherMaster );
PRECACHE_REGISTER( team_train_watcher_master );
@@ -710,6 +714,11 @@ void CTeamTrainWatcher::InputSetTrainRecedeTime( inputdata_t &inputdata )
}
}
void CTeamTrainWatcher::InputSetTrainCanRecede( inputdata_t &inputdata )
{
m_bTrainCanRecede = inputdata.value.Bool();
}
void CTeamTrainWatcher::InputOnStartOvertime( inputdata_t &inputdata )
{
// recalculate the recede time

View File

@@ -34,7 +34,9 @@ class CTeamControlPoint;
// #define TWMASTER_THINK "CTeamTrainWatcherMasterThink"
class CTeamTrainWatcher : public CBaseEntity, public CGameEventListener
DECLARE_AUTO_LIST( ITFTeamTrainWatcher );
class CTeamTrainWatcher : public CBaseEntity, public CGameEventListener, public ITFTeamTrainWatcher
{
DECLARE_CLASS( CTeamTrainWatcher, CBaseEntity );
public:
@@ -55,6 +57,7 @@ public:
void InputOnStartOvertime( inputdata_t &inputdata );
void InputSetSpeedForwardModifier( inputdata_t &inputdata );
void InputSetTrainRecedeTime( inputdata_t &inputdata );
void InputSetTrainCanRecede( inputdata_t &inputdata );
// ==========================================================
// given a start node and a list of goal nodes

View File

@@ -1646,7 +1646,7 @@ static CBaseEntity *FindPhysicsBlockerForHierarchy( CBaseEntity *pParentEntity )
{
IPhysicsObject *pOther = pSnapshot->GetObject(1);
CBaseEntity *pOtherEntity = static_cast<CBaseEntity *>(pOther->GetGameData());
if ( pOtherEntity->GetMoveType() == MOVETYPE_VPHYSICS )
if ( pOtherEntity && pOtherEntity->GetMoveType() == MOVETYPE_VPHYSICS )
{
Vector normal;
pSnapshot->GetSurfaceNormal(normal);

View File

@@ -43,7 +43,6 @@ BEGIN_DATADESC(CTriggerAreaCapture)
// DEFINE_FIELD( m_TeamData, CUtlVector < perteamdata_t > ),
// DEFINE_FIELD( m_Blockers, CUtlVector < blockers_t > ),
// DEFINE_FIELD( m_bActive, FIELD_BOOLEAN ),
// DEFINE_FIELD( m_iAreaIndex, FIELD_INTEGER ),
// DEFINE_FIELD( m_hPoint, CHandle < CTeamControlPoint > ),
// DEFINE_FIELD( m_bRequiresObject, FIELD_BOOLEAN ),
// DEFINE_FIELD( m_iCapAttemptNumber, FIELD_INTEGER ),
@@ -96,8 +95,6 @@ void CTriggerAreaCapture::Spawn( void )
Precache();
m_iAreaIndex = -1;
SetTouch ( &CTriggerAreaCaptureShim::Touch );
SetThink( &CTriggerAreaCapture::CaptureThink );
SetNextThink( gpGlobals->curtime + AREA_THINK_TIME );
@@ -164,14 +161,6 @@ void CTriggerAreaCapture::Precache( void )
{
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CTriggerAreaCapture::SetAreaIndex( int index )
{
m_iAreaIndex = index;
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
@@ -231,7 +220,7 @@ void CTriggerAreaCapture::StartTouch(CBaseEntity *pOther)
//-----------------------------------------------------------------------------
void CTriggerAreaCapture::EndTouch(CBaseEntity *pOther)
{
if ( PassesTriggerFilters(pOther) && m_hPoint )
if ( IsTouching( pOther ) && m_hPoint )
{
IGameEvent *event = gameeventmanager->CreateEvent( "controlpoint_endtouch" );
if ( event )
@@ -274,8 +263,6 @@ void CTriggerAreaCapture::AreaTouch( CBaseEntity *pOther )
if ( !TeamplayGameRules()->PointsMayBeCaptured() )
return;
Assert( m_iAreaIndex != -1 );
// dont touch for non-alive or non-players
if( !pOther->IsPlayer() || !pOther->IsAlive() )
return;
@@ -771,6 +758,8 @@ void CTriggerAreaCapture::StartCapture( int team, int capmode )
m_nCapturingTeam = team;
OnStartCapture( m_nCapturingTeam );
UpdateNumPlayers();
if ( CaptureModeScalesWithPlayers() )

View File

@@ -55,13 +55,13 @@ public:
// A team has finished capturing the zone.
virtual void OnEndCapture( int iTeam ) { return; }
virtual void OnStartCapture( int iTeam ) { return; }
public:
virtual void Spawn( void );
virtual void Precache( void );
virtual bool KeyValue( const char *szKeyName, const char *szValue );
void SetAreaIndex( int index );
bool IsActive( void );
bool CheckIfDeathCausesBlock( CBaseMultiplayerPlayer *pVictim, CBaseMultiplayerPlayer *pKiller );
@@ -173,8 +173,6 @@ private:
COutputInt m_OnNumCappersChanged;
COutputInt m_OnNumCappersChanged2;
int m_iAreaIndex; //index of this area among all other areas
CHandle<CTeamControlPoint> m_hPoint; //the capture point that we are linked to!
bool m_bRequiresObject;

View File

@@ -392,30 +392,37 @@ bool CBaseTrigger::PassesTriggerFilters(CBaseEntity *pOther)
bool bOtherIsPlayer = pOther->IsPlayer();
if ( HasSpawnFlags(SF_TRIGGER_ONLY_CLIENTS_IN_VEHICLES) && bOtherIsPlayer )
if ( bOtherIsPlayer )
{
if ( !((CBasePlayer*)pOther)->IsInAVehicle() )
CBasePlayer *pPlayer = (CBasePlayer*)pOther;
if ( !pPlayer->IsAlive() )
return false;
// Make sure we're also not exiting the vehicle at the moment
IServerVehicle *pVehicleServer = ((CBasePlayer*)pOther)->GetVehicle();
if ( pVehicleServer == NULL )
return false;
if ( pVehicleServer->IsPassengerExiting() )
return false;
}
if ( HasSpawnFlags(SF_TRIGGER_ONLY_CLIENTS_IN_VEHICLES) )
{
if ( !pPlayer->IsInAVehicle() )
return false;
if ( HasSpawnFlags(SF_TRIGGER_ONLY_CLIENTS_OUT_OF_VEHICLES) && bOtherIsPlayer )
{
if ( ((CBasePlayer*)pOther)->IsInAVehicle() )
return false;
}
// Make sure we're also not exiting the vehicle at the moment
IServerVehicle *pVehicleServer = pPlayer->GetVehicle();
if ( pVehicleServer == NULL )
return false;
if ( HasSpawnFlags( SF_TRIGGER_DISALLOW_BOTS ) && bOtherIsPlayer )
{
if ( ((CBasePlayer*)pOther)->IsFakeClient() )
return false;
if ( pVehicleServer->IsPassengerExiting() )
return false;
}
if ( HasSpawnFlags(SF_TRIGGER_ONLY_CLIENTS_OUT_OF_VEHICLES) )
{
if ( pPlayer->IsInAVehicle() )
return false;
}
if ( HasSpawnFlags( SF_TRIGGER_DISALLOW_BOTS ) )
{
if ( pPlayer->IsFakeClient() )
return false;
}
}
CBaseFilter *pFilter = m_hFilter.Get();
@@ -503,6 +510,14 @@ void CBaseTrigger::EndTouch(CBaseEntity *pOther)
{
m_hTouchingEntities.Remove( i );
}
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() ) ) );
Warning( "Dead player [%s] is still touching this trigger at [%f %f %f]", hOther->GetEntityName().ToCStr(), XYZ( hOther->GetAbsOrigin() ) );
#endif
m_hTouchingEntities.Remove( i );
}
else
{
bFoundOtherTouchee = true;

View File

@@ -902,7 +902,15 @@ void UTIL_ScreenShakeObject( CBaseEntity *pEnt, const Vector &center, float ampl
continue;
}
localAmplitude = ComputeShakeAmplitude( center, pPlayer->WorldSpaceCenter(), amplitude, radius );
if ( radius > 0 )
{
localAmplitude = ComputeShakeAmplitude( center, pPlayer->WorldSpaceCenter(), amplitude, radius );
}
else
{
// If using a 0 radius, apply to everyone with no falloff
localAmplitude = amplitude;
}
// This happens if the player is outside the radius,
// in which case we should ignore all commands

View File

@@ -616,11 +616,7 @@ void CVoteController::VoteControllerThink( void )
}
else
{
// Don't track failed dedicated server votes
if ( m_iEntityHoldingVote != DEDICATED_SERVER )
{
m_potentialIssues[m_iActiveIssueIndex]->OnVoteFailed();
}
m_potentialIssues[m_iActiveIssueIndex]->OnVoteFailed( m_iEntityHoldingVote );
m_resetVoteTimer.Start( 5.0 );
}
}
@@ -895,34 +891,38 @@ const char *CBaseIssue::GetVotePassedString( void )
//-----------------------------------------------------------------------------
// Purpose: Store failures to prevent vote spam
//-----------------------------------------------------------------------------
void CBaseIssue::OnVoteFailed( void )
void CBaseIssue::OnVoteFailed( int iEntityHoldingVote )
{
// Check for an existing match
for ( int index = 0; index < m_FailedVotes.Count(); index++ )
// Don't track failed dedicated server votes
if ( BRecordVoteFailureEventForEntity( iEntityHoldingVote ) )
{
FailedVote *pFailedVote = m_FailedVotes[index];
if ( Q_strcmp( pFailedVote->szFailedVoteParameter, GetDetailsString() ) == 0 )
// Check for an existing match
for ( int index = 0; index < m_FailedVotes.Count(); index++ )
{
int nTime = sv_vote_failure_timer.GetInt();
FailedVote *pFailedVote = m_FailedVotes[index];
if ( Q_strcmp( pFailedVote->szFailedVoteParameter, GetDetailsString() ) == 0 )
{
int nTime = sv_vote_failure_timer.GetInt();
#ifdef TF_DLL
if ( TFGameRules() && TFGameRules()->IsMannVsMachineMode() )
{
nTime = sv_vote_failure_timer_mvm.GetInt();
}
if ( TFGameRules() && TFGameRules()->IsMannVsMachineMode() )
{
nTime = sv_vote_failure_timer_mvm.GetInt();
}
#endif // TF_DLL
pFailedVote->flLockoutTime = gpGlobals->curtime + nTime;
pFailedVote->flLockoutTime = gpGlobals->curtime + nTime;
return;
return;
}
}
}
// Need to create a new one
FailedVote *pNewFailedVote = new FailedVote;
int iIndex = m_FailedVotes.AddToTail( pNewFailedVote );
Q_strcpy( m_FailedVotes[iIndex]->szFailedVoteParameter, GetDetailsString() );
m_FailedVotes[iIndex]->flLockoutTime = gpGlobals->curtime + sv_vote_failure_timer.GetFloat();
// Need to create a new one
FailedVote *pNewFailedVote = new FailedVote;
int iIndex = m_FailedVotes.AddToTail( pNewFailedVote );
Q_strcpy( m_FailedVotes[iIndex]->szFailedVoteParameter, GetDetailsString() );
m_FailedVotes[iIndex]->flLockoutTime = gpGlobals->curtime + sv_vote_failure_timer.GetFloat();
}
}
//-----------------------------------------------------------------------------
@@ -939,7 +939,7 @@ bool CBaseIssue::CanTeamCallVote( int iTeam ) const
bool CBaseIssue::CanCallVote( int iEntIndex, const char *pszDetails, vote_create_failed_t &nFailCode, int &nTime )
{
// Automated server vote - don't bother testing against it
if ( iEntIndex == DEDICATED_SERVER )
if ( !BRecordVoteFailureEventForEntity( iEntIndex ) )
return true;
// Bogus player

View File

@@ -25,7 +25,7 @@ public:
const char *GetTypeString( void ); // Connection between console command and specific type of issue
virtual const char *GetDetailsString();
virtual void SetIssueDetails( const char *pszDetails ); // We need to know the details part of the con command for later
virtual void OnVoteFailed( void ); // The moment the vote fails, also has some time for feedback before the window goes away
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?
@@ -40,6 +40,7 @@ public:
virtual bool IsYesNoVote( void );
virtual void SetYesNoVoteCount( int iNumYesVotes, int iNumNoVotes, int iNumPotentialVotes );
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; }
protected:
static void ListStandardNoArgCommand( CBasePlayer *forWhom, const char *issueString ); // List a Yes vote command