aboutsummaryrefslogtreecommitdiff
path: root/mp/src/game
diff options
context:
space:
mode:
authorJoe Ludwig <[email protected]>2013-12-03 08:54:16 -0800
committerJoe Ludwig <[email protected]>2013-12-03 08:54:16 -0800
commitbeaae8ac45a2f322a792404092d4482065bef7ef (patch)
tree747f35193ba235f0f0b070c05b53468a54559c8e /mp/src/game
parentMake .xcconfigs text files too. (diff)
downloadsource-sdk-2013-beaae8ac45a2f322a792404092d4482065bef7ef.tar.xz
source-sdk-2013-beaae8ac45a2f322a792404092d4482065bef7ef.zip
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
Diffstat (limited to 'mp/src/game')
-rw-r--r--mp/src/game/client/c_baseanimating.cpp8
-rw-r--r--mp/src/game/client/c_baseentity.cpp7
-rw-r--r--mp/src/game/client/c_baseflex.cpp27
-rw-r--r--mp/src/game/client/c_baseflex.h1
-rw-r--r--mp/src/game/client/c_baseplayer.cpp138
-rw-r--r--mp/src/game/client/c_baseplayer.h6
-rw-r--r--mp/src/game/client/c_pixel_visibility.cpp2
-rw-r--r--mp/src/game/client/c_prop_vehicle.cpp2
-rw-r--r--mp/src/game/client/cdll_client_int.cpp56
-rw-r--r--mp/src/game/client/client_base.vpc2
-rw-r--r--mp/src/game/client/client_virtualreality.cpp711
-rw-r--r--mp/src/game/client/client_virtualreality.h50
-rw-r--r--mp/src/game/client/clientmode_shared.cpp20
-rw-r--r--mp/src/game/client/clientmode_shared.h1
-rw-r--r--mp/src/game/client/game_controls/vguitextwindow.cpp20
-rw-r--r--mp/src/game/client/hl2/hud_autoaim.cpp2
-rw-r--r--mp/src/game/client/hl2/hud_damageindicator.cpp2
-rw-r--r--mp/src/game/client/hl2/hud_weaponselection.cpp18
-rw-r--r--mp/src/game/client/hud_basedeathnotice.cpp63
-rw-r--r--mp/src/game/client/hud_basedeathnotice.h13
-rw-r--r--mp/src/game/client/hud_crosshair.cpp2
-rw-r--r--mp/src/game/client/hud_vote.cpp4
-rw-r--r--mp/src/game/client/iclientmode.h1
-rw-r--r--mp/src/game/client/in_main.cpp2
-rw-r--r--mp/src/game/client/replay/vgui/replayperformanceeditor.cpp17
-rw-r--r--mp/src/game/client/replay/vgui/replayperformanceeditor.h2
-rw-r--r--mp/src/game/client/sixense/in_sixense.cpp2
-rw-r--r--mp/src/game/client/view.cpp116
-rw-r--r--mp/src/game/client/view_scene.cpp2
-rw-r--r--mp/src/game/client/viewpostprocess.cpp2
-rw-r--r--mp/src/game/client/viewrender.cpp52
-rw-r--r--mp/src/game/client/viewrender.h4
-rw-r--r--mp/src/game/protobuf_include.vpc4
-rw-r--r--mp/src/game/server/ai_activity.cpp4
-rw-r--r--mp/src/game/server/ai_movesolver.cpp4
-rw-r--r--mp/src/game/server/ai_networkmanager.cpp2
-rw-r--r--mp/src/game/server/baseanimating.cpp18
-rw-r--r--mp/src/game/server/baseanimating.h1
-rw-r--r--mp/src/game/server/baseentity.cpp11
-rw-r--r--mp/src/game/server/basemultiplayerplayer.cpp10
-rw-r--r--mp/src/game/server/basemultiplayerplayer.h1
-rw-r--r--mp/src/game/server/baseprojectile.cpp136
-rw-r--r--mp/src/game/server/baseprojectile.h61
-rw-r--r--mp/src/game/server/basetempentity.cpp2
-rw-r--r--mp/src/game/server/entity_tools_server.cpp36
-rw-r--r--mp/src/game/server/hl1_CBaseHelicopter.h2
-rw-r--r--mp/src/game/server/hl2/hl2_player.cpp2
-rw-r--r--mp/src/game/server/logicrelay.h2
-rw-r--r--mp/src/game/server/nav_mesh.cpp5
-rw-r--r--mp/src/game/server/player.cpp16
-rw-r--r--mp/src/game/server/player.h3
-rw-r--r--mp/src/game/server/player_lagcompensation.cpp2
-rw-r--r--mp/src/game/server/server_base.vpc2
-rw-r--r--mp/src/game/server/team_control_point_master.cpp10
-rw-r--r--mp/src/game/server/team_train_watcher.cpp9
-rw-r--r--mp/src/game/server/team_train_watcher.h5
-rw-r--r--mp/src/game/server/trains.cpp2
-rw-r--r--mp/src/game/server/trigger_area_capture.cpp17
-rw-r--r--mp/src/game/server/trigger_area_capture.h4
-rw-r--r--mp/src/game/server/triggers.cpp53
-rw-r--r--mp/src/game/server/util.cpp10
-rw-r--r--mp/src/game/server/vote_controller.cpp48
-rw-r--r--mp/src/game/server/vote_controller.h3
-rw-r--r--mp/src/game/shared/activitylist.cpp5
-rw-r--r--mp/src/game/shared/ai_activity.h7
-rw-r--r--mp/src/game/shared/basecombatweapon_shared.h2
-rw-r--r--mp/src/game/shared/basegrenade_shared.h8
-rw-r--r--mp/src/game/shared/baseplayer_shared.cpp2
-rw-r--r--mp/src/game/shared/baseprojectile.cpp26
-rw-r--r--mp/src/game/shared/baseprojectile.h53
-rw-r--r--mp/src/game/shared/baseviewmodel_shared.cpp2
-rw-r--r--mp/src/game/shared/effect_color_tables.h1
-rw-r--r--mp/src/game/shared/gamemovement.cpp20
-rw-r--r--mp/src/game/shared/gamerules.h2
-rw-r--r--mp/src/game/shared/movevars_shared.cpp12
-rw-r--r--mp/src/game/shared/mp_shareddefs.cpp47
-rw-r--r--mp/src/game/shared/mp_shareddefs.h44
-rw-r--r--mp/src/game/shared/multiplay_gamerules.cpp41
-rw-r--r--mp/src/game/shared/multiplay_gamerules.h3
-rw-r--r--mp/src/game/shared/particle_property.cpp23
-rw-r--r--mp/src/game/shared/props_shared.cpp2
-rw-r--r--mp/src/game/shared/props_shared.h2
-rw-r--r--mp/src/game/shared/shareddefs.h12
-rw-r--r--mp/src/game/shared/takedamageinfo.cpp2
-rw-r--r--mp/src/game/shared/takedamageinfo.h3
-rw-r--r--mp/src/game/shared/teamplay_gamerules.cpp6
-rw-r--r--mp/src/game/shared/teamplay_gamerules.h2
-rw-r--r--mp/src/game/shared/teamplay_round_timer.cpp6
-rw-r--r--mp/src/game/shared/teamplayroundbased_gamerules.cpp19
-rw-r--r--mp/src/game/shared/teamplayroundbased_gamerules.h7
-rw-r--r--mp/src/game/shared/voice_banmgr.cpp6
91 files changed, 1176 insertions, 1029 deletions
diff --git a/mp/src/game/client/c_baseanimating.cpp b/mp/src/game/client/c_baseanimating.cpp
index c71d2682..c7cc08b4 100644
--- a/mp/src/game/client/c_baseanimating.cpp
+++ b/mp/src/game/client/c_baseanimating.cpp
@@ -1013,7 +1013,9 @@ CStudioHdr *C_BaseAnimating::OnNewModel()
{
// XXX what's authoritative? the model pointer or the model index? what a mess.
nNewIndex = modelinfo->GetModelIndex( modelinfo->GetModelName( GetModel() ) );
- Assert( modelinfo->GetModel( nNewIndex ) == GetModel() );
+ Assert( nNewIndex < 0 || modelinfo->GetModel( nNewIndex ) == GetModel() );
+ if ( nNewIndex < 0 )
+ nNewIndex = m_nModelIndex;
}
m_AutoRefModelIndex = nNewIndex;
@@ -5099,7 +5101,7 @@ void C_BaseAnimating::StudioFrameAdvance()
SetCycle( flNewCycle );
- m_flGroundSpeed = GetSequenceGroundSpeed( hdr, GetSequence() );
+ m_flGroundSpeed = GetSequenceGroundSpeed( hdr, GetSequence() ) * GetModelScale();
#if 0
// I didn't have a test case for this, but it seems like the right thing to do. Check multi-player!
@@ -5289,7 +5291,7 @@ void C_BaseAnimating::ResetSequenceInfo( void )
}
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;
diff --git a/mp/src/game/client/c_baseentity.cpp b/mp/src/game/client/c_baseentity.cpp
index 0b09309a..8f40d7ef 100644
--- a/mp/src/game/client/c_baseentity.cpp
+++ b/mp/src/game/client/c_baseentity.cpp
@@ -894,7 +894,12 @@ C_BaseEntity::C_BaseEntity() :
{
AddVar( &m_vecOrigin, &m_iv_vecOrigin, LATCH_SIMULATION_VAR );
AddVar( &m_angRotation, &m_iv_angRotation, LATCH_SIMULATION_VAR );
- AddVar( &m_vecVelocity, &m_iv_vecVelocity, LATCH_SIMULATION_VAR );
+ // Removing this until we figure out why velocity introduces view hitching.
+ // One possible fix is removing the player->ResetLatched() call in CGameMovement::FinishDuck(),
+ // but that re-introduces a third-person hitching bug. One possible cause is the abrupt change
+ // in player size/position that occurs when ducking, and how prediction tries to work through that.
+ //
+ // AddVar( &m_vecVelocity, &m_iv_vecVelocity, LATCH_SIMULATION_VAR );
m_DataChangeEventRef = -1;
m_EntClientFlags = 0;
diff --git a/mp/src/game/client/c_baseflex.cpp b/mp/src/game/client/c_baseflex.cpp
index 0a5db8e5..6146b2dd 100644
--- a/mp/src/game/client/c_baseflex.cpp
+++ b/mp/src/game/client/c_baseflex.cpp
@@ -1159,6 +1159,33 @@ void C_BaseFlex::SetupWeights( const matrix3x4_t *pBoneToWorld, int nFlexWeightC
//-----------------------------------------------------------------------------
+// Purpose: Use the local bone positions to set flex control weights
+// via boneflexdrivers specified in the model
+//-----------------------------------------------------------------------------
+void C_BaseFlex::BuildTransformations( CStudioHdr *pStudioHdr, Vector *pos, Quaternion q[], const matrix3x4_t& cameraTransform, int boneMask, CBoneBitList &boneComputed )
+{
+ const int nBoneFlexDriverCount = pStudioHdr->BoneFlexDriverCount();
+
+ for ( int i = 0; i < nBoneFlexDriverCount; ++i )
+ {
+ const mstudioboneflexdriver_t *pBoneFlexDriver = pStudioHdr->BoneFlexDriver( i );
+ const Vector &position = pos[ pBoneFlexDriver->m_nBoneIndex ];
+
+ const int nControllerCount = pBoneFlexDriver->m_nControlCount;
+ for ( int j = 0; j < nControllerCount; ++j )
+ {
+ const mstudioboneflexdrivercontrol_t *pController = pBoneFlexDriver->pBoneFlexDriverControl( j );
+ Assert( pController->m_nFlexControllerIndex >= 0 && pController->m_nFlexControllerIndex < pStudioHdr->numflexcontrollers() );
+ Assert( pController->m_nBoneComponent >= 0 && pController->m_nBoneComponent <= 2 );
+ SetFlexWeight( static_cast< LocalFlexController_t >( pController->m_nFlexControllerIndex ), RemapValClamped( position[pController->m_nBoneComponent], pController->m_flMin, pController->m_flMax, 0.0f, 1.0f ) );
+ }
+ }
+
+ BaseClass::BuildTransformations( pStudioHdr, pos, q, cameraTransform, boneMask, boneComputed );
+}
+
+
+//-----------------------------------------------------------------------------
// Purpose: process the entities networked state, vcd playback, wav file visemes, and blinks into a global shared flex controller array
//-----------------------------------------------------------------------------
bool C_BaseFlex::SetupGlobalWeights( const matrix3x4_t *pBoneToWorld, int nFlexWeightCount, float *pFlexWeights, float *pFlexDelayedWeights )
diff --git a/mp/src/game/client/c_baseflex.h b/mp/src/game/client/c_baseflex.h
index f99061d1..71cee3d8 100644
--- a/mp/src/game/client/c_baseflex.h
+++ b/mp/src/game/client/c_baseflex.h
@@ -147,6 +147,7 @@ public:
virtual void OnThreadedDrawSetup();
// model specific
+ virtual void BuildTransformations( CStudioHdr *pStudioHdr, Vector *pos, Quaternion q[], const matrix3x4_t& cameraTransform, int boneMask, CBoneBitList &boneComputed );
static void LinkToGlobalFlexControllers( CStudioHdr *hdr );
virtual void SetupWeights( const matrix3x4_t *pBoneToWorld, int nFlexWeightCount, float *pFlexWeights, float *pFlexDelayedWeights );
virtual bool SetupGlobalWeights( const matrix3x4_t *pBoneToWorld, int nFlexWeightCount, float *pFlexWeights, float *pFlexDelayedWeights );
diff --git a/mp/src/game/client/c_baseplayer.cpp b/mp/src/game/client/c_baseplayer.cpp
index 3b1ac003..942f7a37 100644
--- a/mp/src/game/client/c_baseplayer.cpp
+++ b/mp/src/game/client/c_baseplayer.cpp
@@ -47,7 +47,7 @@
#include "replay/ienginereplay.h"
#endif
#include "steam/steam_api.h"
-#include "headtrack/isourcevirtualreality.h"
+#include "sourcevr/isourcevirtualreality.h"
#include "client_virtualreality.h"
#if defined USES_ECON_ITEMS
@@ -115,6 +115,13 @@ static ConVar cl_first_person_uses_world_model ( "cl_first_person_uses_world_mod
ConVar demo_fov_override( "demo_fov_override", "0", FCVAR_CLIENTDLL | FCVAR_DONTRECORD, "If nonzero, this value will be used to override FOV during demo playback." );
+// This only needs to be approximate - it just controls the distance to the pivot-point of the head ("the neck") of the in-game character, not the player's real-world neck length.
+// Ideally we would find this vector by subtracting the neutral-pose difference between the head bone (the pivot point) and the "eyes" attachment point.
+// However, some characters don't have this attachment point, and finding the neutral pose is a pain.
+// This value is found by hand, and a good value depends more on the in-game models than on actual human shapes.
+ConVar cl_meathook_neck_pivot_ingame_up( "cl_meathook_neck_pivot_ingame_up", "7.0" );
+ConVar cl_meathook_neck_pivot_ingame_fwd( "cl_meathook_neck_pivot_ingame_fwd", "3.0" );
+
void RecvProxy_LocalVelocityX( const CRecvProxyData *pData, void *pStruct, void *pOut );
void RecvProxy_LocalVelocityY( const CRecvProxyData *pData, void *pStruct, void *pOut );
void RecvProxy_LocalVelocityZ( const CRecvProxyData *pData, void *pStruct, void *pOut );
@@ -429,6 +436,8 @@ C_BasePlayer::C_BasePlayer() : m_iv_vecViewOffset( "C_BasePlayer::m_iv_vecViewOf
m_bFiredWeapon = false;
m_nForceVisionFilterFlags = 0;
+
+ ListenForGameEvent( "base_player_teleported" );
}
//-----------------------------------------------------------------------------
@@ -698,6 +707,20 @@ surfacedata_t* C_BasePlayer::GetGroundSurface()
return physprops->GetSurfaceData( trace.surface.surfaceProps );
}
+void C_BasePlayer::FireGameEvent( IGameEvent *event )
+{
+ if ( FStrEq( event->GetName(), "base_player_teleported" ) )
+ {
+ const int index = event->GetInt( "entindex" );
+ if ( index == entindex() && IsLocalPlayer() )
+ {
+ // In VR, we want to make sure our head and body
+ // are aligned after we teleport.
+ g_ClientVirtualReality.AlignTorsoAndViewToWeapon();
+ }
+ }
+
+}
//-----------------------------------------------------------------------------
// returns the player name
@@ -1851,11 +1874,9 @@ void C_BasePlayer::ThirdPersonSwitch( bool bThirdperson )
{
return !input->CAM_IsThirdPerson() && ( !ToolsEnabled() || !ToolFramework_IsThirdPersonCamera() );
}
- else
- {
- // Not looking at the local player, e.g. in a replay in third person mode or freelook.
- return false;
- }
+
+ // Not looking at the local player, e.g. in a replay in third person mode or freelook.
+ return false;
}
//-----------------------------------------------------------------------------
@@ -1867,11 +1888,9 @@ void C_BasePlayer::ThirdPersonSwitch( bool bThirdperson )
{
return !LocalPlayerInFirstPersonView() || cl_first_person_uses_world_model.GetBool();
}
- else
- {
- static ConVarRef vr_first_person_uses_world_model( "vr_first_person_uses_world_model" );
- return !LocalPlayerInFirstPersonView() || vr_first_person_uses_world_model.GetBool();
- }
+
+ static ConVarRef vr_first_person_uses_world_model( "vr_first_person_uses_world_model" );
+ return !LocalPlayerInFirstPersonView() || vr_first_person_uses_world_model.GetBool();
}
@@ -1995,6 +2014,16 @@ void C_BasePlayer::PostThink( void )
if ( IsAlive())
{
+ // Need to do this on the client to avoid prediction errors
+ if ( GetFlags() & FL_DUCKING )
+ {
+ SetCollisionBounds( VEC_DUCK_HULL_MIN, VEC_DUCK_HULL_MAX );
+ }
+ else
+ {
+ SetCollisionBounds( VEC_HULL_MIN, VEC_HULL_MAX );
+ }
+
if ( !CommentaryModeShouldSwallowInput( this ) )
{
// do weapon stuff
@@ -2850,7 +2879,13 @@ void C_BasePlayer::BuildFirstPersonMeathookTransformations( CStudioHdr *hdr, Vec
m_BoneAccessor.SetWritableBones( BONE_USED_BY_ANYTHING );
- matrix3x4_t &mHeadTransform = GetBoneForWrite( LookupBone( pchHeadBoneName ) );
+ int iHead = LookupBone( pchHeadBoneName );
+ if ( iHead == -1 )
+ {
+ return;
+ }
+
+ matrix3x4_t &mHeadTransform = GetBoneForWrite( iHead );
// "up" on the head bone is along the negative Y axis - not sure why.
//Vector vHeadTransformUp ( -mHeadTransform[0][1], -mHeadTransform[1][1], -mHeadTransform[2][1] );
@@ -2862,29 +2897,19 @@ void C_BasePlayer::BuildFirstPersonMeathookTransformations( CStudioHdr *hdr, Vec
// We can't move this with animations or effects without causing nausea, so we need to move
// the whole body so that the animated head is in the right place to match the player-controlled head.
Vector vHeadUp;
- bool bMeathookEnable = true;
Vector vRealPivotPoint;
- bool bEnableDecapitation = true;
if( UseVR() )
{
- static ConVarRef vr_neck_pivot_ingame_up( "vr_neck_pivot_ingame_up" );
- static ConVarRef vr_neck_pivot_ingame_fwd( "vr_neck_pivot_ingame_fwd" );
- static ConVarRef vr_meathook_enable ( "vr_meathook_enable" );
- static ConVarRef vr_decapitation_enable ( "vr_decapitation_enable" );
-
VMatrix mWorldFromMideye = g_ClientVirtualReality.GetWorldFromMidEye();
- bMeathookEnable = vr_meathook_enable.GetBool();
- bEnableDecapitation = vr_decapitation_enable.GetBool();
-
// What we do here is:
// * Take the required eye pos+orn - the actual pose the player is controlling with the HMD.
- // * Go downwards in that space by headtrack_neck_pivot_ingame_* - this is now the neck-pivot in the game world of where the player is actually looking.
+ // * Go downwards in that space by cl_meathook_neck_pivot_ingame_* - this is now the neck-pivot in the game world of where the player is actually looking.
// * Now place the body of the animated character so that the head bone is at that position.
// The head bone is the neck pivot point of the in-game character.
Vector vRealMidEyePos = mWorldFromMideye.GetTranslation();
- vRealPivotPoint = vRealMidEyePos - ( mWorldFromMideye.GetUp() * vr_neck_pivot_ingame_up.GetFloat() ) - ( mWorldFromMideye.GetForward() * vr_neck_pivot_ingame_fwd.GetFloat() );
+ vRealPivotPoint = vRealMidEyePos - ( mWorldFromMideye.GetUp() * cl_meathook_neck_pivot_ingame_up.GetFloat() ) - ( mWorldFromMideye.GetForward() * cl_meathook_neck_pivot_ingame_fwd.GetFloat() );
}
else
{
@@ -2892,55 +2917,48 @@ void C_BasePlayer::BuildFirstPersonMeathookTransformations( CStudioHdr *hdr, Vec
Vector vForward, vRight, vUp;
AngleVectors( MainViewAngles(), &vForward, &vRight, &vUp );
- vRealPivotPoint = MainViewOrigin() - ( vUp * 7.3f ) - ( vForward * 3.f );
+ vRealPivotPoint = MainViewOrigin() - ( vUp * cl_meathook_neck_pivot_ingame_up.GetFloat() ) - ( vForward * cl_meathook_neck_pivot_ingame_fwd.GetFloat() );
}
Vector vDeltaToAdd = vRealPivotPoint - vHeadTransformTranslation;
- if ( bMeathookEnable )
+ // Now add this offset to the entire skeleton.
+ for (int i = 0; i < hdr->numbones(); i++)
{
- // Now add this offset to the entire skeleton.
- for (int i = 0; i < hdr->numbones(); i++)
+ // Only update bones reference by the bone mask.
+ if ( !( hdr->boneFlags( i ) & boneMask ) )
{
- // Only update bones reference by the bone mask.
- if ( !( hdr->boneFlags( i ) & boneMask ) )
- {
- continue;
- }
- matrix3x4_t& bone = GetBoneForWrite( i );
- Vector vBonePos;
- MatrixGetTranslation ( bone, vBonePos );
- vBonePos += vDeltaToAdd;
- MatrixSetTranslation ( vBonePos, bone );
+ continue;
}
+ matrix3x4_t& bone = GetBoneForWrite( i );
+ Vector vBonePos;
+ MatrixGetTranslation ( bone, vBonePos );
+ vBonePos += vDeltaToAdd;
+ MatrixSetTranslation ( vBonePos, bone );
}
- if ( bEnableDecapitation )
- {
- // Then scale the head to zero, but leave its position - forms a "neck stub".
- // This prevents us rendering junk all over the screen, e.g. inside of mouth, etc.
- MatrixScaleByZero ( mHeadTransform );
-
- // TODO: right now we nuke the hats by shrinking them to nothing,
- // but it feels like we should do something more sensible.
- // For example, for one sniper taunt he takes his hat off and waves it - would be nice to see it then.
- int iHelm = LookupBone( "prp_helmet" );
- if ( iHelm != -1 )
- {
- // Scale the helmet.
- matrix3x4_t &transformhelmet = GetBoneForWrite( iHelm );
- MatrixScaleByZero ( transformhelmet );
- }
+ // Then scale the head to zero, but leave its position - forms a "neck stub".
+ // This prevents us rendering junk all over the screen, e.g. inside of mouth, etc.
+ MatrixScaleByZero( mHeadTransform );
- iHelm = LookupBone( "prp_hat" );
- if ( iHelm != -1 )
- {
- matrix3x4_t &transformhelmet = GetBoneForWrite( iHelm );
- MatrixScaleByZero ( transformhelmet );
- }
+ // TODO: right now we nuke the hats by shrinking them to nothing,
+ // but it feels like we should do something more sensible.
+ // For example, for one sniper taunt he takes his hat off and waves it - would be nice to see it then.
+ int iHelm = LookupBone( "prp_helmet" );
+ if ( iHelm != -1 )
+ {
+ // Scale the helmet.
+ matrix3x4_t &transformhelmet = GetBoneForWrite( iHelm );
+ MatrixScaleByZero( transformhelmet );
}
+ iHelm = LookupBone( "prp_hat" );
+ if ( iHelm != -1 )
+ {
+ matrix3x4_t &transformhelmet = GetBoneForWrite( iHelm );
+ MatrixScaleByZero( transformhelmet );
+ }
}
diff --git a/mp/src/game/client/c_baseplayer.h b/mp/src/game/client/c_baseplayer.h
index 45c282bf..9d3657bf 100644
--- a/mp/src/game/client/c_baseplayer.h
+++ b/mp/src/game/client/c_baseplayer.h
@@ -23,6 +23,8 @@
#include "hintsystem.h"
#include "SoundEmitterSystem/isoundemittersystembase.h"
#include "c_env_fog_controller.h"
+#include "igameevents.h"
+#include "GameEventListener.h"
#if defined USES_ECON_ITEMS
#include "econ_item.h"
@@ -66,7 +68,7 @@ bool IsInFreezeCam( void );
//-----------------------------------------------------------------------------
// Purpose: Base Player class
//-----------------------------------------------------------------------------
-class C_BasePlayer : public C_BaseCombatCharacter
+class C_BasePlayer : public C_BaseCombatCharacter, public CGameEventListener
{
public:
DECLARE_CLASS( C_BasePlayer, C_BaseCombatCharacter );
@@ -467,6 +469,8 @@ protected:
// used by client side player footsteps
surfacedata_t* GetGroundSurface();
+ virtual void FireGameEvent( IGameEvent *event );
+
protected:
// Did we just enter a vehicle this frame?
bool JustEnteredVehicle();
diff --git a/mp/src/game/client/c_pixel_visibility.cpp b/mp/src/game/client/c_pixel_visibility.cpp
index e379c856..8ff507b1 100644
--- a/mp/src/game/client/c_pixel_visibility.cpp
+++ b/mp/src/game/client/c_pixel_visibility.cpp
@@ -16,7 +16,7 @@
#include "utlmultilist.h"
#include "vprof.h"
#include "icommandline.h"
-#include "headtrack/isourcevirtualreality.h"
+#include "sourcevr/isourcevirtualreality.h"
static void PixelvisDrawChanged( IConVar *pPixelvisVar, const char *pOld, float flOldValue );
diff --git a/mp/src/game/client/c_prop_vehicle.cpp b/mp/src/game/client/c_prop_vehicle.cpp
index 74dbf7f1..d093656f 100644
--- a/mp/src/game/client/c_prop_vehicle.cpp
+++ b/mp/src/game/client/c_prop_vehicle.cpp
@@ -18,7 +18,7 @@
#include "vgui/ISurface.h"
#include "client_virtualreality.h"
#include "../hud_crosshair.h"
-#include "headtrack/isourcevirtualreality.h"
+#include "sourcevr/isourcevirtualreality.h"
// NVNT haptic utils
#include "haptics/haptic_utils.h"
diff --git a/mp/src/game/client/cdll_client_int.cpp b/mp/src/game/client/cdll_client_int.cpp
index 0f40f2d3..b5a53e72 100644
--- a/mp/src/game/client/cdll_client_int.cpp
+++ b/mp/src/game/client/cdll_client_int.cpp
@@ -121,7 +121,7 @@
#include "clientsteamcontext.h"
#include "renamed_recvtable_compat.h"
#include "mouthinfo.h"
-#include "headtrack/isourcevirtualreality.h"
+#include "sourcevr/isourcevirtualreality.h"
#include "client_virtualreality.h"
#include "mumble.h"
@@ -148,7 +148,6 @@
#endif
extern vgui::IInputInternal *g_InputInternal;
-const char *COM_GetModDirectory(); // return the mod dir (rather than the complete -game param, which can be a path)
//=============================================================================
// HPE_BEGIN
@@ -332,6 +331,11 @@ static ConVar s_CV_ShowParticleCounts("showparticlecounts", "0", 0, "Display num
static ConVar s_cl_team("cl_team", "default", FCVAR_USERINFO|FCVAR_ARCHIVE, "Default team when joining a game");
static ConVar s_cl_class("cl_class", "default", FCVAR_USERINFO|FCVAR_ARCHIVE, "Default class when joining a game");
+#ifdef HL1MP_CLIENT_DLL
+static ConVar s_cl_load_hl1_content("cl_load_hl1_content", "0", FCVAR_ARCHIVE, "Mount the content from Half-Life: Source if possible");
+#endif
+
+
// Physics system
bool g_bLevelInitialized;
bool g_bTextMode = false;
@@ -943,7 +947,7 @@ int CHLClient::Init( CreateInterfaceFn appSystemFactory, CreateInterfaceFn physi
InitFbx();
#endif
- // it's ok if this is NULL. That just means the headtrack.dll wasn't found
+ // it's ok if this is NULL. That just means the sourcevr.dll wasn't found
g_pSourceVR = (ISourceVirtualReality *)appSystemFactory(SOURCE_VIRTUAL_REALITY_INTERFACE_VERSION, NULL);
factorylist_t factories;
@@ -977,17 +981,6 @@ int CHLClient::Init( CreateInterfaceFn appSystemFactory, CreateInterfaceFn physi
g_pcv_ThreadMode = g_pCVar->FindVar( "host_thread_mode" );
- // If we are in VR mode do some initial setup work
- if( UseVR() )
- {
- int nViewportWidth, nViewportHeight;
-
- g_pSourceVR->GetViewportBounds( ISourceVirtualReality::VREye_Left, NULL, NULL, &nViewportWidth, &nViewportHeight );
- vgui::surface()->SetFullscreenViewport( 0, 0, nViewportWidth, nViewportHeight );
-
- vgui::ivgui()->SetVRMode( true );
- }
-
if (!Initializer::InitializeAllObjects())
return false;
@@ -1091,6 +1084,7 @@ int CHLClient::Init( CreateInterfaceFn appSystemFactory, CreateInterfaceFn physi
#ifndef _X360
HookHapticMessages(); // Always hook the messages
#endif
+
return true;
}
@@ -1141,29 +1135,23 @@ void CHLClient::PostInit()
g_pSixenseInput->PostInit();
#endif
- // If we are in VR mode execute headtrack.cfg in PostInit so all the convars will
- // already be set up
- if( UseVR() )
- {
- // general all-game stuff
- engine->ExecuteClientCmd( "exec headtrack\\headtrack.cfg" );
-
- // game specific VR config
- CUtlString sCmd;
- sCmd.Format( "exec headtrack_%s.cfg", COM_GetModDirectory() );
- engine->ExecuteClientCmd( sCmd.Get() );
+ g_ClientVirtualReality.StartupComplete();
- engine->ExecuteClientCmd( "vr_start_tracking" );
-
- vgui::surface()->SetSoftwareCursor( true );
-#if defined(POSIX)
- ConVarRef m_rawinput( "m_rawinput" );
- m_rawinput.SetValue( 1 );
+#ifdef HL1MP_CLIENT_DLL
+ if ( s_cl_load_hl1_content.GetBool() && steamapicontext && steamapicontext->SteamApps() )
+ {
+ char szPath[ MAX_PATH*2 ];
+ int ccFolder= steamapicontext->SteamApps()->GetAppInstallDir( 280, szPath, sizeof(szPath) );
+ if ( ccFolder > 0 )
+ {
+ V_AppendSlash( szPath, sizeof(szPath) );
+ V_strncat( szPath, "hl1", sizeof( szPath ) );
- ConVarRef mat_vsync( "mat_vsync" );
- mat_vsync.SetValue( 0 );
-#endif
+ g_pFullFileSystem->AddSearchPath( szPath, "HL1" );
+ g_pFullFileSystem->AddSearchPath( szPath, "GAME" );
+ }
}
+#endif
}
//-----------------------------------------------------------------------------
diff --git a/mp/src/game/client/client_base.vpc b/mp/src/game/client/client_base.vpc
index 79a27d5d..52dceb7e 100644
--- a/mp/src/game/client/client_base.vpc
+++ b/mp/src/game/client/client_base.vpc
@@ -206,6 +206,8 @@ $Project
$File "$SRCDIR\game\shared\basegrenade_shared.cpp"
$File "$SRCDIR\game\shared\baseparticleentity.cpp"
$File "$SRCDIR\game\shared\baseplayer_shared.cpp"
+ $File "$SRCDIR\game\shared\baseprojectile.cpp"
+ $File "$SRCDIR\game\shared\baseprojectile.h"
$File "$SRCDIR\game\shared\baseviewmodel_shared.cpp"
$File "beamdraw.cpp"
$File "$SRCDIR\game\shared\beam_shared.cpp"
diff --git a/mp/src/game/client/client_virtualreality.cpp b/mp/src/game/client/client_virtualreality.cpp
index 1512d7bf..d729210e 100644
--- a/mp/src/game/client/client_virtualreality.cpp
+++ b/mp/src/game/client/client_virtualreality.cpp
@@ -9,15 +9,21 @@
#include "client_virtualreality.h"
#include "materialsystem/itexture.h"
+#include "materialsystem/materialsystem_config.h"
#include "view_shared.h"
+#include "view_scene.h"
#include "VGuiMatSurface/IMatSystemSurface.h"
#include "vgui_controls/Controls.h"
-#include "headtrack/isourcevirtualreality.h"
+#include "sourcevr/isourcevirtualreality.h"
#include "ienginevgui.h"
#include "cdll_client_int.h"
+#include "vgui/IVGui.h"
+#include "vgui_controls/Controls.h"
#include "tier0/vprof_telemetry.h"
#include <time.h>
+const char *COM_GetModDirectory(); // return the mod dir (rather than the complete -game param, which can be a path)
+
CClientVirtualReality g_ClientVirtualReality;
EXPOSE_SINGLE_INTERFACE_GLOBALVAR( CClientVirtualReality, IClientVirtualReality,
CLIENTVIRTUALREALITY_INTERFACE_VERSION, g_ClientVirtualReality );
@@ -26,6 +32,9 @@ EXPOSE_SINGLE_INTERFACE_GLOBALVAR( CClientVirtualReality, IClientVirtualReality,
// --------------------------------------------------------------------
// A huge pile of VR convars
// --------------------------------------------------------------------
+ConVar vr_activate_default( "vr_activate_default", "0", FCVAR_ARCHIVE, "If this is true the game will switch to VR mode once startup is complete." );
+
+
ConVar vr_moveaim_mode ( "vr_moveaim_mode", "3", FCVAR_ARCHIVE, "0=move+shoot from face. 1=move with torso. 2,3,4=shoot with face+mouse cursor. 5+ are probably not that useful." );
ConVar vr_moveaim_mode_zoom ( "vr_moveaim_mode_zoom", "3", FCVAR_ARCHIVE, "0=move+shoot from face. 1=move with torso. 2,3,4=shoot with face+mouse cursor. 5+ are probably not that useful." );
@@ -54,21 +63,18 @@ ConVar vr_debug_remote_cam_target_z( "vr_debug_remote_cam_target_z", "-50.0" );
ConVar vr_translation_limit( "vr_translation_limit", "10.0", 0, "How far the in-game head will translate before being clamped." );
-ConVar vr_dont_use_calibration_projection ( "vr_dont_use_calibration_projection", "0", 0, "1=use calibrated rotation, but not projection" );
-
// HUD config values
ConVar vr_render_hud_in_world( "vr_render_hud_in_world", "1" );
ConVar vr_hud_max_fov( "vr_hud_max_fov", "60", FCVAR_ARCHIVE, "Max FOV of the HUD" );
ConVar vr_hud_forward( "vr_hud_forward", "500", FCVAR_ARCHIVE, "Apparent distance of the HUD in inches" );
ConVar vr_hud_display_ratio( "vr_hud_display_ratio", "0.95", FCVAR_ARCHIVE );
+ConVar vr_hud_never_overlay( "vr_hud_never_overlay", "0" );
ConVar vr_hud_axis_lock_to_world( "vr_hud_axis_lock_to_world", "0", FCVAR_ARCHIVE, "Bitfield - locks HUD axes to the world - 0=pitch, 1=yaw, 2=roll" );
// Default distance clips through rocketlauncher, heavy's body, etc.
ConVar vr_projection_znear_multiplier( "vr_projection_znear_multiplier", "0.3", 0, "Allows moving the ZNear plane to deal with body clipping" );
-ConVar vr_stat_sample_period ( "vr_stat_sample_period", "1", 0, "Frequency with which to sample motion stats" );
-
// Should the viewmodel (weapon) translate with the HMD, or remain fixed to the in-world body (but still rotate with the head)? Purely a graphics effect - no effect on actual bullet aiming.
// Has no effect in aim modes where aiming is not controlled by the head.
ConVar vr_viewmodel_translate_with_head ( "vr_viewmodel_translate_with_head", "0", 0, "1=translate the viewmodel with the head motion." );
@@ -80,16 +86,9 @@ ConVar vr_zoom_scope_scale ( "vr_zoom_scope_scale", "6.0", 0, "Something to do w
ConVar vr_viewmodel_offset_forward( "vr_viewmodel_offset_forward", "-8", 0 );
ConVar vr_viewmodel_offset_forward_large( "vr_viewmodel_offset_forward_large", "-15", 0 );
-ConVar vr_ipdtest_left_t ( "vr_ipdtest_left_t", "260", FCVAR_ARCHIVE );
-ConVar vr_ipdtest_left_b ( "vr_ipdtest_left_b", "530", FCVAR_ARCHIVE );
-ConVar vr_ipdtest_left_i ( "vr_ipdtest_left_i", "550", FCVAR_ARCHIVE );
-ConVar vr_ipdtest_left_o ( "vr_ipdtest_left_o", "200", FCVAR_ARCHIVE );
-ConVar vr_ipdtest_right_t ( "vr_ipdtest_right_t", "260", FCVAR_ARCHIVE );
-ConVar vr_ipdtest_right_b ( "vr_ipdtest_right_b", "530", FCVAR_ARCHIVE );
-ConVar vr_ipdtest_right_i ( "vr_ipdtest_right_i", "550", FCVAR_ARCHIVE );
-ConVar vr_ipdtest_right_o ( "vr_ipdtest_right_o", "200", FCVAR_ARCHIVE );
-
+ConVar vr_force_windowed ( "vr_force_windowed", "0", FCVAR_ARCHIVE );
+ConVar vr_first_person_uses_world_model ( "vr_first_person_uses_world_model", "1", 0, "Causes the third person model to be drawn instead of the view model" );
// --------------------------------------------------------------------
// Purpose: Cycle through the aim & move modes.
@@ -122,6 +121,32 @@ void CC_VR_Cycle_Aim_Move_Mode ( const CCommand& args )
static ConCommand vr_cycle_aim_move_mode("vr_cycle_aim_move_mode", CC_VR_Cycle_Aim_Move_Mode, "Cycle through the aim & move modes." );
+// --------------------------------------------------------------------
+// Purpose: Switch to/from VR mode.
+// --------------------------------------------------------------------
+CON_COMMAND( vr_activate, "Switch to VR mode" )
+{
+ g_ClientVirtualReality.Activate();
+}
+CON_COMMAND( vr_deactivate, "Switch from VR mode to normal mode" )
+{
+ g_ClientVirtualReality.Deactivate();
+}
+CON_COMMAND( vr_toggle, "Toggles VR mode" )
+{
+ if( g_pSourceVR )
+ {
+ if( g_pSourceVR->ShouldRunInVR() )
+ g_ClientVirtualReality.Deactivate();
+ else
+ g_ClientVirtualReality.Activate();
+ }
+ else
+ {
+ Msg( "VR Mode is not enabled.\n" );
+ }
+}
+
// --------------------------------------------------------------------
// Purpose: Returns true if the matrix is orthonormal
@@ -235,11 +260,9 @@ CClientVirtualReality::CClientVirtualReality()
m_rtLastMotionSample = 0;
m_bMotionUpdated = false;
- m_bIpdTestEnabled = false;
-
- // Needs to be after the tracker has initted.
- m_bIpdTestEnabled = false;
- m_IpdTestControl = 0;
+#if defined( USE_SDL )
+ m_nNonVRSDLDisplayIndex = 0;
+#endif
}
CClientVirtualReality::~CClientVirtualReality()
@@ -378,8 +401,8 @@ void CClientVirtualReality::DrawMainMenu()
viewEye[STEREO_EYE_RIGHT].y = rightY;
viewEye[STEREO_EYE_RIGHT].m_eStereoEye = STEREO_EYE_RIGHT;
- // let headtrack.dll tell us where to put the cameras
- ProcessCurrentTrackingState( 75.f );
+ // let sourcevr.dll tell us where to put the cameras
+ ProcessCurrentTrackingState( 0 );
Vector vViewModelOrigin;
QAngle qViewModelAngles;
OverrideView( &viewEye[ STEREO_EYE_MONO ] , &vViewModelOrigin, &qViewModelAngles, HMM_NOOVERRIDE );
@@ -388,21 +411,20 @@ void CClientVirtualReality::DrawMainMenu()
// render both eyes
for( int nView = STEREO_EYE_LEFT; nView <= STEREO_EYE_RIGHT; nView++ )
{
- // clear happens here probably
- render->Push3DView( viewEye[nView], VIEW_CLEAR_DEPTH|VIEW_CLEAR_COLOR, NULL, NULL );
-
- RenderHUDQuad( true, false );
+ CMatRenderContextPtr pRenderContext( materials );
+ PIXEvent pixEvent( pRenderContext, nView == STEREO_EYE_LEFT ? "left eye" : "right eye" );
+ ITexture *pColor = g_pSourceVR->GetRenderTarget( (ISourceVirtualReality::VREye)(nView-1), ISourceVirtualReality::RT_Color );
+ ITexture *pDepth = g_pSourceVR->GetRenderTarget( (ISourceVirtualReality::VREye)(nView-1), ISourceVirtualReality::RT_Depth );
+ render->Push3DView( viewEye[nView], VIEW_CLEAR_DEPTH|VIEW_CLEAR_COLOR, pColor, NULL, pDepth );
+ RenderHUDQuad( false, false );
render->PopView( NULL );
- }
- vrect_t rect;
- rect.x = rect.y = 0;
- rect.width = leftW*2;
- rect.height = leftH;
- PostProcessFrame( &rect );
-}
+ PostProcessFrame( (StereoEye_t)nView );
+ OverlayHUDQuadWithUndistort( viewEye[nView], true, true, false );
+ }
+}
// --------------------------------------------------------------------
@@ -449,8 +471,7 @@ bool CClientVirtualReality::OverrideView ( CViewSetup *pViewMiddle, Vector *pVie
QAngle torsoAngles = m_PlayerTorsoAngle;
VMatrix worldFromTorso;
- AngleMatrix ( torsoAngles, worldFromTorso.As3x4() );
- worldFromTorso.SetTranslation ( m_PlayerTorsoOrigin );
+ worldFromTorso.SetupMatrixOrgAngles( m_PlayerTorsoOrigin, torsoAngles );
//// Scale translation e.g. to allow big in-game leans with only a small head movement.
//// Clamp HMD movement to a reasonable amount to avoid wallhacks, vis problems, etc.
@@ -484,16 +505,14 @@ bool CClientVirtualReality::OverrideView ( CViewSetup *pViewMiddle, Vector *pVie
// Aim point is independent of view - leave it as it was, just copy it into m_WorldFromWeapon for our use.
m_TorsoFromMideye = matMideyeZeroFromMideyeCurrent;
m_WorldFromMidEye = worldFromTorso * matMideyeZeroFromMideyeCurrent;
- AngleMatrix ( originalMiddleAngles, m_WorldFromWeapon.As3x4() );
- m_WorldFromWeapon.SetTranslation ( originalMiddleOrigin );
+ m_WorldFromWeapon.SetupMatrixOrgAngles( originalMiddleOrigin, originalMiddleAngles );
break;
case HMM_SHOOTMOVELOOKMOUSE:
// HMD is ignored completely, mouse does everything.
m_PlayerTorsoAngle = originalMiddleAngles;
- AngleMatrix ( originalMiddleAngles, worldFromTorso.As3x4() );
- worldFromTorso.SetTranslation ( m_PlayerTorsoOrigin );
+ worldFromTorso.SetupMatrixOrgAngles( m_PlayerTorsoOrigin, originalMiddleAngles );
m_TorsoFromMideye.Identity();
m_WorldFromMidEye = worldFromTorso;
@@ -535,9 +554,8 @@ bool CClientVirtualReality::OverrideView ( CViewSetup *pViewMiddle, Vector *pVie
Vector vView = vLookat - vOffset;
VectorAngles ( vView, m_WorldFromMidEye.GetUp(), pViewMiddle->angles );
- AngleMatrix ( pViewMiddle->angles, m_WorldFromMidEye.As3x4() );
+ m_WorldFromMidEye.SetupMatrixOrgAngles( pViewMiddle->origin, pViewMiddle->angles );
- m_WorldFromMidEye.SetTranslation ( pViewMiddle->origin );
m_TorsoFromMideye.Identity();
}
@@ -584,47 +602,19 @@ bool CClientVirtualReality::OverrideStereoView( CViewSetup *pViewMiddle, CViewSe
return false;
}
- if ( vr_stereo_swap_eyes.GetBool() )
- {
- // Windows likes to randomly rename display numbers which causes eye-swaps, so this tries to cope with that.
- CViewSetup *pViewTemp = pViewLeft;
- pViewLeft = pViewRight;
- pViewRight = pViewTemp;
- }
-
- // Move eyes to calibrated positions.
- VMatrix worldFromLeftEye = m_WorldFromMidEye * g_pSourceVR->GetMidEyeFromLeft();
- VMatrix worldFromRightEye = m_WorldFromMidEye * g_pSourceVR->GetMidEyeFromRight();
-
- Assert ( IsOrthonormal ( worldFromLeftEye, 0.001f ) );
- Assert ( IsOrthonormal ( worldFromRightEye, 0.001f ) );
-
- Vector rightFromLeft = worldFromRightEye.GetTranslation() - worldFromLeftEye.GetTranslation();
- //float calibratedIPD = rightFromLeft.Length(); // THIS IS NOT CORRECT. The positions of the virtual cameras do have any real physical "meaning" with the way we currently calibrate.
- float calibratedIPD = g_pSourceVR->GetDisplaySeparationMM() / 25.4f;
+ VMatrix matOffsetLeft = g_pSourceVR->GetMidEyeFromEye( ISourceVirtualReality::VREye_Left );
+ VMatrix matOffsetRight = g_pSourceVR->GetMidEyeFromEye( ISourceVirtualReality::VREye_Right );
- // Scale the eyes closer/further to fit the desired IPD.
- // (the calibrated distance is the IPD of whoever calibrated it!)
- float desiredIPD = g_pSourceVR->GetUserIPDMM() / 25.4f;
- if ( calibratedIPD < 0.000001f )
- {
- // No HMD, or a monocular HMD.
- }
- else
- {
- float scale = 0.5f * ( desiredIPD - calibratedIPD ) / calibratedIPD;
- worldFromLeftEye.SetTranslation ( worldFromLeftEye.GetTranslation() - ( scale * rightFromLeft ) );
- worldFromRightEye.SetTranslation ( worldFromRightEye.GetTranslation() + ( scale * rightFromLeft ) );
- }
+ // Move eyes to IPD positions.
+ VMatrix worldFromLeftEye = m_WorldFromMidEye * matOffsetLeft;
+ VMatrix worldFromRightEye = m_WorldFromMidEye * matOffsetRight;
Assert ( IsOrthonormal ( worldFromLeftEye, 0.001f ) );
Assert ( IsOrthonormal ( worldFromRightEye, 0.001f ) );
// Finally convert back to origin+angles.
- pViewLeft->origin = worldFromLeftEye.GetTranslation();
- VectorAngles ( worldFromLeftEye.GetForward(), worldFromLeftEye.GetUp(), pViewLeft->angles );
- pViewRight->origin = worldFromRightEye.GetTranslation();
- VectorAngles ( worldFromRightEye.GetForward(), worldFromRightEye.GetUp(), pViewRight->angles );
+ MatrixAngles( worldFromLeftEye.As3x4(), pViewLeft->angles, pViewLeft->origin );
+ MatrixAngles( worldFromRightEye.As3x4(), pViewRight->angles, pViewRight->origin );
// Find the projection matrices.
@@ -645,13 +635,6 @@ bool CClientVirtualReality::OverrideStereoView( CViewSetup *pViewMiddle, CViewSe
}
}
- if ( vr_dont_use_calibration_projection.GetBool() )
- {
- pViewLeft ->m_bViewToProjectionOverride = false;
- pViewRight ->m_bViewToProjectionOverride = false;
- pViewMiddle->m_bViewToProjectionOverride = false;
- }
-
switch ( vr_stereo_mono_set_eye.GetInt() )
{
case 0:
@@ -683,6 +666,17 @@ bool CClientVirtualReality::OverrideStereoView( CViewSetup *pViewMiddle, CViewSe
CalcFovFromProjection ( &(pViewRight ->fov), pViewRight ->m_ViewToProjection );
CalcFovFromProjection ( &(pViewMiddle->fov), pViewMiddle->m_ViewToProjection );
+ // if we don't know the HUD FOV, figure that out now
+ if( m_fHudHorizontalFov == 0.f )
+ {
+ // Figure out the current HUD FOV.
+ m_fHudHorizontalFov = pViewLeft->fov * vr_hud_display_ratio.GetFloat();
+ if( m_fHudHorizontalFov > vr_hud_max_fov.GetFloat() )
+ {
+ m_fHudHorizontalFov = vr_hud_max_fov.GetFloat();
+ }
+ }
+
// remember the view angles so we can limit the weapon to something near those
m_PlayerViewAngle = pViewMiddle->angles;
m_PlayerViewOrigin = pViewMiddle->origin;
@@ -701,7 +695,6 @@ bool CClientVirtualReality::OverrideStereoView( CViewSetup *pViewMiddle, CViewSe
m_fHudHalfHeight = tan( DEG2RAD( fVFOV * 0.5f ) ) * fHudForward * m_WorldZoomScale;
QAngle HudAngles;
- VMatrix HudUpCorrection;
switch ( m_hmmMovementActual )
{
case HMM_SHOOTFACE_MOVETORSO:
@@ -709,7 +702,6 @@ bool CClientVirtualReality::OverrideStereoView( CViewSetup *pViewMiddle, CViewSe
// This helps keep you oriented about where "forwards" is, which is otherwise surprisingly tricky!
// TODO: try preserving roll and/or pitch from the view?
HudAngles = m_PlayerTorsoAngle;
- HudUpCorrection.Identity();
break;
case HMM_SHOOTFACE_MOVEFACE:
case HMM_SHOOTMOUSE_MOVEFACE:
@@ -720,7 +712,6 @@ bool CClientVirtualReality::OverrideStereoView( CViewSetup *pViewMiddle, CViewSe
case HMM_SHOOTBOUNDEDMOUSE_LOOKFACE_MOVEMOUSE:
// Put the HUD in front of wherever the player is looking.
HudAngles = m_PlayerViewAngle;
- HudUpCorrection = g_pSourceVR->GetHudUpCorrection();
break;
default: Assert ( false ); break;
}
@@ -742,9 +733,7 @@ bool CClientVirtualReality::OverrideStereoView( CViewSetup *pViewMiddle, CViewSe
MatrixAngles( m_WorldFromWeapon.As3x4(), aimAngles );
HudAngles[YAW] = aimAngles[YAW];
}
- AngleMatrix ( HudAngles, m_WorldFromHud.As3x4() );
- m_WorldFromHud.SetTranslation ( m_PlayerViewOrigin );
- m_WorldFromHud = m_WorldFromHud * HudUpCorrection;
+ m_WorldFromHud.SetupMatrixOrgAngles( m_PlayerViewOrigin, HudAngles );
// Remember in source X forwards, Y left, Z up.
// We need to transform to a more conventional X right, Y up, Z backwards before doing the projection.
@@ -806,8 +795,8 @@ bool CClientVirtualReality::OverridePlayerMotion( float flInputSampleFrametime,
{
// Figure out what changes were made to the WEAPON by mouse/joystick/etc
VMatrix worldFromOldWeapon, worldFromCurWeapon;
- AngleMatrix ( oldAngles, worldFromOldWeapon.As3x4() );
- AngleMatrix ( curAngles, worldFromCurWeapon.As3x4() );
+ worldFromOldWeapon.SetupMatrixAngles( oldAngles );
+ worldFromCurWeapon.SetupMatrixAngles( curAngles );
// We ignore mouse pitch, the mouse can't do rolls, so it's just yaw changes.
if( !m_bOverrideTorsoAngle )
@@ -817,7 +806,7 @@ bool CClientVirtualReality::OverridePlayerMotion( float flInputSampleFrametime,
m_PlayerTorsoAngle[PITCH] = 0.0f;
}
- AngleMatrix ( m_PlayerTorsoAngle, worldFromTorso.As3x4() );
+ worldFromTorso.SetupMatrixAngles( m_PlayerTorsoAngle );
// Weapon view = mideye view, so apply that to the torso to find the world view direction.
m_WorldFromWeapon = worldFromTorso * m_TorsoFromMideye;
@@ -846,10 +835,8 @@ bool CClientVirtualReality::OverridePlayerMotion( float flInputSampleFrametime,
}
// Let every other system know.
- AngleMatrix( *pNewAngles, m_WorldFromWeapon.As3x4() );
- AngleMatrix( m_PlayerTorsoAngle, worldFromTorso.As3x4() );
- // Restore the translation.
- m_WorldFromWeapon.SetTranslation ( vWeaponOrigin );
+ m_WorldFromWeapon.SetupMatrixOrgAngles( vWeaponOrigin, *pNewAngles );
+ worldFromTorso.SetupMatrixAngles( m_PlayerTorsoAngle );
}
break;
case HMM_SHOOTBOUNDEDMOUSE_LOOKFACE_MOVEFACE:
@@ -913,10 +900,8 @@ bool CClientVirtualReality::OverridePlayerMotion( float flInputSampleFrametime,
}
// Let every other system know.
- AngleMatrix( *pNewAngles, m_WorldFromWeapon.As3x4() );
- AngleMatrix( m_PlayerTorsoAngle, worldFromTorso.As3x4() );
- // Restore the translation.
- m_WorldFromWeapon.SetTranslation ( vWeaponOrigin );
+ m_WorldFromWeapon.SetupMatrixOrgAngles( vWeaponOrigin, *pNewAngles );
+ worldFromTorso.SetupMatrixAngles( m_PlayerTorsoAngle );
}
break;
case HMM_SHOOTMOUSE_MOVEFACE:
@@ -942,10 +927,8 @@ bool CClientVirtualReality::OverridePlayerMotion( float flInputSampleFrametime,
m_PlayerTorsoAngle[ YAW ] += AngleDiff( curAngles[YAW], oldAngles[YAW] ) /2.f;
}
- AngleMatrix( *pNewAngles, m_WorldFromWeapon.As3x4() );
- AngleMatrix( m_PlayerTorsoAngle, worldFromTorso.As3x4() );
- // Restore the translation.
- m_WorldFromWeapon.SetTranslation ( vWeaponOrigin );
+ m_WorldFromWeapon.SetupMatrixOrgAngles( vWeaponOrigin, *pNewAngles );
+ worldFromTorso.SetupMatrixAngles( m_PlayerTorsoAngle );
}
break;
default: Assert ( false ); break;
@@ -1007,101 +990,6 @@ bool CClientVirtualReality::OverridePlayerMotion( float flInputSampleFrametime,
return true;
}
-
-// --------------------------------------------------------------------
-// Purpose: Collects convar and HMD state once a session
-// --------------------------------------------------------------------
-bool CClientVirtualReality::CollectSessionStartStats( KeyValues *pkvStats )
-{
- pkvStats->SetName( "TF2VRSessionDetails" );
-
- CUtlString sSerialNumber = g_pSourceVR->GetDisplaySerialNumber();
- if( sSerialNumber.IsValid() && !sSerialNumber.IsEmpty() )
- {
- pkvStats->SetString( "SerialNumber", sSerialNumber.Get() );
- }
- CUtlString sModelNumber = g_pSourceVR->GetDisplayModelNumber();
- if( sModelNumber.IsValid() && !sModelNumber.IsEmpty() )
- {
- pkvStats->SetString( "ModelNumberID", sModelNumber.Get() );
- }
-
- pkvStats->SetFloat( "vr_separation_user_inches", g_pSourceVR->GetUserIPDMM() / 25.4f );
- //pkvStats->SetFloat( "vr_separation_toein_pixels", vr_separation_toein_pixels.GetFloat() );
- //pkvStats->SetInt( "vr_moveaim_mode", vr_moveaim_mode.GetInt() );
- //pkvStats->SetFloat( "vr_moveaim_reticle_yaw_limit", vr_moveaim_reticle_yaw_limit.GetFloat() );
- //pkvStats->SetFloat( "vr_moveaim_reticle_pitch_limit", vr_moveaim_reticle_pitch_limit.GetFloat() );
- //pkvStats->SetInt( "vr_moveaim_mode_zoom", vr_moveaim_mode_zoom.GetInt() );
- //pkvStats->SetFloat( "vr_moveaim_reticle_yaw_limit_zoom", vr_moveaim_reticle_yaw_limit_zoom.GetFloat() );
- //pkvStats->SetFloat( "vr_moveaim_reticle_pitch_limit_zoom", vr_moveaim_reticle_pitch_limit_zoom.GetFloat() );
- //pkvStats->SetFloat( "vr_hud_max_fov", vr_hud_max_fov.GetFloat() );
- //pkvStats->SetFloat( "vr_hud_forward", vr_hud_forward.GetFloat() );
- //pkvStats->SetFloat( "vr_neckmodel_up", vr_neckmodel_up.GetFloat() );
- //pkvStats->SetFloat( "vr_neckmodel_forwards", vr_neckmodel_forwards.GetFloat() );
- //pkvStats->SetInt( "vr_hud_axis_lock_to_world", vr_hud_axis_lock_to_world.GetInt() );
-
- //pkvStats->SetInt( "vr_ipdtest_left_t", vr_ipdtest_left_t.GetInt() );
- //pkvStats->SetInt( "vr_ipdtest_left_b", vr_ipdtest_left_b.GetInt() );
- //pkvStats->SetInt( "vr_ipdtest_left_i", vr_ipdtest_left_i.GetInt() );
- //pkvStats->SetInt( "vr_ipdtest_left_o", vr_ipdtest_left_o.GetInt() );
- //pkvStats->SetInt( "vr_ipdtest_right_t", vr_ipdtest_right_t.GetInt() );
- //pkvStats->SetInt( "vr_ipdtest_right_b", vr_ipdtest_right_b.GetInt() );
- //pkvStats->SetInt( "vr_ipdtest_right_i", vr_ipdtest_right_i.GetInt() );
- //pkvStats->SetInt( "vr_ipdtest_right_o", vr_ipdtest_right_o.GetInt() );
-
- return true;
-}
-
-
-// --------------------------------------------------------------------
-// Purpose: Collects view stats every so often
-// --------------------------------------------------------------------
-bool CClientVirtualReality::CollectPeriodicStats( KeyValues *pkvStats )
-{
- // maybe we haven't even been called to get tracking data
- if( !m_bMotionUpdated )
- return false;
- m_bMotionUpdated = false;
-
- uint32 unPeriod = (uint32) vr_stat_sample_period.GetInt();
- if( unPeriod == 0 )
- return false; // periodic stats are turned off
-
- RTime32 rtCurrent = time(NULL);
- if( rtCurrent == m_rtLastMotionSample && ( rtCurrent - m_rtLastMotionSample ) < unPeriod )
- return false; // it isn't time to report yet
-
- pkvStats->SetName( "TF2VRMotionSample" );
-
- pkvStats->SetInt( "SampleTime", rtCurrent );
-
- Vector vPos;
- QAngle viewAngles;
- MatrixAngles( m_WorldFromMidEye.As3x4(), viewAngles, vPos );
-
- pkvStats->SetFloat( "LookYaw", viewAngles[YAW] );
- pkvStats->SetFloat( "LookPitch", viewAngles[PITCH] );
- pkvStats->SetFloat( "LookRoll", viewAngles[ROLL] );
- pkvStats->SetFloat( "PositionX", vPos.x );
- pkvStats->SetFloat( "PositionY", vPos.y );
- pkvStats->SetFloat( "PositionZ", vPos.z );
-
- pkvStats->SetFloat( "VelocityX", m_PlayerLastMovement.x );
- pkvStats->SetFloat( "VelocityY", m_PlayerLastMovement.y );
- pkvStats->SetFloat( "VelocityZ", m_PlayerLastMovement.z );
-
- QAngle aimAngles;
- MatrixAngles( m_WorldFromWeapon.As3x4(), aimAngles );
-
- pkvStats->SetFloat( "AimYaw", aimAngles[YAW] );
- pkvStats->SetFloat( "AimPitch", aimAngles[PITCH] );
-
- m_rtLastMotionSample = rtCurrent;
-
- return true;
-}
-
-
// --------------------------------------------------------------------
// Purpose: Returns true if the world is zoomed
// --------------------------------------------------------------------
@@ -1154,6 +1042,19 @@ void CClientVirtualReality::CancelTorsoTransformOverride()
}
+bool CClientVirtualReality::CanOverlayHudQuad()
+{
+ bool bCanOverlay = true;
+
+ bCanOverlay = bCanOverlay && vr_render_hud_in_world.GetBool();
+ bCanOverlay = bCanOverlay && ( ! vr_hud_never_overlay.GetBool() );
+ bCanOverlay = bCanOverlay && ( vr_hud_axis_lock_to_world.GetInt() == 0 );
+ bCanOverlay = bCanOverlay && ( m_hmmMovementActual != HMM_SHOOTFACE_MOVETORSO );
+
+ return bCanOverlay;
+}
+
+
// --------------------------------------------------------------------
// Purpose: Returns the bounds in world space where the game should
// position the HUD.
@@ -1177,6 +1078,10 @@ void CClientVirtualReality::GetHUDBounds( Vector *pViewer, Vector *pUL, Vector *
// --------------------------------------------------------------------
void CClientVirtualReality::RenderHUDQuad( bool bBlackout, bool bTranslucent )
{
+ // If we can overlay the HUD directly onto the target later, we'll do that instead (higher image quality).
+ if ( CanOverlayHudQuad() )
+ return;
+
Vector vHead, vUL, vUR, vLL, vLR;
GetHUDBounds ( &vHead, &vUL, &vUR, &vLL, &vLR );
@@ -1304,14 +1209,6 @@ float CClientVirtualReality::GetZoomedModeMagnification()
// --------------------------------------------------------------------
bool CClientVirtualReality::ProcessCurrentTrackingState( float fGameFOV )
{
- // Figure out the current HUD FOV.
- m_fHudHorizontalFov = g_pSourceVR->GetHorizontalFOVDegrees() * vr_hud_display_ratio.GetFloat();
- if( m_fHudHorizontalFov > vr_hud_max_fov.GetFloat() )
- {
- m_fHudHorizontalFov = vr_hud_max_fov.GetFloat();
- }
-
-
m_WorldZoomScale = 1.0f;
if ( fGameFOV != 0.0f )
{
@@ -1397,8 +1294,7 @@ void CClientVirtualReality::AlignTorsoAndViewToWeapon()
if( !UseVR() )
return;
- VRTrackerState_t state = g_pSourceVR->GetTrackerState();
- if( state.bWillDriftInYaw )
+ if( g_pSourceVR->WillDriftInYaw() )
{
m_iAlignTorsoAndViewToWeaponCountdown = 2;
}
@@ -1408,291 +1304,202 @@ void CClientVirtualReality::AlignTorsoAndViewToWeapon()
// --------------------------------------------------------------------
// Purpose: Lets VR do stuff at the very end of the rendering process
// --------------------------------------------------------------------
-void CClientVirtualReality::PostProcessFrame( const vrect_t *SrcRect )
+void CClientVirtualReality::PostProcessFrame( StereoEye_t eEye )
{
if( !UseVR() )
return;
- g_pSourceVR->DoDistortionProcessing( SrcRect );
-
- if ( m_bIpdTestEnabled )
- {
- DrawIpdCalibration ( SrcRect );
- }
+ g_pSourceVR->DoDistortionProcessing( eEye == STEREO_EYE_LEFT ? ISourceVirtualReality::VREye_Left : ISourceVirtualReality::VREye_Right );
}
-//-----------------------------------------------------------------------------
-// Calibration UI
-//-----------------------------------------------------------------------------
+// --------------------------------------------------------------------
+// Pastes the HUD directly onto the backbuffer / render target.
+// (higher quality than the RenderHUDQuad() path but can't always be used)
+// --------------------------------------------------------------------
+void CClientVirtualReality::OverlayHUDQuadWithUndistort( const CViewSetup &eyeView, bool bDoUndistort, bool bBlackout, bool bTranslucent )
+{
+ if ( ! UseVR() )
+ return;
+
+ // If we can't overlay the HUD, it will be handled on another path (rendered into the scene with RenderHUDQuad()).
+ if ( ! CanOverlayHudQuad() )
+ return;
+
+ // Get the position of the HUD quad in world space as used by RenderHUDQuad(). Then convert to a rectangle in normalized
+ // device coordinates.
+ Vector vHead, vUL, vUR, vLL, vLR;
+ GetHUDBounds ( &vHead, &vUL, &vUR, &vLL, &vLR );
-// These control the conversion of IPD from pixels to inches.
-ConVar vr_ipdtest_interp_ipd_start_pixels ( "vr_ipdtest_interp_ipd_start_pixels", "491.0", 0 );
-ConVar vr_ipdtest_interp_ipd_start_inches ( "vr_ipdtest_interp_ipd_start_inches", "2.717", 0 ); // 69mm
-ConVar vr_ipdtest_interp_ipd_end_pixels ( "vr_ipdtest_interp_ipd_end_pixels", "602.0", 0 );
-ConVar vr_ipdtest_interp_ipd_end_inches ( "vr_ipdtest_interp_ipd_end_inches", "2.205", 0 ); // 56mm
+ VMatrix worldToView, viewToProjection, worldToProjection, worldToPixels;
+ render->GetMatricesForView( eyeView, &worldToView, &viewToProjection, &worldToProjection, &worldToPixels );
-// These numbers need to be filled in from physical tests. Right now they are placeholder.
-ConVar vr_ipdtest_interp_relief_start_pixels ( "vr_ipdtest_interp_relief_start_pixels", "400.0", 0 );
-ConVar vr_ipdtest_interp_relief_start_inches ( "vr_ipdtest_interp_relief_start_inches", "0.0", 0 );
-ConVar vr_ipdtest_interp_relief_end_pixels ( "vr_ipdtest_interp_relief_end_pixels", "600.0", 0 );
-ConVar vr_ipdtest_interp_relief_end_inches ( "vr_ipdtest_interp_relief_end_inches", "1.0", 0 );
+ Vector pUL, pUR, pLL, pLR;
+ worldToProjection.V3Mul( vUL, pUL );
+ worldToProjection.V3Mul( vUR, pUR );
+ worldToProjection.V3Mul( vLL, pLL );
+ worldToProjection.V3Mul( vLR, pLR );
+ float ndcHudBounds[4];
+ ndcHudBounds[0] = Min ( Min( pUL.x, pUR.x ), Min( pLL.x, pLR.x ) );
+ ndcHudBounds[1] = Min ( Min( pUL.y, pUR.y ), Min( pLL.y, pLR.y ) );
+ ndcHudBounds[2] = Max ( Max( pUL.x, pUR.x ), Max( pLL.x, pLR.x ) );
+ ndcHudBounds[3] = Max ( Max( pUL.y, pUR.y ), Max( pLL.y, pLR.y ) );
+ ISourceVirtualReality::VREye sourceVrEye = ( eyeView.m_eStereoEye == STEREO_EYE_LEFT ) ? ISourceVirtualReality::VREye_Left : ISourceVirtualReality::VREye_Right;
-float Interpolate ( float fIn, float fInStart, float fInEnd, float fOutStart, float fOutEnd )
-{
- float fLamdba = ( fIn - fInStart ) / ( fInEnd - fInStart );
- float fOut = fOutStart + fLamdba * ( fOutEnd - fOutStart );
- return fOut;
+ g_pSourceVR->CompositeHud ( sourceVrEye, ndcHudBounds, bDoUndistort, bBlackout, bTranslucent );
}
-void CClientVirtualReality::RecalcEyeCalibration ( TEyeCalibration *p )
+
+// --------------------------------------------------------------------
+// Purpose: Switches to VR mode
+// --------------------------------------------------------------------
+void CClientVirtualReality::Activate()
{
- int iDisplayWidth, iDisplayHeight;
- bool bSuccess = g_pSourceVR->GetWindowSize ( &iDisplayWidth, &iDisplayHeight );
- Assert ( bSuccess );
- if ( bSuccess )
+ // we can only do this if a headtrack DLL is loaded
+ if( !g_pSourceVR )
+ return;
+
+ // see if VR mode is even enabled
+ if( materials->GetCurrentConfigForVideoCard().m_nVRModeAdapter == -1 )
{
- // Eye relief.
- // Many ways to take the average eye size. But since the top edge is hard to find (strains the eyes, and there's problems with glasses), let's just use the difference between left and right.
- p->Left.fSizePixels = (float)( p->Left.iIn - p->Left.iOut );
- p->Right.fSizePixels = (float)( p->Right.iIn - p->Right.iOut );
- // ...not that we have any data yet, nor do we know what to do with it if we had it.
- float fLeftInches = Interpolate ( p->Left.fSizePixels,
- vr_ipdtest_interp_relief_start_pixels.GetFloat(),
- vr_ipdtest_interp_relief_end_pixels.GetFloat(),
- vr_ipdtest_interp_relief_start_inches.GetFloat(),
- vr_ipdtest_interp_relief_end_inches.GetFloat() );
- p->Left.fReliefInches = fLeftInches;
- float fRightInches = Interpolate ( p->Right.fSizePixels,
- vr_ipdtest_interp_relief_start_pixels.GetFloat(),
- vr_ipdtest_interp_relief_end_pixels.GetFloat(),
- vr_ipdtest_interp_relief_start_inches.GetFloat(),
- vr_ipdtest_interp_relief_end_inches.GetFloat() );
- p->Right.fReliefInches = fRightInches;
-
- // Calculate IPD
- // In and Out are both measured from the nearest edge of the display, i.e. the left ones from the left edge, the right ones from the right edge.
- float fLeftMid = (float)( p->Left.iIn + p->Left.iOut ) * 0.5f;
- float fRightMid = (float)( p->Right.iIn + p->Right.iOut ) * 0.5f;
- // An outside value of 0 is the first actual pixel on the outer edge of the display.
- // So if both values are 0, the two lines are (iDisplayWidth-1) apart.
- float fSeparationInPixels = (float)( iDisplayWidth - 1 ) - fLeftMid - fRightMid;
- float fIpdInches = Interpolate ( fSeparationInPixels,
- vr_ipdtest_interp_ipd_start_pixels.GetFloat(),
- vr_ipdtest_interp_ipd_end_pixels.GetFloat(),
- vr_ipdtest_interp_ipd_start_inches.GetFloat(),
- vr_ipdtest_interp_ipd_end_inches.GetFloat() );
- p->fIpdInches = fIpdInches;
- p->fIpdPixels = fSeparationInPixels;
+ Warning( "Enable VR mode in the video options before trying to use it.\n" );
+ return;
}
-}
+ // See if we have an actual adapter
+ int32 nVRModeAdapter = g_pSourceVR->GetVRModeAdapter();
+ if( nVRModeAdapter == -1 )
+ {
+ Warning( "Unable to get VRMode adapter from OpenVR. VR mode cannot be enabled. Try restarting and then enabling VR again.\n" );
+ return;
+ }
-void CClientVirtualReality::GetCurrentEyeCalibration ( TEyeCalibration *p )
-{
- p->Left.iTop = vr_ipdtest_left_t.GetInt();
- p->Left.iBot = vr_ipdtest_left_b.GetInt();
- p->Left.iIn = vr_ipdtest_left_i.GetInt();
- p->Left.iOut = vr_ipdtest_left_o.GetInt();
- p->Right.iTop = vr_ipdtest_right_t.GetInt();
- p->Right.iBot = vr_ipdtest_right_b.GetInt();
- p->Right.iIn = vr_ipdtest_right_i.GetInt();
- p->Right.iOut = vr_ipdtest_right_o.GetInt();
- RecalcEyeCalibration ( p );
- m_IpdTestCurrent = *p;
-}
+ // we can only activate if we've got a VR device
+ if( materials->GetCurrentConfigForVideoCard().m_nVRModeAdapter != nVRModeAdapter )
+ {
+ Warning( "VR Mode expects adapter %d which is different from %d which we are currently using. Try restarting and enabling VR mode again.\n",
+ nVRModeAdapter, materials->GetCurrentConfigForVideoCard().m_nVRModeAdapter );
+ engine->ExecuteClientCmd( "mat_enable_vrmode 0\n" );
+ return;
+ }
-void CClientVirtualReality::SetCurrentEyeCalibration ( TEyeCalibration const &p )
-{
- m_IpdTestCurrent = p;
- RecalcEyeCalibration ( &m_IpdTestCurrent );
- g_pSourceVR->SetUserIPDMM( m_IpdTestCurrent.fIpdInches * 25.4f );
- vr_ipdtest_left_t.SetValue ( m_IpdTestCurrent.Left.iTop );
- vr_ipdtest_left_b.SetValue ( m_IpdTestCurrent.Left.iBot );
- vr_ipdtest_left_i.SetValue ( m_IpdTestCurrent.Left.iIn );
- vr_ipdtest_left_o.SetValue ( m_IpdTestCurrent.Left.iOut );
- vr_ipdtest_right_t.SetValue ( m_IpdTestCurrent.Right.iTop );
- vr_ipdtest_right_b.SetValue ( m_IpdTestCurrent.Right.iBot );
- vr_ipdtest_right_i.SetValue ( m_IpdTestCurrent.Right.iIn );
- vr_ipdtest_right_o.SetValue ( m_IpdTestCurrent.Right.iOut );
-
-#ifdef _DEBUG
- Warning ( " TBIO: left %d %d %d %d: right %d %d %d %d: %f inches\n", // Need the spaces to center it so I can read it!
- m_IpdTestCurrent.Left.iTop,
- m_IpdTestCurrent.Left.iBot,
- m_IpdTestCurrent.Left.iIn,
- m_IpdTestCurrent.Left.iOut,
- m_IpdTestCurrent.Right.iTop,
- m_IpdTestCurrent.Right.iBot,
- m_IpdTestCurrent.Right.iIn,
- m_IpdTestCurrent.Right.iOut,
- m_IpdTestCurrent.fIpdInches );
+
+ // can't activate twice
+ if( UseVR() )
+ return;
+
+ // remember where we were
+ m_bNonVRWindowed = g_pMaterialSystem->GetCurrentConfigForVideoCard().Windowed();
+ vgui::surface()->GetScreenSize( m_nNonVRWidth, m_nNonVRHeight );
+#if defined( USE_SDL )
+ static ConVarRef sdl_displayindex( "sdl_displayindex" );
+ m_nNonVRSDLDisplayIndex = sdl_displayindex.GetInt();
#endif
-}
-void CClientVirtualReality::SetEyeCalibrationDisplayMisc ( int iEditingNum, bool bVisible )
-{
- if( bVisible && !m_bIpdTestEnabled )
+ if( !g_pSourceVR->Activate() )
{
- // if we're being shown, read out the current config from the convars
- GetCurrentEyeCalibration ( &m_IpdTestCurrent );
+ // we couldn't activate, so just punt on this whole thing
+ return;
}
- m_IpdTestControl = iEditingNum;
- m_bIpdTestEnabled = bVisible;
-}
+ // general all-game stuff
+ engine->ExecuteClientCmd( "mat_reset_rendertargets\n" );
+ // game specific VR config
+ CUtlString sCmd;
+ sCmd.Format( "exec sourcevr_%s.cfg\n", COM_GetModDirectory() );
+ engine->ExecuteClientCmd( sCmd.Get() );
-void CClientVirtualReality::DrawIpdCalibration ( const vrect_t *SrcRect )
-{
- int ControlNum = m_IpdTestControl;
- int WhichEdges = 0;
- bool bShowLeft = false;
- bool bShowRight = false;
- switch ( ControlNum )
+ vgui::surface()->SetSoftwareCursor( true );
+
+#if defined(POSIX)
+ ConVarRef m_rawinput( "m_rawinput" );
+ m_bNonVRRawInput = m_rawinput.GetBool();
+ m_rawinput.SetValue( 1 );
+
+ ConVarRef mat_vsync( "mat_vsync" );
+ mat_vsync.SetValue( 0 );
+#endif
+
+ g_pMatSystemSurface->ForceScreenSizeOverride(true, 640, 480 );
+ int nViewportWidth, nViewportHeight;
+
+ g_pSourceVR->GetViewportBounds( ISourceVirtualReality::VREye_Left, NULL, NULL, &nViewportWidth, &nViewportHeight );
+ vgui::surface()->SetFullscreenViewportAndRenderTarget( 0, 0, nViewportWidth, nViewportHeight, g_pSourceVR->GetRenderTarget( ISourceVirtualReality::VREye_Left, ISourceVirtualReality::RT_Color ) );
+
+ vgui::ivgui()->SetVRMode( true );
+
+ VRRect_t rect;
+ if( g_pSourceVR->GetDisplayBounds( &rect ) )
{
- case 0: case 1: case 2: case 3:
- bShowLeft = true;
- WhichEdges = 1 << ControlNum;
- break;
- case 4: case 5: case 6: case 7:
- bShowRight = true;
- WhichEdges = 1 << ControlNum;
- break;
- case 8:
- // Adjust IPD directly.
- bShowLeft = true;
- bShowRight = true;
- WhichEdges = 0x33;
- break;
- case 9:
- // Left relief.
- bShowLeft = true;
- WhichEdges = 0xff;
- break;
- case 10:
- // Right relief.
- bShowRight = true;
- WhichEdges = 0xff;
- break;
- default:
- Assert ( false );
- break;
+
+ // set mode
+ char szCmd[ 256 ];
+ Q_snprintf( szCmd, sizeof( szCmd ), "mat_setvideomode %i %i %i\n", rect.nWidth, rect.nHeight, vr_force_windowed.GetBool()? 1 : 0 );
+ engine->ClientCmd_Unrestricted( szCmd );
}
+}
- CMatRenderContextPtr pRenderContext( materials );
- //pRenderContext->ClearColor4ub ( 0, 0, 0, 0 );
- //pRenderContext->ClearBuffers ( true, true );
+void CClientVirtualReality::Deactivate()
+{
+ // can't deactivate when we aren't active
+ if( !UseVR() )
+ return;
- IMaterial *pMaterial = materials->FindMaterial ( "debug/debugtranslucentsinglecolor", TEXTURE_GROUP_OTHER, true );
- pMaterial->ColorModulate( 1.0f, 1.0f, 1.0f );
- pMaterial->AlphaModulate( 1.0f );
+ g_pSourceVR->Deactivate();
- const int Border = 4;
- const int BlueStart = 10; // Well, it used to be blue, now it isn't.
- const int BlueSize = 30;
+ g_pMatSystemSurface->ForceScreenSizeOverride(false, 0, 0 );
+ g_pMaterialSystem->GetRenderContext()->Viewport( 0, 0, m_nNonVRWidth, m_nNonVRHeight );
+ vgui::surface()->SetFullscreenViewportAndRenderTarget( 0, 0, m_nNonVRWidth, m_nNonVRHeight, NULL );
- // You want a pure green for the "current" edge so that it has no chromatic aberration smearing (i.e. white is a terrible choice!)
- // The non-current lines can be a different colour because you're not actively tuning them.
-#define SET_COLOR1(num) if ( 0 != ( WhichEdges & (1<<(num)) ) ) { pMaterial->ColorModulate( 0.0f, 1.0f, 0.0f ); } else { pMaterial->ColorModulate( 0.25f, 0.25f, 0.25f ); }
-#define SET_COLOR2(num) if ( 0 != ( WhichEdges & (1<<(num)) ) ) { pMaterial->ColorModulate( 1.0f, 1.0f, 1.0f ); } else { pMaterial->ColorModulate( 0.0f, 0.0f, 0.0f ); }
+ static ConVarRef cl_software_cursor( "cl_software_cursor" );
+ vgui::surface()->SetSoftwareCursor( cl_software_cursor.GetBool() );
- if ( bShowLeft )
+#if defined( USE_SDL )
+ static ConVarRef sdl_displayindex( "sdl_displayindex" );
+ sdl_displayindex.SetValue( m_nNonVRSDLDisplayIndex );
+#endif
+
+#if defined(POSIX)
+ ConVarRef m_rawinput( "m_rawinput" );
+ m_rawinput.SetValue( m_bNonVRRawInput );
+#endif
+
+ // Make sure the client .dll root panel is at the proper point before doing the "SolveTraverse" calls
+ vgui::VPANEL root = enginevgui->GetPanel( PANEL_CLIENTDLL );
+ if ( root != 0 )
{
- int t = m_IpdTestCurrent.Left.iTop;
- int b = m_IpdTestCurrent.Left.iBot;
- int l = m_IpdTestCurrent.Left.iOut;
- int r = m_IpdTestCurrent.Left.iIn;
-
- // Render a black rect to enhance contrast.
- pMaterial->ColorModulate( 0.0f, 0.0f, 0.0f );
- pMaterial->AlphaModulate( 1.0f );
-
- pRenderContext->DrawScreenSpaceRectangle ( pMaterial, l-Border-1, t-Border-1, r-l+Border*2+3, Border*2+3, 0.0f, 0.0f, 0.0f, 0.0f, 16, 16 );
- pRenderContext->DrawScreenSpaceRectangle ( pMaterial, l-Border-1, b-Border-1, r-l+Border*2+3, Border*2+3, 0.0f, 0.0f, 0.0f, 0.0f, 16, 16 );
- pRenderContext->DrawScreenSpaceRectangle ( pMaterial, l-Border-1, t-Border-1, Border*2+3, b-t+Border*2+3, 0.0f, 0.0f, 0.0f, 0.0f, 16, 16 );
- pRenderContext->DrawScreenSpaceRectangle ( pMaterial, r-Border-1, t-Border-1, Border*2+3, b-t+Border*2+3, 0.0f, 0.0f, 0.0f, 0.0f, 16, 16 );
-
- int cx = (l+r)/2;
- int cy = (t+b)/2;
-
- // For each side, draw the line along the side, and also a line "pointing to" it from the middle.
- // Left
- SET_COLOR1(1);
- pRenderContext->DrawScreenSpaceRectangle ( pMaterial, l, t, 1, b-t+1, 0.0f, 0.0f, 0.0f, 0.0f, 16, 16 );
- SET_COLOR2(1);
- pRenderContext->DrawScreenSpaceRectangle ( pMaterial, l+BlueStart, cy-1, BlueSize, 3, 0.0f, 0.0f, 0.0f, 0.0f, 16, 16 );
-
- // Right
- SET_COLOR1(0);
- pRenderContext->DrawScreenSpaceRectangle ( pMaterial, r, t, 1, b-t+1, 0.0f, 0.0f, 0.0f, 0.0f, 16, 16 );
- SET_COLOR2(0);
- pRenderContext->DrawScreenSpaceRectangle ( pMaterial, r-BlueStart-BlueSize, cy-1, BlueSize, 3, 0.0f, 0.0f, 0.0f, 0.0f, 16, 16 );
-
- // Top
- SET_COLOR1(2);
- pRenderContext->DrawScreenSpaceRectangle ( pMaterial, l, t, r-l+1, 1, 0.0f, 0.0f, 0.0f, 0.0f, 16, 16 );
- SET_COLOR2(2);
- pRenderContext->DrawScreenSpaceRectangle ( pMaterial, cx-1, t+BlueStart, 3, BlueSize, 0.0f, 0.0f, 0.0f, 0.0f, 16, 16 );
-
- // Bottom
- SET_COLOR1(3);
- pRenderContext->DrawScreenSpaceRectangle ( pMaterial, l, b, r-l+1, 1, 0.0f, 0.0f, 0.0f, 0.0f, 16, 16 );
- SET_COLOR2(3);
- pRenderContext->DrawScreenSpaceRectangle ( pMaterial, cx-1, b-BlueStart-BlueSize, 3, BlueSize, 0.0f, 0.0f, 0.0f, 0.0f, 16, 16 );
+ vgui::ipanel()->SetSize( root, m_nNonVRWidth, m_nNonVRHeight );
}
-
- if ( bShowRight )
+ // Same for client .dll tools
+ root = enginevgui->GetPanel( PANEL_CLIENTDLL_TOOLS );
+ if ( root != 0 )
{
- int t = m_IpdTestCurrent.Right.iTop;
- int b = m_IpdTestCurrent.Right.iBot;
- // An outside value of 0 is the first actual pixel on the edge of the display. So if both values are 0, the two lines are (SrcRect->width - 1) apart.
- int l = SrcRect->width - 1 - m_IpdTestCurrent.Right.iIn;
- int r = SrcRect->width - 1 - m_IpdTestCurrent.Right.iOut;
-
- // Render a black rect to enhance contrast.
- pMaterial->ColorModulate( 0.0f, 0.0f, 0.0f );
- pMaterial->AlphaModulate( 1.0f );
-
- pRenderContext->DrawScreenSpaceRectangle ( pMaterial, l-Border-1, t-Border-1, r-l+Border*2+3, Border*2+3, 0.0f, 0.0f, 0.0f, 0.0f, 16, 16 );
- pRenderContext->DrawScreenSpaceRectangle ( pMaterial, l-Border-1, b-Border-1, r-l+Border*2+3, Border*2+3, 0.0f, 0.0f, 0.0f, 0.0f, 16, 16 );
- pRenderContext->DrawScreenSpaceRectangle ( pMaterial, l-Border-1, t-Border-1, Border*2+3, b-t+Border*2+3, 0.0f, 0.0f, 0.0f, 0.0f, 16, 16 );
- pRenderContext->DrawScreenSpaceRectangle ( pMaterial, r-Border-1, t-Border-1, Border*2+3, b-t+Border*2+3, 0.0f, 0.0f, 0.0f, 0.0f, 16, 16 );
-
- int cx = (l+r)/2;
- int cy = (t+b)/2;
-
- // For each side, draw the line along the side, and also a line "pointing to" it from the middle.
- // Left
- SET_COLOR1(4);
- pRenderContext->DrawScreenSpaceRectangle ( pMaterial, l, t, 1, b-t+1, 0.0f, 0.0f, 0.0f, 0.0f, 16, 16 );
- SET_COLOR2(4);
- pRenderContext->DrawScreenSpaceRectangle ( pMaterial, l+BlueStart, cy-1, BlueSize, 3, 0.0f, 0.0f, 0.0f, 0.0f, 16, 16 );
-
- // Right
- SET_COLOR1(5);
- pRenderContext->DrawScreenSpaceRectangle ( pMaterial, r, t, 1, b-t+1, 0.0f, 0.0f, 0.0f, 0.0f, 16, 16 );
- SET_COLOR2(5);
- pRenderContext->DrawScreenSpaceRectangle ( pMaterial, r-BlueStart-BlueSize, cy-1, BlueSize, 3, 0.0f, 0.0f, 0.0f, 0.0f, 16, 16 );
-
- // Top
- SET_COLOR1(6);
- pRenderContext->DrawScreenSpaceRectangle ( pMaterial, l, t, r-l+1, 1, 0.0f, 0.0f, 0.0f, 0.0f, 16, 16 );
- SET_COLOR2(6);
- pRenderContext->DrawScreenSpaceRectangle ( pMaterial, cx-1, t+BlueStart, 3, BlueSize, 0.0f, 0.0f, 0.0f, 0.0f, 16, 16 );
-
- // Bottom
- SET_COLOR1(7);
- pRenderContext->DrawScreenSpaceRectangle ( pMaterial, l, b, r-l+1, 1, 0.0f, 0.0f, 0.0f, 0.0f, 16, 16 );
- SET_COLOR2(7);
- pRenderContext->DrawScreenSpaceRectangle ( pMaterial, cx-1, b-BlueStart-BlueSize, 3, BlueSize, 0.0f, 0.0f, 0.0f, 0.0f, 16, 16 );
+ vgui::ipanel()->SetSize( root, m_nNonVRWidth, m_nNonVRHeight );
}
- return;
+ int viewWidth, viewHeight;
+ vgui::surface()->GetScreenSize( viewWidth, viewHeight );
+
+ engine->ExecuteClientCmd( "mat_reset_rendertargets\n" );
+
+ // set mode
+ char szCmd[ 256 ];
+ Q_snprintf( szCmd, sizeof( szCmd ), "mat_setvideomode %i %i %i\n", m_nNonVRWidth, m_nNonVRHeight, m_bNonVRWindowed ? 1 : 0 );
+ engine->ClientCmd_Unrestricted( szCmd );
+
+}
+
+
+// Called when startup is complete
+void CClientVirtualReality::StartupComplete()
+{
+ if( vr_activate_default.GetBool() )
+ Activate();
}
diff --git a/mp/src/game/client/client_virtualreality.h b/mp/src/game/client/client_virtualreality.h
index c06c6527..9aadfeb3 100644
--- a/mp/src/game/client/client_virtualreality.h
+++ b/mp/src/game/client/client_virtualreality.h
@@ -14,6 +14,7 @@
#include "tier3/tier3.h"
#include "iclientvirtualreality.h"
+#include "view_shared.h"
enum HeadtrackMovementMode_t
{
@@ -34,20 +35,6 @@ enum HeadtrackMovementMode_t
};
-// used for interacting with the calibration UI
-struct TEyeCalibration
-{
- struct TEyeEdges
- {
- int iTop, iBot, iIn, iOut; // These are used to calculate everything else.
- float fSizePixels;
- float fReliefInches;
- } Left, Right;
-
- float fIpdPixels;
- float fIpdInches;
-};
-
//-----------------------------------------------------------------------------
// The implementation
//-----------------------------------------------------------------------------
@@ -77,6 +64,8 @@ public:
virtual InitReturnVal_t Init();
virtual void Shutdown();
+ // Called when startup is complete
+ void StartupComplete();
//---------------------------------------------------------
// IClientVirtualReality implementation
@@ -94,6 +83,7 @@ public:
bool CurrentlyZoomed();
void OverrideTorsoTransform( const Vector & position, const QAngle & angles ) ;
void CancelTorsoTransformOverride( ) ;
+ bool CanOverlayHudQuad();
void GetHUDBounds( Vector *pViewer, Vector *pUL, Vector *pUR, Vector *pLL, Vector *pLR );
void RenderHUDQuad( bool bBlackout, bool bTranslucent );
float GetZoomedModeMagnification();
@@ -105,23 +95,14 @@ public:
const VMatrix & GetWorldFromMidEye() const { return m_WorldFromMidEyeNoDebugCam; }
void OverrideViewModelTransform( Vector & vmorigin, QAngle & vmangles, bool bUseLargeOverride );
void AlignTorsoAndViewToWeapon();
- void PostProcessFrame( const vrect_t *SrcRect );
+ void PostProcessFrame( StereoEye_t eEye );
+ void OverlayHUDQuadWithUndistort( const CViewSetup &view, bool bDoUndistort, bool bBlackout, bool bTranslucent );
//---------------------------------------------------------
- // Stat collection
+ // Enter/leave VR mode
//---------------------------------------------------------
- bool CollectSessionStartStats( KeyValues *pkvStats );
- bool CollectPeriodicStats( KeyValues *pkvStats );
-
- //---------------------------------------------------------
- // IPD Calibration
- //---------------------------------------------------------
- void DrawIpdCalibration ( const vrect_t *SrcRect );
-
- void RecalcEyeCalibration ( TEyeCalibration *p );
- void GetCurrentEyeCalibration ( TEyeCalibration *p );
- void SetCurrentEyeCalibration ( TEyeCalibration const &p );
- void SetEyeCalibrationDisplayMisc ( int iEditingNum, bool bVisible );
+ void Activate();
+ void Deactivate();
private:
HeadtrackMovementMode_t m_hmmMovementActual;
@@ -169,11 +150,14 @@ private:
RTime32 m_rtLastMotionSample;
- // IPD test fields
- bool m_bIpdTestEnabled;
- int m_IpdTestControl;
- TEyeCalibration m_IpdTestCurrent;
-
+ // video mode we had before we entered VR mode
+ bool m_bNonVRWindowed;
+ int m_nNonVRWidth;
+ int m_nNonVRHeight;
+#if defined( USE_SDL )
+ int m_nNonVRSDLDisplayIndex;
+#endif
+ bool m_bNonVRRawInput;
};
extern CClientVirtualReality g_ClientVirtualReality;
diff --git a/mp/src/game/client/clientmode_shared.cpp b/mp/src/game/client/clientmode_shared.cpp
index a1d1127d..b6dee29c 100644
--- a/mp/src/game/client/clientmode_shared.cpp
+++ b/mp/src/game/client/clientmode_shared.cpp
@@ -36,7 +36,7 @@
#include <vgui/ILocalize.h>
#include "hud_vote.h"
#include "ienginevgui.h"
-#include "headtrack/isourcevirtualreality.h"
+#include "sourcevr/isourcevirtualreality.h"
#if defined( _X360 )
#include "xbox/xbox_console.h"
#endif
@@ -208,6 +208,7 @@ static void __MsgFunc_VGUIMenu( bf_read &msg )
if ( count > 0 )
{
KeyValues *keys = new KeyValues("data");
+ //Msg( "MsgFunc_VGUIMenu:\n" );
for ( int i=0; i<count; i++)
{
@@ -216,10 +217,25 @@ static void __MsgFunc_VGUIMenu( bf_read &msg )
msg.ReadString( name, sizeof(name) );
msg.ReadString( data, sizeof(data) );
+ //Msg( " %s <- '%s'\n", name, data );
keys->SetString( name, data );
}
+ // !KLUDGE! Whitelist of URL protocols formats for MOTD
+ if (
+ !V_stricmp( panelname, PANEL_INFO ) // MOTD
+ && keys->GetInt( "type", 0 ) == 2 // URL message type
+ ) {
+ const char *pszURL = keys->GetString( "msg", "" );
+ if ( Q_strncmp( pszURL, "http://", 7 ) != 0 && Q_strncmp( pszURL, "https://", 8 ) != 0 )
+ {
+ Warning( "Blocking MOTD URL '%s'; must begin with 'http://' or 'https://'\n", pszURL );
+ keys->deleteThis();
+ return;
+ }
+ }
+
viewport->SetData( keys );
keys->deleteThis();
@@ -496,7 +512,7 @@ bool ClientModeShared::ShouldBlackoutAroundHUD()
//-----------------------------------------------------------------------------
-// Purpose: Allows the client mode to override mouse control stuff in headtrack
+// Purpose: Allows the client mode to override mouse control stuff in sourcevr
//-----------------------------------------------------------------------------
HeadtrackMovementMode_t ClientModeShared::ShouldOverrideHeadtrackControl()
{
diff --git a/mp/src/game/client/clientmode_shared.h b/mp/src/game/client/clientmode_shared.h
index ae784c00..27336964 100644
--- a/mp/src/game/client/clientmode_shared.h
+++ b/mp/src/game/client/clientmode_shared.h
@@ -132,6 +132,7 @@ public:
virtual bool IsInfoPanelAllowed() OVERRIDE { return true; }
virtual void InfoPanelDisplayed() OVERRIDE { }
+ virtual bool IsHTMLInfoPanelAllowed() OVERRIDE { return true; }
protected:
CBaseViewport *m_pViewport;
diff --git a/mp/src/game/client/game_controls/vguitextwindow.cpp b/mp/src/game/client/game_controls/vguitextwindow.cpp
index 450fa07c..5cdc2532 100644
--- a/mp/src/game/client/game_controls/vguitextwindow.cpp
+++ b/mp/src/game/client/game_controls/vguitextwindow.cpp
@@ -9,6 +9,7 @@
#include "vguitextwindow.h"
#include <networkstringtabledefs.h>
#include <cdll_client_int.h>
+#include <clientmode_shared.h>
#include <vgui/IScheme.h>
#include <vgui/ILocalize.h>
@@ -165,8 +166,15 @@ void CTextWindow::ShowText( const char *text )
void CTextWindow::ShowURL( const char *URL, bool bAllowUserToDisable )
{
#if defined( ENABLE_CHROMEHTMLWINDOW )
- if ( bAllowUserToDisable && cl_disablehtmlmotd.GetBool() )
+ #ifdef _DEBUG
+ Msg( "CTextWindow::ShowURL( %s )\n", URL );
+ #endif
+
+ ClientModeShared *mode = ( ClientModeShared * )GetClientModeNormal();
+ if ( ( bAllowUserToDisable && cl_disablehtmlmotd.GetBool() ) || !mode->IsHTMLInfoPanelAllowed() )
{
+ Warning( "Blocking HTML info panel '%s'; Using plaintext instead.\n", URL );
+
// User has disabled HTML TextWindows. Show the fallback as text only.
if ( g_pStringTableInfoPanel )
{
@@ -289,7 +297,15 @@ void CTextWindow::Update( void )
}
else if ( m_nContentType == TYPE_URL )
{
- ShowURL( m_szMessage );
+ if ( !Q_strncmp( m_szMessage, "http://", 7 ) || !Q_strncmp( m_szMessage, "https://", 8 ) || !Q_stricmp( m_szMessage, "about:blank" ) )
+ {
+ ShowURL( m_szMessage );
+ }
+ else
+ {
+ // We should have trapped this at a higher level
+ Assert( !"URL protocol is missing or blocked" );
+ }
}
else if ( m_nContentType == TYPE_FILE )
{
diff --git a/mp/src/game/client/hl2/hud_autoaim.cpp b/mp/src/game/client/hl2/hud_autoaim.cpp
index 3339a72f..aa808acf 100644
--- a/mp/src/game/client/hl2/hud_autoaim.cpp
+++ b/mp/src/game/client/hl2/hud_autoaim.cpp
@@ -146,6 +146,7 @@ void CHUDAutoAim::VidInit( void )
//-----------------------------------------------------------------------------
bool CHUDAutoAim::ShouldDraw( void )
{
+#ifndef HL1_CLIENT_DLL
C_BaseHLPlayer *pLocalPlayer = (C_BaseHLPlayer *)C_BasePlayer::GetLocalPlayer();
if ( pLocalPlayer )
{
@@ -154,6 +155,7 @@ bool CHUDAutoAim::ShouldDraw( void )
return false;
}
}
+#endif
return ( (hud_draw_fixed_reticle.GetBool() || hud_draw_active_reticle.GetBool()) && CHudElement::ShouldDraw() && !engine->IsDrawingLoadingImage() );
}
diff --git a/mp/src/game/client/hl2/hud_damageindicator.cpp b/mp/src/game/client/hl2/hud_damageindicator.cpp
index 86debdf7..48dd9b62 100644
--- a/mp/src/game/client/hl2/hud_damageindicator.cpp
+++ b/mp/src/game/client/hl2/hud_damageindicator.cpp
@@ -20,7 +20,7 @@
#include "IEffects.h"
#include "hudelement.h"
#include "clienteffectprecachesystem.h"
-#include "headtrack/isourcevirtualreality.h"
+#include "sourcevr/isourcevirtualreality.h"
using namespace vgui;
diff --git a/mp/src/game/client/hl2/hud_weaponselection.cpp b/mp/src/game/client/hl2/hud_weaponselection.cpp
index 3d857e99..9d223169 100644
--- a/mp/src/game/client/hl2/hud_weaponselection.cpp
+++ b/mp/src/game/client/hl2/hud_weaponselection.cpp
@@ -451,6 +451,17 @@ void CHudWeaponSelection::Paint()
if ( !pSelectedWeapon )
return;
+ bool bPushedViewport = false;
+ if( hud_fastswitch.GetInt() == HUDTYPE_FASTSWITCH || hud_fastswitch.GetInt() == HUDTYPE_PLUS )
+ {
+ CMatRenderContextPtr pRenderContext( materials );
+ if( pRenderContext->GetRenderTarget() )
+ {
+ surface()->PushFullscreenViewport();
+ bPushedViewport = true;
+ }
+ }
+
// interpolate the selected box size between the small box size and the large box size
// interpolation has been removed since there is no weapon pickup animation anymore, so it's all at the largest size
float percentageDone = 1.0f; //min(1.0f, (gpGlobals->curtime - m_flPickupStartTime) / m_flWeaponPickupGrowTime);
@@ -727,6 +738,11 @@ void CHudWeaponSelection::Paint()
}
break;
}
+
+ if( bPushedViewport )
+ {
+ surface()->PopFullscreenViewport();
+ }
}
@@ -1025,8 +1041,6 @@ void CHudWeaponSelection::ApplySchemeSettings(vgui::IScheme *pScheme)
{
SetBounds( x, y, screenWide - x, screenTall - y );
}
-
- SetForceStereoRenderToFrameBuffer( true );
}
//-----------------------------------------------------------------------------
diff --git a/mp/src/game/client/hud_basedeathnotice.cpp b/mp/src/game/client/hud_basedeathnotice.cpp
index b3f494b6..d732bd05 100644
--- a/mp/src/game/client/hud_basedeathnotice.cpp
+++ b/mp/src/game/client/hud_basedeathnotice.cpp
@@ -114,7 +114,8 @@ void CHudBaseDeathNotice::Paint()
DeathNoticeItem &msg = m_DeathNotices[i];
CHudTexture *icon = msg.iconDeath;
-
+ CHudTexture *iconPrekiller = msg.iconPreKiller;
+
wchar_t victim[256]=L"";
wchar_t killer[256]=L"";
@@ -125,10 +126,15 @@ void CHudBaseDeathNotice::Paint()
int iVictimTextWide = UTIL_ComputeStringWidth( m_hTextFont, victim ) + xSpacing;
int iDeathInfoTextWide= msg.wzInfoText[0] ? UTIL_ComputeStringWidth( m_hTextFont, msg.wzInfoText ) + xSpacing : 0;
+ int iDeathInfoEndTextWide= msg.wzInfoTextEnd[0] ? UTIL_ComputeStringWidth( m_hTextFont, msg.wzInfoTextEnd ) + xSpacing : 0;
+
int iKillerTextWide = killer[0] ? UTIL_ComputeStringWidth( m_hTextFont, killer ) + xSpacing : 0;
int iLineTall = m_flLineHeight;
int iTextTall = surface()->GetFontTall( m_hTextFont );
int iconWide = 0, iconTall = 0, iDeathInfoOffset = 0, iVictimTextOffset = 0, iconActualWide = 0;
+
+ int iPreKillerTextWide = msg.wzPreKillerText[0] ? UTIL_ComputeStringWidth( m_hTextFont, msg.wzPreKillerText ) - xSpacing : 0;
+ int iconPrekillerWide = 0, iconPrekillerActualWide = 0, iconPreKillerTall = 0;
// Get the local position for this notice
if ( icon )
@@ -145,7 +151,25 @@ void CHudBaseDeathNotice::Paint()
iconTall *= flScale;
iconWide *= flScale;
}
- int iTotalWide = iKillerTextWide + iconWide + iVictimTextWide + iDeathInfoTextWide + ( xMargin * 2 );
+
+ if ( iconPrekiller )
+ {
+ iconPrekillerActualWide = iconPrekiller->EffectiveWidth( 1.0f );
+ iconPrekillerWide = iconPrekillerActualWide;
+ iconPreKillerTall = iconPrekiller->EffectiveHeight( 1.0f );
+
+ int iconTallDesired = iLineTall-YRES(2);
+ Assert( 0 != iconTallDesired );
+ float flScale = (float) iconTallDesired / (float) iconPreKillerTall;
+
+ iconPrekillerActualWide *= flScale;
+ iconPreKillerTall *= flScale;
+ iconPrekillerWide *= flScale;
+ }
+
+ int iTotalWide = iKillerTextWide + iconWide + iVictimTextWide + iDeathInfoTextWide + iDeathInfoEndTextWide + ( xMargin * 2 );
+ iTotalWide += iconPrekillerWide + iPreKillerTextWide;
+
int y = yStart + ( ( iLineTall + m_flLineSpacing ) * i );
int yText = y + ( ( iLineTall - iTextTall ) / 2 );
int yIcon = y + ( ( iLineTall - iconTall ) / 2 );
@@ -160,11 +184,11 @@ void CHudBaseDeathNotice::Paint()
Vertex_t vert[NUM_BACKGROUND_COORD];
GetBackgroundPolygonVerts( x, y+1, x+iTotalWide, y+iLineTall-1, ARRAYSIZE( vert ), vert );
surface()->DrawSetTexture( -1 );
- surface()->DrawSetColor( msg.bLocalPlayerInvolved ? m_clrLocalBGColor : m_clrBaseBGColor );
+ surface()->DrawSetColor( GetBackgroundColor ( i ) );
surface()->DrawTexturedPolygon( ARRAYSIZE( vert ), vert );
x += xMargin;
-
+
if ( killer[0] )
{
// Draw killer's name
@@ -172,6 +196,22 @@ void CHudBaseDeathNotice::Paint()
x += iKillerTextWide;
}
+ // prekiller text
+ if ( msg.wzPreKillerText[0] )
+ {
+ x += xSpacing;
+ DrawText( x + iDeathInfoOffset, yText, m_hTextFont, GetInfoTextColor( i ), msg.wzPreKillerText );
+ x += iPreKillerTextWide;
+ }
+
+ // Prekiller icon
+ if ( iconPrekiller )
+ {
+ int yPreIconTall = y + ( ( iLineTall - iconPreKillerTall ) / 2 );
+ iconPrekiller->DrawSelf( x, yPreIconTall, iconPrekillerActualWide, iconPreKillerTall, m_clrIcon );
+ x += iconPrekillerWide + xSpacing;
+ }
+
// Draw glow behind weapon icon to show it was a crit death
if ( msg.bCrit && msg.iconCritDeath )
{
@@ -194,13 +234,19 @@ void CHudBaseDeathNotice::Paint()
iVictimTextOffset -= iDeathInfoTextWide;
}
- DrawText( x + iDeathInfoOffset, yText, m_hTextFont, GetInfoTextColor( msg.bLocalPlayerInvolved ), msg.wzInfoText );
+ DrawText( x + iDeathInfoOffset, yText, m_hTextFont, GetInfoTextColor( i ), msg.wzInfoText );
x += iDeathInfoTextWide;
}
// Draw victims name
DrawText( x + iVictimTextOffset, yText, m_hTextFont, GetTeamColor( msg.Victim.iTeam, msg.bLocalPlayerInvolved ), victim );
x += iVictimTextWide;
+
+ // Draw Additional Text on the end of the victims name
+ if ( msg.wzInfoTextEnd[0] )
+ {
+ DrawText( x , yText, m_hTextFont, GetInfoTextColor( i ), msg.wzInfoTextEnd );
+ }
}
}
@@ -358,7 +404,12 @@ void CHudBaseDeathNotice::FireGameEvent( IGameEvent *event )
bLocalPlayerInvolved = true;
}
- if ( event->GetInt( "damagebits" ) & DMG_CRITICAL )
+ if ( event->GetInt( "death_flags" ) & TF_DEATH_AUSTRALIUM )
+ {
+ m_DeathNotices[iMsg].bCrit= true;
+ m_DeathNotices[iMsg].iconCritDeath = GetIcon( "d_australium", bLocalPlayerInvolved ? kDeathNoticeIcon_Inverted : kDeathNoticeIcon_Standard );
+ }
+ else if ( event->GetInt( "damagebits" ) & DMG_CRITICAL )
{
m_DeathNotices[iMsg].bCrit= true;
m_DeathNotices[iMsg].iconCritDeath = GetIcon( "d_crit", bLocalPlayerInvolved ? kDeathNoticeIcon_Inverted : kDeathNoticeIcon_Standard );
diff --git a/mp/src/game/client/hud_basedeathnotice.h b/mp/src/game/client/hud_basedeathnotice.h
index 7bd3bb56..2a9da0c5 100644
--- a/mp/src/game/client/hud_basedeathnotice.h
+++ b/mp/src/game/client/hud_basedeathnotice.h
@@ -30,6 +30,7 @@ struct DeathNoticeItem
{
szIcon[0]=0;
wzInfoText[0]=0;
+ wzInfoTextEnd[0]=0;
iconDeath = NULL;
iconCritDeath = NULL;
bSelfInflicted = false;
@@ -40,6 +41,9 @@ struct DeathNoticeItem
iWeaponID = -1;
iKillerID = -1;
iVictimID = -1;
+
+ iconPreKiller = NULL;
+ wzPreKillerText[0] = 0;
}
float GetExpiryTime();
@@ -48,8 +52,13 @@ struct DeathNoticeItem
DeathNoticePlayer Victim;
char szIcon[32]; // name of icon to display
wchar_t wzInfoText[32]; // any additional text to display next to icon
+ wchar_t wzInfoTextEnd[32]; // any additional text to display next to victim name
CHudTexture *iconDeath;
CHudTexture *iconCritDeath; // crit background icon
+
+ CHudTexture *iconPreKiller;
+ wchar_t wzPreKillerText[32];
+
bool bSelfInflicted;
bool bLocalPlayerInvolved;
bool bCrit;
@@ -104,7 +113,8 @@ protected:
virtual int UseExistingNotice( IGameEvent *event ) { return -1; }
void GetLocalizedControlPointName( IGameEvent *event, char *namebuf, int namelen );
- virtual Color GetInfoTextColor( bool bLocalPlayerInvolved ){ return Color( 255, 255, 255, 255 ); }
+ virtual Color GetInfoTextColor( int iDeathNoticeMsg ){ return Color( 255, 255, 255, 255 ); }
+ virtual Color GetBackgroundColor ( int iDeathNoticeMsg ) { return m_DeathNotices[iDeathNoticeMsg].bLocalPlayerInvolved ? m_clrLocalBGColor : m_clrBaseBGColor; }
CPanelAnimationVarAliasType( float, m_flLineHeight, "LineHeight", "16", "proportional_float" );
CPanelAnimationVarAliasType( float, m_flLineSpacing, "LineSpacing", "4", "proportional_float" );
@@ -115,6 +125,7 @@ protected:
CPanelAnimationVar( Color, m_clrIcon, "IconColor", "255 80 0 255" );
CPanelAnimationVar( Color, m_clrBaseBGColor, "BaseBackgroundColor", "46 43 42 220" );
CPanelAnimationVar( Color, m_clrLocalBGColor, "LocalBackgroundColor", "245 229 196 200" );
+ CPanelAnimationVar( Color, m_clrKillStreakBg, "KillStreakBackgroundColor", "224 223 219 200" );
CUtlVector<DeathNoticeItem> m_DeathNotices;
diff --git a/mp/src/game/client/hud_crosshair.cpp b/mp/src/game/client/hud_crosshair.cpp
index 5327d23b..fc7714fe 100644
--- a/mp/src/game/client/hud_crosshair.cpp
+++ b/mp/src/game/client/hud_crosshair.cpp
@@ -16,7 +16,7 @@
#include "materialsystem/imaterialsystem.h"
#include "VGuiMatSurface/IMatSystemSurface.h"
#include "client_virtualreality.h"
-#include "headtrack/isourcevirtualreality.h"
+#include "sourcevr/isourcevirtualreality.h"
#ifdef SIXENSE
#include "sixense/in_sixense.h"
diff --git a/mp/src/game/client/hud_vote.cpp b/mp/src/game/client/hud_vote.cpp
index 7a88bb22..55b8f389 100644
--- a/mp/src/game/client/hud_vote.cpp
+++ b/mp/src/game/client/hud_vote.cpp
@@ -1059,6 +1059,10 @@ void CHudVote::MsgFunc_CallVoteFailed( bf_read &msg )
case VOTE_FAILED_CANNOT_KICK_DURING_ROUND:
m_pCallVoteFailed->SetControlString( "FailedReason", "#GameUI_vote_failed_round_active" );
break;
+
+ case VOTE_FAILED_MODIFICATION_ALREADY_ACTIVE:
+ m_pCallVoteFailed->SetControlString( "FailedReason", "#GameUI_vote_failed_event_already_active" );
+ break;
}
}
diff --git a/mp/src/game/client/iclientmode.h b/mp/src/game/client/iclientmode.h
index 5bf7aedb..2b74f625 100644
--- a/mp/src/game/client/iclientmode.h
+++ b/mp/src/game/client/iclientmode.h
@@ -147,6 +147,7 @@ public:
virtual bool IsInfoPanelAllowed() = 0;
virtual void InfoPanelDisplayed() = 0;
+ virtual bool IsHTMLInfoPanelAllowed() = 0;
};
extern IClientMode *g_pClientMode;
diff --git a/mp/src/game/client/in_main.cpp b/mp/src/game/client/in_main.cpp
index 9cb7cd31..21eb30a0 100644
--- a/mp/src/game/client/in_main.cpp
+++ b/mp/src/game/client/in_main.cpp
@@ -31,7 +31,7 @@
#endif
#include "client_virtualreality.h"
-#include "headtrack/isourcevirtualreality.h"
+#include "sourcevr/isourcevirtualreality.h"
// NVNT Include
#include "haptics/haptic_utils.h"
diff --git a/mp/src/game/client/replay/vgui/replayperformanceeditor.cpp b/mp/src/game/client/replay/vgui/replayperformanceeditor.cpp
index 781a5c37..99178f6e 100644
--- a/mp/src/game/client/replay/vgui/replayperformanceeditor.cpp
+++ b/mp/src/game/client/replay/vgui/replayperformanceeditor.cpp
@@ -1185,6 +1185,7 @@ CReplayPerformanceEditorPanel::CReplayPerformanceEditorPanel( Panel *parent, Rep
m_nRedBlueSigns[0] = -1;
m_nRedBlueSigns[1] = 1;
m_iCurPlayerTarget = -1;
+ m_bCurrentTargetNeedsVisibilityUpdate = false;
m_pImageList = new ImageList( false );
@@ -1737,6 +1738,19 @@ void CReplayPerformanceEditorPanel::OnTick()
pCamera->SetPrimaryTarget( m_iCurPlayerTarget );
}
+ // fixes a case where the replay would be paused and the player would cycle cameras but the
+ // target's visibility wouldn't be updated until the replay was unpaused (they would be invisible)
+ if ( m_bCurrentTargetNeedsVisibilityUpdate )
+ {
+ C_BaseEntity *pTarget = ClientEntityList().GetEnt( pCamera->GetPrimaryTargetIndex() );
+ if ( pTarget )
+ {
+ pTarget->UpdateVisibility();
+ }
+
+ m_bCurrentTargetNeedsVisibilityUpdate = false;
+ }
+
// If in free-cam mode, add set view event if we're not paused
if ( bInAControllableCameraMode && m_bShownAtLeastOnce && bRecording )
{
@@ -2444,12 +2458,14 @@ void CReplayPerformanceEditorPanel::OnCommand( const char *command )
{
ReplayCamera()->SetMode( OBS_MODE_IN_EYE );
UpdateCameraSelectionPosition( CAM_FIRST );
+ m_bCurrentTargetNeedsVisibilityUpdate = true;
g_pReplayPerformanceController->AddEvent_Camera_Change_FirstPerson( flCurTime, nEntIndex );
}
else if ( !V_stricmp( pCamType, "third" ) )
{
ReplayCamera()->SetMode( OBS_MODE_CHASE );
UpdateCameraSelectionPosition( CAM_THIRD );
+ m_bCurrentTargetNeedsVisibilityUpdate = true;
g_pReplayPerformanceController->AddEvent_Camera_Change_ThirdPerson( flCurTime, nEntIndex );
AddSetViewEvent();
}
@@ -2457,6 +2473,7 @@ void CReplayPerformanceEditorPanel::OnCommand( const char *command )
{
ReplayCamera()->SetMode( OBS_MODE_ROAMING );
UpdateCameraSelectionPosition( CAM_FREE );
+ m_bCurrentTargetNeedsVisibilityUpdate = true;
g_pReplayPerformanceController->AddEvent_Camera_Change_Free( flCurTime );
AddSetViewEvent();
DisplayPerformanceTip( "#Replay_PerfTip_EnterFreeCam", &replay_perftip_count_freecam_enter, MAX_TIP_DISPLAYS );
diff --git a/mp/src/game/client/replay/vgui/replayperformanceeditor.h b/mp/src/game/client/replay/vgui/replayperformanceeditor.h
index 50a96d09..034843a3 100644
--- a/mp/src/game/client/replay/vgui/replayperformanceeditor.h
+++ b/mp/src/game/client/replay/vgui/replayperformanceeditor.h
@@ -224,6 +224,8 @@ private:
float m_flActiveTimeInEditor; // Will be zero'd out if user is idle (ie if they don't press space bar often enough)
CPanelAnimationVarAliasType( int, m_nRightMarginWidth, "right_margin_width", "0", "proportional_xpos" );
+
+ bool m_bCurrentTargetNeedsVisibilityUpdate;
};
//-----------------------------------------------------------------------------
diff --git a/mp/src/game/client/sixense/in_sixense.cpp b/mp/src/game/client/sixense/in_sixense.cpp
index 2988201f..e0f4ba39 100644
--- a/mp/src/game/client/sixense/in_sixense.cpp
+++ b/mp/src/game/client/sixense/in_sixense.cpp
@@ -62,7 +62,7 @@ using sixenseMath::Line;
#include "iinput.h"
#include "game/client/iviewport.h"
#include "filesystem.h"
-#include "headtrack/isourcevirtualreality.h"
+#include "sourcevr/isourcevirtualreality.h"
#ifdef TF_CLIENT_DLL
#include "tf_hud_menu_engy_build.h"
diff --git a/mp/src/game/client/view.cpp b/mp/src/game/client/view.cpp
index b282b5c3..333a2756 100644
--- a/mp/src/game/client/view.cpp
+++ b/mp/src/game/client/view.cpp
@@ -36,13 +36,14 @@
#include "materialsystem/itexture.h"
#include "materialsystem/imaterialsystem.h"
#include "materialsystem/materialsystem_config.h"
+#include "VGuiMatSurface/IMatSystemSurface.h"
#include "toolframework_client.h"
#include "tier0/icommandline.h"
#include "ienginevgui.h"
#include <vgui_controls/Controls.h>
#include <vgui/ISurface.h>
#include "ScreenSpaceEffects.h"
-#include "headtrack/isourcevirtualreality.h"
+#include "sourcevr/isourcevirtualreality.h"
#include "client_virtualreality.h"
#if defined( REPLAY_ENABLED )
@@ -84,10 +85,6 @@ extern ConVar sensitivity;
ConVar zoom_sensitivity_ratio( "zoom_sensitivity_ratio", "1.0", 0, "Additional mouse sensitivity scale factor applied when FOV is zoomed in." );
-#ifdef STAGING_ONLY
-ConVar vr_stereo_debug_viewport( "vr_stereo_debug_viewport", "0" );
-#endif
-
CViewRender g_DefaultViewRender;
IViewRender *view = NULL; // set in cldll_client_init.cpp if no mod creates their own
@@ -301,16 +298,6 @@ void CViewRender::Init( void )
m_pDrawEntities = cvar->FindVar( "r_drawentities" );
m_pDrawBrushModels = cvar->FindVar( "r_drawbrushmodels" );
- if( UseVR() )
- {
- m_eStartEye = STEREO_EYE_LEFT;
- m_eLastEye = STEREO_EYE_RIGHT;
- }
- else
- {
- m_eStartEye = m_eLastEye = STEREO_EYE_MONO;
- }
-
beams->InitBeams();
tempents->Init();
@@ -500,12 +487,18 @@ void CViewRender::DriftPitch (void)
StereoEye_t CViewRender::GetFirstEye() const
{
- return m_eStartEye;
+ if( UseVR() )
+ return STEREO_EYE_LEFT;
+ else
+ return STEREO_EYE_MONO;
}
StereoEye_t CViewRender::GetLastEye() const
{
- return m_eLastEye;
+ if( UseVR() )
+ return STEREO_EYE_RIGHT;
+ else
+ return STEREO_EYE_MONO;
}
@@ -1177,57 +1170,14 @@ void CViewRender::Render( vrect_t *rect )
}
break;
- case STEREO_EYE_LEFT:
- {
-#ifdef STAGING_ONLY
- if ( vr_stereo_debug_viewport.GetBool() )
- {
- // Stress-test for crazy viewports.
- view.width = vr.width * flViewportScale * 0.25f;
- view.height = vr.height * flViewportScale * 0.75f;
- view.x = vr.x * flViewportScale;
- view.y = (vr.y + vr.height * 0.20f) * flViewportScale;
-
- view.m_nUnscaledWidth = vr.width / 2;
- }
- else
-#endif
- {
- view.width = vr.width * flViewportScale * 0.5f;
- view.height = vr.height * flViewportScale;
- view.x = vr.x * flViewportScale ;
- view.y = vr.y * flViewportScale;
-
- view.m_nUnscaledWidth = vr.width / 2;
- }
- }
- break;
-
case STEREO_EYE_RIGHT:
+ case STEREO_EYE_LEFT:
{
-#ifdef STAGING_ONLY
- if ( vr_stereo_debug_viewport.GetBool() )
- {
- // Stress-test for crazy viewports.
- view.width = vr.width * flViewportScale * 0.75f;
- view.height = vr.height * flViewportScale * 0.75f;
- view.x = vr.x + vr.width * 0.25f;
- view.y = vr.y + vr.height * 0.1f;
-
- view.m_nUnscaledWidth = vr.width / 2;
- view.m_nUnscaledX = vr.x + view.m_nUnscaledWidth;
- }
- else
-#endif
- {
- view.width = vr.width * flViewportScale * 0.5f;
- view.height = vr.height * flViewportScale;
- view.x = (vr.x + view.width) * flViewportScale;
- view.y = vr.y * flViewportScale;
-
- view.m_nUnscaledWidth = vr.width / 2;
- view.m_nUnscaledX = vr.x + view.m_nUnscaledWidth;
- }
+ g_pSourceVR->GetViewportBounds( (ISourceVirtualReality::VREye)(eEye - 1 ), &view.x, &view.y, &view.width, &view.height );
+ view.m_nUnscaledWidth = view.width;
+ view.m_nUnscaledHeight = view.height;
+ view.m_nUnscaledX = view.x;
+ view.m_nUnscaledY = view.y;
}
break;
@@ -1302,9 +1252,32 @@ void CViewRender::Render( vrect_t *rect )
// we should use the monitor view from the left eye for both eyes
flags |= RENDERVIEW_SUPPRESSMONITORRENDERING;
}
+
RenderView( view, nClearFlags, flags );
- }
+ if ( UseVR() )
+ {
+ bool bDoUndistort = ! engine->IsTakingScreenshot();
+
+ if ( bDoUndistort )
+ {
+ g_ClientVirtualReality.PostProcessFrame( eEye );
+ }
+
+ // logic here all cloned from code in viewrender.cpp around RenderHUDQuad:
+
+ // figure out if we really want to draw the HUD based on freeze cam
+ bool bInFreezeCam = ( pPlayer && pPlayer->GetObserverMode() == OBS_MODE_FREEZECAM );
+
+ // draw the HUD after the view model so its "I'm closer" depth queues work right.
+ if( !bInFreezeCam && g_ClientVirtualReality.ShouldRenderHUDInWorld() )
+ {
+ // TODO - a bit of a shonky test - basically trying to catch the main menu, the briefing screen, the loadout screen, etc.
+ bool bTranslucent = !g_pMatSystemSurface->IsCursorVisible();
+ g_ClientVirtualReality.OverlayHUDQuadWithUndistort( view, bDoUndistort, g_pClientMode->ShouldBlackoutAroundHUD(), bTranslucent );
+ }
+ }
+ }
// TODO: should these be inside or outside the stereo eye stuff?
@@ -1334,15 +1307,6 @@ void CViewRender::Render( vrect_t *rect )
}
- if ( UseVR() )
- {
- if ( !engine->IsTakingScreenshot() )
- {
- // Deal with the distortion on the display.
- g_ClientVirtualReality.PostProcessFrame( rect );
- }
- }
-
}
diff --git a/mp/src/game/client/view_scene.cpp b/mp/src/game/client/view_scene.cpp
index 73c05a2b..098e9ae9 100644
--- a/mp/src/game/client/view_scene.cpp
+++ b/mp/src/game/client/view_scene.cpp
@@ -11,7 +11,7 @@
#include "rendertexture.h"
#include "view_scene.h"
#include "viewrender.h"
-#include "headtrack/isourcevirtualreality.h"
+#include "sourcevr/isourcevirtualreality.h"
#include "client_virtualreality.h"
// memdbgon must be the last include file in a .cpp file!!!
diff --git a/mp/src/game/client/viewpostprocess.cpp b/mp/src/game/client/viewpostprocess.cpp
index 7fe7c40d..3f74acdc 100644
--- a/mp/src/game/client/viewpostprocess.cpp
+++ b/mp/src/game/client/viewpostprocess.cpp
@@ -834,7 +834,7 @@ void CLuminanceHistogramSystem::UpdateLuminanceRanges( void )
s_bFirstTime = false;
// This seems like a bad idea but it's fine for now
- const char *sModsForOriginalAlgorithm[] = { "dod", "cstrike", "lostcoast" };
+ const char *sModsForOriginalAlgorithm[] = { "dod", "cstrike", "lostcoast", "hl1" };
for ( int i=0; i<3; i++ )
{
if ( strlen( engine->GetGameDirectory() ) >= strlen( sModsForOriginalAlgorithm[i] ) )
diff --git a/mp/src/game/client/viewrender.cpp b/mp/src/game/client/viewrender.cpp
index 7422479b..a9ef4eb8 100644
--- a/mp/src/game/client/viewrender.cpp
+++ b/mp/src/game/client/viewrender.cpp
@@ -51,7 +51,7 @@
#include "studio_stats.h"
#include "con_nprint.h"
#include "clientmode_shared.h"
-#include "headtrack/isourcevirtualreality.h"
+#include "sourcevr/isourcevirtualreality.h"
#include "client_virtualreality.h"
#ifdef PORTAL
@@ -394,7 +394,7 @@ protected:
bool GetSkyboxFogEnable();
void Enable3dSkyboxFog( void );
- void DrawInternal( view_id_t iSkyBoxViewID = VIEW_3DSKY, bool bInvokePreAndPostRender = true, ITexture *pRenderTarget = NULL );
+ void DrawInternal( view_id_t iSkyBoxViewID, bool bInvokePreAndPostRender, ITexture *pRenderTarget, ITexture *pDepthTarget );
sky3dparams_t * PreRender3dSkyboxWorld( SkyboxVisibility_t nSkyboxVisible );
@@ -1055,7 +1055,15 @@ void CViewRender::DrawViewModels( const CViewSetup &view, bool drawViewmodel )
viewModelSetup.fov = view.fovViewmodel;
viewModelSetup.m_flAspectRatio = engine->GetScreenAspectRatio();
- render->Push3DView( viewModelSetup, 0, NULL, GetFrustum() );
+ ITexture *pRTColor = NULL;
+ ITexture *pRTDepth = NULL;
+ if( view.m_eStereoEye != STEREO_EYE_MONO )
+ {
+ pRTColor = g_pSourceVR->GetRenderTarget( (ISourceVirtualReality::VREye)(view.m_eStereoEye-1), ISourceVirtualReality::RT_Color );
+ pRTDepth = g_pSourceVR->GetRenderTarget( (ISourceVirtualReality::VREye)(view.m_eStereoEye-1), ISourceVirtualReality::RT_Depth );
+ }
+
+ render->Push3DView( viewModelSetup, 0, pRTColor, GetFrustum(), pRTDepth );
#ifdef PORTAL //the depth range hack doesn't work well enough for the portal mod (and messing with the depth hack values makes some models draw incorrectly)
//step up to a full depth clear if we're extremely close to a portal (in a portal environment)
@@ -1822,7 +1830,15 @@ void CViewRender::SetupMain3DView( const CViewSetup &view, int &nClearFlags )
}
else
{
- render->Push3DView( view, nClearFlags, NULL, GetFrustum() );
+ ITexture *pRTColor = NULL;
+ ITexture *pRTDepth = NULL;
+ if( view.m_eStereoEye != STEREO_EYE_MONO )
+ {
+ pRTColor = g_pSourceVR->GetRenderTarget( (ISourceVirtualReality::VREye)(view.m_eStereoEye-1), ISourceVirtualReality::RT_Color );
+ pRTDepth = g_pSourceVR->GetRenderTarget( (ISourceVirtualReality::VREye)(view.m_eStereoEye-1), ISourceVirtualReality::RT_Depth );
+ }
+
+ render->Push3DView( view, nClearFlags, pRTColor, GetFrustum(), pRTDepth );
}
// If we didn't clear the depth here, we'll need to clear it later
@@ -2155,6 +2171,12 @@ void CViewRender::RenderView( const CViewSetup &view, int nClearFlags, int whatT
pCopyMaterial->DecrementReferenceCount();
}
+ // if we're in VR mode we might need to override the render target
+ if( UseVR() )
+ {
+ saveRenderTarget = g_pSourceVR->GetRenderTarget( (ISourceVirtualReality::VREye)(view.m_eStereoEye - 1), ISourceVirtualReality::RT_Color );
+ }
+
// Draw the 2D graphics
render->Push2DView( view, 0, saveRenderTarget, GetFrustum() );
@@ -2192,7 +2214,9 @@ void CViewRender::RenderView( const CViewSetup &view, int nClearFlags, int whatT
vgui::surface()->GetScreenSize( viewWidth, viewHeight );
- viewFramebufferX = view.m_eStereoEye == STEREO_EYE_RIGHT ? viewFramebufferWidth : 0;
+ viewFramebufferX = 0;
+ if( view.m_eStereoEye == STEREO_EYE_RIGHT && !saveRenderTarget )
+ viewFramebufferX = viewFramebufferWidth;
viewFramebufferY = 0;
}
}
@@ -2224,7 +2248,7 @@ void CViewRender::RenderView( const CViewSetup &view, int nClearFlags, int whatT
// let vgui know where to render stuff for the forced-to-framebuffer panels
if( UseVR() )
{
- vgui::surface()->SetFullscreenViewport( viewFramebufferX, viewFramebufferY, viewFramebufferWidth, viewFramebufferHeight );
+ vgui::surface()->SetFullscreenViewportAndRenderTarget( viewFramebufferX, viewFramebufferY, viewFramebufferWidth, viewFramebufferHeight, saveRenderTarget );
}
// clear the render target if we need to
@@ -4703,7 +4727,7 @@ sky3dparams_t *CSkyboxView::PreRender3dSkyboxWorld( SkyboxVisibility_t nSkyboxVi
//-----------------------------------------------------------------------------
//
//-----------------------------------------------------------------------------
-void CSkyboxView::DrawInternal( view_id_t iSkyBoxViewID, bool bInvokePreAndPostRender, ITexture *pRenderTarget )
+void CSkyboxView::DrawInternal( view_id_t iSkyBoxViewID, bool bInvokePreAndPostRender, ITexture *pRenderTarget, ITexture *pDepthTarget )
{
unsigned char **areabits = render->GetAreaBits();
unsigned char *savebits;
@@ -4736,7 +4760,7 @@ void CSkyboxView::DrawInternal( view_id_t iSkyBoxViewID, bool bInvokePreAndPostR
// cluster with sky. Then we could just connect the areas to do our vis.
//m_bOverrideVisOrigin could hose us here, so call direct
render->ViewSetupVis( false, 1, &m_pSky3dParams->origin.Get() );
- render->Push3DView( (*this), m_ClearFlags, pRenderTarget, GetFrustum() );
+ render->Push3DView( (*this), m_ClearFlags, pRenderTarget, GetFrustum(), pDepthTarget );
// Store off view origin and angles
SetupCurrentView( origin, angles, iSkyBoxViewID );
@@ -4832,7 +4856,15 @@ void CSkyboxView::Draw()
{
VPROF_BUDGET( "CViewRender::Draw3dSkyboxworld", "3D Skybox" );
- DrawInternal();
+ ITexture *pRTColor = NULL;
+ ITexture *pRTDepth = NULL;
+ if( m_eStereoEye != STEREO_EYE_MONO )
+ {
+ pRTColor = g_pSourceVR->GetRenderTarget( (ISourceVirtualReality::VREye)(m_eStereoEye-1), ISourceVirtualReality::RT_Color );
+ pRTDepth = g_pSourceVR->GetRenderTarget( (ISourceVirtualReality::VREye)(m_eStereoEye-1), ISourceVirtualReality::RT_Depth );
+ }
+
+ DrawInternal(VIEW_3DSKY, true, pRTColor, pRTDepth );
}
@@ -4882,7 +4914,7 @@ void CPortalSkyboxView::Draw()
bool bInvokePreAndPostRender = ( g_pPortalRender->ShouldUseStencilsToRenderPortals() == false );
- DrawInternal( iSkyBoxViewID, bInvokePreAndPostRender, m_pRenderTarget );
+ DrawInternal( iSkyBoxViewID, bInvokePreAndPostRender, m_pRenderTarget, NULL );
pRenderContext->EnableClipping( bClippingEnabled );
diff --git a/mp/src/game/client/viewrender.h b/mp/src/game/client/viewrender.h
index d9901237..723c3222 100644
--- a/mp/src/game/client/viewrender.h
+++ b/mp/src/game/client/viewrender.h
@@ -474,10 +474,6 @@ private:
// This stores the current view
CViewSetup m_CurrentView;
- // these will both be mono or they will be left/right
- StereoEye_t m_eStartEye;
- StereoEye_t m_eLastEye;
-
// VIS Overrides
// Set to true to turn off client side vis ( !!!! rendering will be slow since everything will draw )
bool m_bForceNoVis;
diff --git a/mp/src/game/protobuf_include.vpc b/mp/src/game/protobuf_include.vpc
index c7290fe3..c4fe5022 100644
--- a/mp/src/game/protobuf_include.vpc
+++ b/mp/src/game/protobuf_include.vpc
@@ -10,6 +10,8 @@ $Project
{
$Folder "Libraries"
{
- $Libexternal libprotobuf
+ $Libexternal libprotobuf [!$VS2012 && !$VS2013]
+ $Libexternal 2012\libprotobuf [$VS2012]
+ $Libexternal 2013\libprotobuf [$VS2013]
}
}
diff --git a/mp/src/game/server/ai_activity.cpp b/mp/src/game/server/ai_activity.cpp
index 463c8942..a476a9f3 100644
--- a/mp/src/game/server/ai_activity.cpp
+++ b/mp/src/game/server/ai_activity.cpp
@@ -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 );
}
diff --git a/mp/src/game/server/ai_movesolver.cpp b/mp/src/game/server/ai_movesolver.cpp
index 1dc81849..101056a7 100644
--- a/mp/src/game/server/ai_movesolver.cpp
+++ b/mp/src/game/server/ai_movesolver.cpp
@@ -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;
diff --git a/mp/src/game/server/ai_networkmanager.cpp b/mp/src/game/server/ai_networkmanager.cpp
index 7f6bea61..21a6f9de 100644
--- a/mp/src/game/server/ai_networkmanager.cpp
+++ b/mp/src/game/server/ai_networkmanager.cpp
@@ -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;
diff --git a/mp/src/game/server/baseanimating.cpp b/mp/src/game/server/baseanimating.cpp
index 2e1e3a22..34bf6378 100644
--- a/mp/src/game/server/baseanimating.cpp
+++ b/mp/src/game/server/baseanimating.cpp
@@ -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;
diff --git a/mp/src/game/server/baseanimating.h b/mp/src/game/server/baseanimating.h
index 5f8a019a..75300e8e 100644
--- a/mp/src/game/server/baseanimating.h
+++ b/mp/src/game/server/baseanimating.h
@@ -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 );
diff --git a/mp/src/game/server/baseentity.cpp b/mp/src/game/server/baseentity.cpp
index edc00977..52316924 100644
--- a/mp/src/game/server/baseentity.cpp
+++ b/mp/src/game/server/baseentity.cpp
@@ -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 );
diff --git a/mp/src/game/server/basemultiplayerplayer.cpp b/mp/src/game/server/basemultiplayerplayer.cpp
index 031282ac..b6ecd44c 100644
--- a/mp/src/game/server/basemultiplayerplayer.cpp
+++ b/mp/src/game/server/basemultiplayerplayer.cpp
@@ -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() )
diff --git a/mp/src/game/server/basemultiplayerplayer.h b/mp/src/game/server/basemultiplayerplayer.h
index 5f9b9519..06a0e00d 100644
--- a/mp/src/game/server/basemultiplayerplayer.h
+++ b/mp/src/game/server/basemultiplayerplayer.h
@@ -89,6 +89,7 @@ public:
// Command rate limiting.
bool ShouldRunRateLimitedCommand( const CCommand &args );
+ bool ShouldRunRateLimitedCommand( const char *pszCommand );
protected:
virtual CAI_Expresser *CreateExpresser( void );
diff --git a/mp/src/game/server/baseprojectile.cpp b/mp/src/game/server/baseprojectile.cpp
deleted file mode 100644
index 30d92fec..00000000
--- a/mp/src/game/server/baseprojectile.cpp
+++ /dev/null
@@ -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 );
-}
diff --git a/mp/src/game/server/baseprojectile.h b/mp/src/game/server/baseprojectile.h
deleted file mode 100644
index 51bd04f7..00000000
--- a/mp/src/game/server/baseprojectile.h
+++ /dev/null
@@ -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
diff --git a/mp/src/game/server/basetempentity.cpp b/mp/src/game/server/basetempentity.cpp
index 45bd600a..a238397e 100644
--- a/mp/src/game/server/basetempentity.cpp
+++ b/mp/src/game/server/basetempentity.cpp
@@ -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,
diff --git a/mp/src/game/server/entity_tools_server.cpp b/mp/src/game/server/entity_tools_server.cpp
index e1888123..5032ca04 100644
--- a/mp/src/game/server/entity_tools_server.cpp
+++ b/mp/src/game/server/entity_tools_server.cpp
@@ -409,13 +409,39 @@ void CC_Ent_Keyvalue( const CCommand &args )
return;
}
- int nID = atoi( args[1] );
+ CBasePlayer *pPlayer = ToBasePlayer( UTIL_GetCommandClient() );
+ CBaseEntity *pEnt;
+ if ( FStrEq( args[1], "" ) || FStrEq( args[1], "!picker" ) )
+ {
+ if (!pPlayer)
+ return;
+
+ extern CBaseEntity *FindPickerEntity( CBasePlayer *pPlayer );
+ pEnt = FindPickerEntity( pPlayer );
- CBaseEntity *pEnt = g_ServerTools.FindEntityByHammerID( nID );
- if ( !pEnt )
+ 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" ) )
{
- Msg( "Entity ID %d not found.\n", nID );
- return;
+ 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;
diff --git a/mp/src/game/server/hl1_CBaseHelicopter.h b/mp/src/game/server/hl1_CBaseHelicopter.h
index 1e3c1044..01586126 100644
--- a/mp/src/game/server/hl1_CBaseHelicopter.h
+++ b/mp/src/game/server/hl1_CBaseHelicopter.h
@@ -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 );
diff --git a/mp/src/game/server/hl2/hl2_player.cpp b/mp/src/game/server/hl2/hl2_player.cpp
index 1659fe31..e7583f5a 100644
--- a/mp/src/game/server/hl2/hl2_player.cpp
+++ b/mp/src/game/server/hl2/hl2_player.cpp
@@ -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;
}
diff --git a/mp/src/game/server/logicrelay.h b/mp/src/game/server/logicrelay.h
index a91a456e..8d082acc 100644
--- a/mp/src/game/server/logicrelay.h
+++ b/mp/src/game/server/logicrelay.h
@@ -36,6 +36,8 @@ public:
// Outputs
COutputEvent m_OnTrigger;
COutputEvent m_OnSpawn;
+
+ bool IsDisabled( void ){ return m_bDisabled; }
private:
diff --git a/mp/src/game/server/nav_mesh.cpp b/mp/src/game/server/nav_mesh.cpp
index eae35c8d..8a15b39e 100644
--- a/mp/src/game/server/nav_mesh.cpp
+++ b/mp/src/game/server/nav_mesh.cpp
@@ -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 );
diff --git a/mp/src/game/server/player.cpp b/mp/src/game/server/player.cpp
index 9ae85cc0..73aab6d6 100644
--- a/mp/src/game/server/player.cpp
+++ b/mp/src/game/server/player.cpp
@@ -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;
@@ -8642,6 +8644,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 -
//-----------------------------------------------------------------------------
diff --git a/mp/src/game/server/player.h b/mp/src/game/server/player.h
index 8cd1d0fa..ddbd4416 100644
--- a/mp/src/game/server/player.h
+++ b/mp/src/game/server/player.h
@@ -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
diff --git a/mp/src/game/server/player_lagcompensation.cpp b/mp/src/game/server/player_lagcompensation.cpp
index 0fafb2a7..08503652 100644
--- a/mp/src/game/server/player_lagcompensation.cpp
+++ b/mp/src/game/server/player_lagcompensation.cpp
@@ -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 )
diff --git a/mp/src/game/server/server_base.vpc b/mp/src/game/server/server_base.vpc
index 6445e07d..f1c3c835 100644
--- a/mp/src/game/server/server_base.vpc
+++ b/mp/src/game/server/server_base.vpc
@@ -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"
diff --git a/mp/src/game/server/team_control_point_master.cpp b/mp/src/game/server/team_control_point_master.cpp
index f60939a7..8ad9796d 100644
--- a/mp/src/game/server/team_control_point_master.cpp
+++ b/mp/src/game/server/team_control_point_master.cpp
@@ -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();
}
diff --git a/mp/src/game/server/team_train_watcher.cpp b/mp/src/game/server/team_train_watcher.cpp
index dba231af..b8ef36c3 100644
--- a/mp/src/game/server/team_train_watcher.cpp
+++ b/mp/src/game/server/team_train_watcher.cpp
@@ -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
diff --git a/mp/src/game/server/team_train_watcher.h b/mp/src/game/server/team_train_watcher.h
index 0bb9b2a6..22b82c6f 100644
--- a/mp/src/game/server/team_train_watcher.h
+++ b/mp/src/game/server/team_train_watcher.h
@@ -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
diff --git a/mp/src/game/server/trains.cpp b/mp/src/game/server/trains.cpp
index 639523b9..bf01ae6f 100644
--- a/mp/src/game/server/trains.cpp
+++ b/mp/src/game/server/trains.cpp
@@ -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);
diff --git a/mp/src/game/server/trigger_area_capture.cpp b/mp/src/game/server/trigger_area_capture.cpp
index 177e7701..2839200b 100644
--- a/mp/src/game/server/trigger_area_capture.cpp
+++ b/mp/src/game/server/trigger_area_capture.cpp
@@ -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 );
@@ -167,14 +164,6 @@ void CTriggerAreaCapture::Precache( void )
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
-void CTriggerAreaCapture::SetAreaIndex( int index )
-{
- m_iAreaIndex = index;
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-//-----------------------------------------------------------------------------
bool CTriggerAreaCapture::IsActive( void )
{
return !m_bDisabled;
@@ -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() )
diff --git a/mp/src/game/server/trigger_area_capture.h b/mp/src/game/server/trigger_area_capture.h
index 2d392755..90e0ed0a 100644
--- a/mp/src/game/server/trigger_area_capture.h
+++ b/mp/src/game/server/trigger_area_capture.h
@@ -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;
diff --git a/mp/src/game/server/triggers.cpp b/mp/src/game/server/triggers.cpp
index 8835ab26..295e826a 100644
--- a/mp/src/game/server/triggers.cpp
+++ b/mp/src/game/server/triggers.cpp
@@ -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;
diff --git a/mp/src/game/server/util.cpp b/mp/src/game/server/util.cpp
index b273520a..aba6f327 100644
--- a/mp/src/game/server/util.cpp
+++ b/mp/src/game/server/util.cpp
@@ -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
diff --git a/mp/src/game/server/vote_controller.cpp b/mp/src/game/server/vote_controller.cpp
index d052e0f9..316974ad 100644
--- a/mp/src/game/server/vote_controller.cpp
+++ b/mp/src/game/server/vote_controller.cpp
@@ -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
diff --git a/mp/src/game/server/vote_controller.h b/mp/src/game/server/vote_controller.h
index 1bdd0281..0376d6a6 100644
--- a/mp/src/game/server/vote_controller.h
+++ b/mp/src/game/server/vote_controller.h
@@ -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
diff --git a/mp/src/game/shared/activitylist.cpp b/mp/src/game/shared/activitylist.cpp
index 94bcff15..2b421252 100644
--- a/mp/src/game/shared/activitylist.cpp
+++ b/mp/src/game/shared/activitylist.cpp
@@ -2270,6 +2270,11 @@ void ActivityList_RegisterSharedActivities( void )
REGISTER_SHARED_ACTIVITY( ACT_THROWABLE_VM_IDLE );
REGISTER_SHARED_ACTIVITY( ACT_THROWABLE_VM_FIRE );
+ REGISTER_SHARED_ACTIVITY( ACT_SPELL_VM_DRAW );
+ REGISTER_SHARED_ACTIVITY( ACT_SPELL_VM_IDLE );
+ REGISTER_SHARED_ACTIVITY( ACT_SPELL_VM_ARM );
+ REGISTER_SHARED_ACTIVITY( ACT_SPELL_VM_FIRE );
+
AssertMsg( g_HighestActivity == LAST_SHARED_ACTIVITY - 1, "Not all activities from ai_activity.h registered in activitylist.cpp" );
}
diff --git a/mp/src/game/shared/ai_activity.h b/mp/src/game/shared/ai_activity.h
index 6c5f05c8..fbd10c39 100644
--- a/mp/src/game/shared/ai_activity.h
+++ b/mp/src/game/shared/ai_activity.h
@@ -2097,11 +2097,16 @@ typedef enum
// Throwable Animations
ACT_MP_THROW,
-
ACT_THROWABLE_VM_DRAW,
ACT_THROWABLE_VM_IDLE,
ACT_THROWABLE_VM_FIRE,
+ // Spell Animations
+ ACT_SPELL_VM_DRAW,
+ ACT_SPELL_VM_IDLE,
+ ACT_SPELL_VM_ARM,
+ ACT_SPELL_VM_FIRE,
+
// this is the end of the global activities, private per-monster activities start here.
LAST_SHARED_ACTIVITY,
} Activity;
diff --git a/mp/src/game/shared/basecombatweapon_shared.h b/mp/src/game/shared/basecombatweapon_shared.h
index d773c0c5..701403a0 100644
--- a/mp/src/game/shared/basecombatweapon_shared.h
+++ b/mp/src/game/shared/basecombatweapon_shared.h
@@ -248,7 +248,7 @@ public:
// but they are out of ammo. The default implementation
// either reloads, switches weapons, or plays an empty sound.
- virtual bool ShouldBlockPrimaryFire() { return !AutoFiresFullClip(); }
+ virtual bool ShouldBlockPrimaryFire() { return false; }
#ifdef CLIENT_DLL
virtual void CreateMove( float flInputSampleTime, CUserCmd *pCmd, const QAngle &vecOldViewAngles ) {}
diff --git a/mp/src/game/shared/basegrenade_shared.h b/mp/src/game/shared/basegrenade_shared.h
index 79e34801..38bb684d 100644
--- a/mp/src/game/shared/basegrenade_shared.h
+++ b/mp/src/game/shared/basegrenade_shared.h
@@ -11,6 +11,8 @@
#pragma once
#endif
+#include "baseprojectile.h"
+
#if defined( CLIENT_DLL )
#define CBaseGrenade C_BaseGrenade
@@ -29,12 +31,12 @@
class CTakeDamageInfo;
#if !defined( CLIENT_DLL )
-class CBaseGrenade : public CBaseAnimating, public CDefaultPlayerPickupVPhysics
+class CBaseGrenade : public CBaseProjectile, public CDefaultPlayerPickupVPhysics
#else
-class CBaseGrenade : public CBaseAnimating
+class CBaseGrenade : public CBaseProjectile
#endif
{
- DECLARE_CLASS( CBaseGrenade, CBaseAnimating );
+ DECLARE_CLASS( CBaseGrenade, CBaseProjectile );
public:
CBaseGrenade(void);
diff --git a/mp/src/game/shared/baseplayer_shared.cpp b/mp/src/game/shared/baseplayer_shared.cpp
index f56e72e4..cba09eb7 100644
--- a/mp/src/game/shared/baseplayer_shared.cpp
+++ b/mp/src/game/shared/baseplayer_shared.cpp
@@ -22,7 +22,7 @@
#include "view.h"
#include "client_virtualreality.h"
#define CRecipientFilter C_RecipientFilter
- #include "headtrack/isourcevirtualreality.h"
+ #include "sourcevr/isourcevirtualreality.h"
#else
diff --git a/mp/src/game/shared/baseprojectile.cpp b/mp/src/game/shared/baseprojectile.cpp
new file mode 100644
index 00000000..c695db93
--- /dev/null
+++ b/mp/src/game/shared/baseprojectile.cpp
@@ -0,0 +1,26 @@
+//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// Purpose:
+//
+// $NoKeywords: $
+//=============================================================================//
+
+#include "cbase.h"
+#include "baseprojectile.h"
+
+
+IMPLEMENT_NETWORKCLASS_ALIASED( BaseProjectile, DT_BaseProjectile )
+
+BEGIN_NETWORK_TABLE( CBaseProjectile, DT_BaseProjectile )
+END_NETWORK_TABLE()
+
+
+//-----------------------------------------------------------------------------
+// Purpose: Constructor.
+//-----------------------------------------------------------------------------
+CBaseProjectile::CBaseProjectile()
+{
+#ifdef GAME_DLL
+ m_iDestroyableHitCount = 0;
+#endif
+}
diff --git a/mp/src/game/shared/baseprojectile.h b/mp/src/game/shared/baseprojectile.h
new file mode 100644
index 00000000..2ff00fc5
--- /dev/null
+++ b/mp/src/game/shared/baseprojectile.h
@@ -0,0 +1,53 @@
+//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// Purpose:
+//
+// $NoKeywords: $
+//=============================================================================//
+
+#ifndef BASEPROJECTILE_H
+#define BASEPROJECTILE_H
+#ifdef _WIN32
+#pragma once
+#endif
+
+#include "cbase.h"
+
+#ifdef GAME_DLL
+#include "baseanimating.h"
+#else
+#include "c_baseanimating.h"
+#endif
+
+#ifdef CLIENT_DLL
+#define CBaseProjectile C_BaseProjectile
+#endif // CLIENT_DLL
+
+//=============================================================================
+//
+// Base Projectile.
+//
+//=============================================================================
+class CBaseProjectile : public CBaseAnimating
+{
+public:
+ DECLARE_CLASS( CBaseProjectile, CBaseAnimating );
+ DECLARE_NETWORKCLASS();
+
+ CBaseProjectile();
+
+#ifdef GAME_DLL
+ virtual int GetDestroyableHitCount( void ) const { return m_iDestroyableHitCount; }
+ void IncrementDestroyableHitCount( void ) { ++m_iDestroyableHitCount; }
+#endif // GAME_DLL
+
+ virtual bool IsDestroyable( void ) { return false; }
+ virtual void Destroy( bool bBlinkOut = true, bool bBreakRocket = false ) {}
+
+protected:
+#ifdef GAME_DLL
+ int m_iDestroyableHitCount;
+#endif // GAME_DLL
+};
+
+#endif // BASEPROJECTILE_H
diff --git a/mp/src/game/shared/baseviewmodel_shared.cpp b/mp/src/game/shared/baseviewmodel_shared.cpp
index 99c4bfce..20538e8c 100644
--- a/mp/src/game/shared/baseviewmodel_shared.cpp
+++ b/mp/src/game/shared/baseviewmodel_shared.cpp
@@ -12,7 +12,7 @@
#include "iprediction.h"
#include "prediction.h"
#include "client_virtualreality.h"
-#include "headtrack/isourcevirtualreality.h"
+#include "sourcevr/isourcevirtualreality.h"
#else
#include "vguiscreen.h"
#endif
diff --git a/mp/src/game/shared/effect_color_tables.h b/mp/src/game/shared/effect_color_tables.h
index 54f6384f..322d0e08 100644
--- a/mp/src/game/shared/effect_color_tables.h
+++ b/mp/src/game/shared/effect_color_tables.h
@@ -44,6 +44,7 @@ static colorentry_t bloodcolors[] =
{ BLOOD_COLOR_RED, 72, 0, 0 },
{ BLOOD_COLOR_YELLOW, 195, 195, 0 },
{ BLOOD_COLOR_MECH, 20, 20, 20 },
+ { BLOOD_COLOR_GREEN, 195, 195, 0 },
};
#endif // EFFECT_COLOR_TABLES_H
diff --git a/mp/src/game/shared/gamemovement.cpp b/mp/src/game/shared/gamemovement.cpp
index 4f1132b1..8de6fc32 100644
--- a/mp/src/game/shared/gamemovement.cpp
+++ b/mp/src/game/shared/gamemovement.cpp
@@ -55,6 +55,12 @@ ConVar player_limit_jump_speed( "player_limit_jump_speed", "1", FCVAR_REPLICATED
// duck controls. Its value is meaningless anytime we don't have the options window open.
ConVar option_duck_method("option_duck_method", "1", FCVAR_REPLICATED|FCVAR_ARCHIVE );// 0 = HOLD to duck, 1 = Duck is a toggle
+#ifdef STAGING_ONLY
+#ifdef CLIENT_DLL
+ConVar debug_latch_reset_onduck( "debug_latch_reset_onduck", "1", FCVAR_CHEAT );
+#endif
+#endif
+
// [MD] I'll remove this eventually. For now, I want the ability to A/B the optimizations.
bool g_bMovementOptimizations = true;
@@ -4108,8 +4114,15 @@ void CGameMovement::FinishUnDuck( void )
mv->SetAbsOrigin( newOrigin );
#ifdef CLIENT_DLL
+#ifdef STAGING_ONLY
+ if ( debug_latch_reset_onduck.GetBool() )
+ {
+ player->ResetLatched();
+ }
+#else
player->ResetLatched();
#endif
+#endif // CLIENT_DLL
// Recategorize position since ducking can change origin
CategorizePosition();
@@ -4207,8 +4220,15 @@ void CGameMovement::FinishDuck( void )
mv->SetAbsOrigin( out );
#ifdef CLIENT_DLL
+#ifdef STAGING_ONLY
+ if ( debug_latch_reset_onduck.GetBool() )
+ {
+ player->ResetLatched();
+ }
+#else
player->ResetLatched();
#endif
+#endif // CLIENT_DLL
}
// See if we are stuck?
diff --git a/mp/src/game/shared/gamerules.h b/mp/src/game/shared/gamerules.h
index 6d99f64f..4b2f5124 100644
--- a/mp/src/game/shared/gamerules.h
+++ b/mp/src/game/shared/gamerules.h
@@ -271,7 +271,7 @@ public:
// Client damage rules
virtual float FlPlayerFallDamage( CBasePlayer *pPlayer ) = 0;// this client just hit the ground after a fall. How much damage?
- virtual bool FPlayerCanTakeDamage( CBasePlayer *pPlayer, CBaseEntity *pAttacker ) {return TRUE;};// can this player take damage from this attacker?
+ virtual bool FPlayerCanTakeDamage( CBasePlayer *pPlayer, CBaseEntity *pAttacker, const CTakeDamageInfo &info ) {return TRUE;};// can this player take damage from this attacker?
virtual bool ShouldAutoAim( CBasePlayer *pPlayer, edict_t *target ) { return TRUE; }
virtual float GetAutoAimScale( CBasePlayer *pPlayer ) { return 1.0f; }
virtual int GetAutoAimMode() { return AUTOAIM_ON; }
diff --git a/mp/src/game/shared/movevars_shared.cpp b/mp/src/game/shared/movevars_shared.cpp
index 3ef79945..b5b94c72 100644
--- a/mp/src/game/shared/movevars_shared.cpp
+++ b/mp/src/game/shared/movevars_shared.cpp
@@ -36,7 +36,7 @@ float GetCurrentGravity( void )
ConVar sv_gravity ( "sv_gravity", DEFAULT_GRAVITY_STRING, FCVAR_NOTIFY | FCVAR_REPLICATED, "World gravity." );
-#if defined( DOD_DLL ) || defined( CSTRIKE_DLL )
+#if defined( DOD_DLL ) || defined( CSTRIKE_DLL ) || defined( HL1MP_DLL )
ConVar sv_stopspeed ( "sv_stopspeed","100", FCVAR_NOTIFY | FCVAR_REPLICATED, "Minimum stopping speed when on ground." );
#else
ConVar sv_stopspeed ( "sv_stopspeed","100", FCVAR_NOTIFY | FCVAR_REPLICATED | FCVAR_DEVELOPMENTONLY, "Minimum stopping speed when on ground." );
@@ -48,7 +48,7 @@ ConVar sv_specaccelerate( "sv_specaccelerate", "5", FCVAR_NOTIFY | FCVAR_ARCHIVE
ConVar sv_specspeed ( "sv_specspeed", "3", FCVAR_ARCHIVE | FCVAR_NOTIFY | FCVAR_REPLICATED);
ConVar sv_specnoclip ( "sv_specnoclip", "1", FCVAR_ARCHIVE | FCVAR_NOTIFY | FCVAR_REPLICATED);
-#if defined( CSTRIKE_DLL )
+#if defined( CSTRIKE_DLL ) || defined( HL1MP_DLL )
ConVar sv_maxspeed ( "sv_maxspeed", "320", FCVAR_NOTIFY | FCVAR_REPLICATED);
#else
ConVar sv_maxspeed ( "sv_maxspeed", "320", FCVAR_NOTIFY | FCVAR_REPLICATED | FCVAR_DEVELOPMENTONLY);
@@ -58,7 +58,7 @@ ConVar sv_maxspeed ( "sv_maxspeed", "320", FCVAR_NOTIFY | FCVAR_REPLICATED | FC
ConVar sv_accelerate ( "sv_accelerate", "7", FCVAR_NOTIFY | FCVAR_REPLICATED);
#else
-#if defined( CSTRIKE_DLL )
+#if defined( CSTRIKE_DLL ) || defined( HL1MP_DLL )
ConVar sv_accelerate ( "sv_accelerate", "10", FCVAR_NOTIFY | FCVAR_REPLICATED);
#else
ConVar sv_accelerate ( "sv_accelerate", "10", FCVAR_NOTIFY | FCVAR_REPLICATED | FCVAR_DEVELOPMENTONLY);
@@ -66,7 +66,7 @@ ConVar sv_maxspeed ( "sv_maxspeed", "320", FCVAR_NOTIFY | FCVAR_REPLICATED | FC
#endif//_XBOX
-#if defined( CSTRIKE_DLL )
+#if defined( CSTRIKE_DLL ) || defined( HL1MP_DLL )
ConVar sv_airaccelerate( "sv_airaccelerate", "10", FCVAR_NOTIFY | FCVAR_REPLICATED);
ConVar sv_wateraccelerate( "sv_wateraccelerate", "10", FCVAR_NOTIFY | FCVAR_REPLICATED);
ConVar sv_waterfriction( "sv_waterfriction", "1", FCVAR_NOTIFY | FCVAR_REPLICATED);
@@ -82,13 +82,13 @@ ConVar sv_rollspeed ( "sv_rollspeed", "200", FCVAR_NOTIFY | FCVAR_REPLICATED | F
ConVar sv_rollangle ( "sv_rollangle", "0", FCVAR_NOTIFY | FCVAR_REPLICATED | FCVAR_DEVELOPMENTONLY, "Max view roll angle");
#endif // CSTRIKE_DLL
-#if defined( DOD_DLL ) || defined( CSTRIKE_DLL )
+#if defined( DOD_DLL ) || defined( CSTRIKE_DLL ) || defined( HL1MP_DLL )
ConVar sv_friction ( "sv_friction","4", FCVAR_NOTIFY | FCVAR_REPLICATED, "World friction." );
#else
ConVar sv_friction ( "sv_friction","4", FCVAR_NOTIFY | FCVAR_REPLICATED | FCVAR_DEVELOPMENTONLY, "World friction." );
#endif // DOD_DLL || CSTRIKE_DLL
-#if defined( CSTRIKE_DLL )
+#if defined( CSTRIKE_DLL ) || defined( HL1MP_DLL )
ConVar sv_bounce ( "sv_bounce","0", FCVAR_NOTIFY | FCVAR_REPLICATED, "Bounce multiplier for when physically simulated objects collide with other objects." );
ConVar sv_maxvelocity ( "sv_maxvelocity","3500", FCVAR_REPLICATED, "Maximum speed any ballistically moving object is allowed to attain per axis." );
ConVar sv_stepsize ( "sv_stepsize","18", FCVAR_NOTIFY | FCVAR_REPLICATED );
diff --git a/mp/src/game/shared/mp_shareddefs.cpp b/mp/src/game/shared/mp_shareddefs.cpp
index 561ba6fb..b555a88f 100644
--- a/mp/src/game/shared/mp_shareddefs.cpp
+++ b/mp/src/game/shared/mp_shareddefs.cpp
@@ -103,7 +103,7 @@ const char *g_pszMPConcepts[] =
"TLK_TAUNT_REPLAY", // MP_CONCEPT_TAUNT_REPLAY
"TLK_TAUNT_LAUGH", // MP_CONCEPT_TAUNT_LAUGH
"TLK_TAUNT_HEROIC_POSE", // MP_CONCEPT_TAUNT_HEROIC_POSE
- "TLK_HIGHFIVE_READY", // MP_CONCEPT_HIGHFIVE_READY
+ "TLK_PARTNER_TAUNT_READY", // MP_CONCEPT_PARTNER_TAUNT_READY
"TLK_PLAYER_HOLDTAUNT", // MP_CONCEPT_HOLDTAUNT
"TLK_TAUNT_PYRO_ARMAGEDDON", // MP_CONCEPT_TAUNT_PYRO_ARMAGEDDON
"TLK_ROCKET_DESTOYED", // MP_CONCEPT_ROCKET_DESTOYED
@@ -144,16 +144,55 @@ const char *g_pszMPConcepts[] =
"TLK_MAGIC_DANCE", // MP_CONCEPT_MAGIC_DANCE
"HalloweenLongFall", // MP_CONCEPT_HALLOWEEN_LONGFALL
"TLK_TAUNT_GUITAR_RIFF", // MP_CONCEPT_TAUNT_GUITAR_RIFF
+
+ // TF Halloween 2013 shenanigans.
+ "TLK_PLAYER_CAST_FIREBALL", // MP_CONCEPT_PLAYER_CAST_FIREBALL
+ "TLK_PLAYER_CAST_MERASMUS_ZAP", // MP_CONCEPT_PLAYER_CAST_MERASMUS_ZAP
+ "TLK_PLAYER_CAST_SELF_HEAL", // MP_CONCEPT_PLAYER_CAST_SELF_HEAL
+ "TLK_PLAYER_CAST_MIRV", // MP_CONCEPT_PLAYER_CAST_MIRV
+ "TLK_PLAYER_CAST_BLAST_JUMP", // MP_CONCEPT_PLAYER_CAST_BLAST_JUMP
+ "TLK_PLAYER_CAST_STEALTH", // MP_CONCEPT_PLAYER_CAST_STEALTH
+ "TLK_PLAYER_CAST_TELEPORT", // MP_CONCEPT_PLAYER_CAST_TELEPORT
+ "TLK_PLAYER_CAST_LIGHTNING_BALL", // MP_CONCEPT_PLAYER_CAST_LIGHTNING_BALL
+ "TLK_PLAYER_CAST_MOVEMENT_BUFF", // MP_CONCEPT_PLAYER_CAST_MOVEMENT_BUFF
+ "TLK_PLAYER_CAST_MONOCULOUS", // MP_CONCEPT_PLAYER_CAST_MONOCULOUS
+ "TLK_PLAYER_CAST_METEOR_SWARM", // MP_CONCEPT_PLAYER_CAST_METEOR_SWARM
+ "TLK_PLAYER_CAST_SKELETON_HORDE", // MP_CONCEPT_PLAYER_CAST_SKELETON_HORDE
+
+ "TLK_PLAYER_SPELL_FIREBALL", // MP_CONCEPT_PLAYER_SPELL_FIREBALL
+ "TLK_PLAYER_SPELL_MERASMUS_ZAP", // MP_CONCEPT_PLAYER_SPELL_MERASMUS_ZAP
+ "TLK_PLAYER_SPELL_SELF_HEAL", // MP_CONCEPT_PLAYER_SPELL_SELF_HEAL
+ "TLK_PLAYER_SPELL_MIRV", // MP_CONCEPT_PLAYER_SPELL_MIRV
+ "TLK_PLAYER_SPELL_BLAST_JUMP", // MP_CONCEPT_PLAYER_SPELL_BLAST_JUMP
+ "TLK_PLAYER_SPELL_STEALTH", // MP_CONCEPT_PLAYER_SPELL_STEALTH
+ "TLK_PLAYER_SPELL_TELEPORT", // MP_CONCEPT_PLAYER_SPELL_TELEPORT
+ "TLK_PLAYER_SPELL_LIGHTNING_BALL", // MP_CONCEPT_PLAYER_SPELL_LIGHTNING_BALL
+ "TLK_PLAYER_SPELL_MOVEMENT_BUFF", // MP_CONCEPT_PLAYER_SPELL_MOVEMENT_BUFF
+ "TLK_PLAYER_SPELL_MONOCULOUS", // MP_CONCEPT_PLAYER_SPELL_MONOCULOUS
+ "TLK_PLAYER_SPELL_METEOR_SWARM", // MP_CONCEPT_PLAYER_SPELL_METEOR_SWARM
+ "TLK_PLAYER_SPELL_SKELETON_HORDE", // MP_CONCEPT_PLAYER_SPELL_SKELETON_HORDE
+
+ // Events.
+ "TLK_PLAYER_SPELL_PICKUP_COMMON", // MP_CONCEPT_PLAYER_SPELL_PICKUP_COMMON
+ "TLK_PLAYER_SPELL_PICKUP_RARE", // MP_CONCEPT_PLAYER_SPELL_PICKUP_RARE
+ "TLK_PLAYER_HELLTOWER_MIDNIGHT", // MP_CONCEPT_PLAYER_HELLTOWER_MIDNIGHT
+ "TLK_PLAYER_SKELETON_KING_APPEAR", // MP_CONCEPT_PLAYER_SKELETON_KING_APPEAR
+
+ "TLK_MANNHATTAN_GATE_ATK", // MP_CONCEPT_MANNHATTAN_GATE_ATK
+ "TLK_MANNHATTAN_GATE_TAKE", // MP_CONCEPT_MANNHATTAN_GATE_TAKE
+ "TLK_RESURRECTED", // MP_CONCEPT_RESURRECTED
+ "TLK_MVM_LOOT_COMMON", // MP_CONCEPT_MVM_LOOT_COMMON
+ "TLK_MVM_LOOT_RARE", // MP_CONCEPT_MVM_LOOT_RARE
+ "TLK_MVM_LOOT_ULTRARARE", // MP_CONCEPT_MVM_LOOT_ULTRARARE
+ "TLK_MEDIC_HEAL_SHIELD", // MP_CONCEPT_MEDIC_HEAL_SHIELD
};
+COMPILE_TIME_ASSERT( ARRAYSIZE( g_pszMPConcepts ) == MP_TF_CONCEPT_COUNT );
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
int GetMPConceptIndexFromString( const char *pszConcept )
{
- // Make sure our concept string and enum arrays are the same length
- Assert( ARRAYSIZE( g_pszMPConcepts ) == MP_TF_CONCEPT_COUNT );
-
for ( int iConcept = 0; iConcept < ARRAYSIZE( g_pszMPConcepts ); ++iConcept )
{
if ( !Q_stricmp( pszConcept, g_pszMPConcepts[iConcept] ) )
diff --git a/mp/src/game/shared/mp_shareddefs.h b/mp/src/game/shared/mp_shareddefs.h
index bb173c52..8ad6011b 100644
--- a/mp/src/game/shared/mp_shareddefs.h
+++ b/mp/src/game/shared/mp_shareddefs.h
@@ -112,7 +112,7 @@ enum
MP_CONCEPT_TAUNT_REPLAY, // "TLK_TAUNT_REPLAY"
MP_CONCEPT_TAUNT_LAUGH, // "TLK_TAUNT_LAUGH"
MP_CONCEPT_TAUNT_HEROIC_POSE, // "TLK_TAUNT_HEROIC_POSE"
- MP_CONCEPT_HIGHFIVE_READY, // "TLK_HIGHFIVE_READY"
+ MP_CONCEPT_PARTNER_TAUNT_READY, // "TLK_PARTNER_TAUNT_READY"
MP_CONCEPT_HOLDTAUNT, // "TLK_PLAYER_HOLDTAUNT"
MP_CONCEPT_TAUNT_PYRO_ARMAGEDDON, // "TLK_TAUNT_PYRO_ARMAGEDDON"
MP_CONCEPT_ROCKET_DESTOYED, // "TLK_ROCKET_DESTOYED"
@@ -153,6 +153,48 @@ enum
MP_CONCEPT_MAGIC_DANCE, // "TLK_MAGIC_DANCE"
MP_CONCEPT_HALLOWEEN_LONGFALL,
MP_CONCEPT_TAUNT_GUITAR_RIFF, // "TLK_TAUNT_GUITAR_RIFF"
+
+ // TF Halloween 2013 shenanigans.
+ MP_CONCEPT_PLAYER_CAST_FIREBALL, // "TLK_PLAYER_CAST_FIREBALL"
+ MP_CONCEPT_PLAYER_CAST_MERASMUS_ZAP, // "TLK_PLAYER_CAST_MERASMUS_ZAP"
+ MP_CONCEPT_PLAYER_CAST_SELF_HEAL, // "TLK_PLAYER_CAST_SELF_HEAL"
+ MP_CONCEPT_PLAYER_CAST_MIRV, // "TLK_PLAYER_CAST_MIRV"
+ MP_CONCEPT_PLAYER_CAST_BLAST_JUMP, // "TLK_PLAYER_CAST_BLAST_JUMP"
+ MP_CONCEPT_PLAYER_CAST_STEALTH, // "TLK_PLAYER_CAST_STEALTH"
+ MP_CONCEPT_PLAYER_CAST_TELEPORT, // "TLK_PLAYER_CAST_TELEPORT"
+ MP_CONCEPT_PLAYER_CAST_LIGHTNING_BALL, // "TLK_PLAYER_CAST_LIGHTNING_BALL"
+ MP_CONCEPT_PLAYER_CAST_MOVEMENT_BUFF, // "TLK_PLAYER_CAST_MOVEMENT_BUFF"
+ MP_CONCEPT_PLAYER_CAST_MONOCULOUS, // "TLK_PLAYER_CAST_MONOCULOUS"
+ MP_CONCEPT_PLAYER_CAST_METEOR_SWARM, // "TLK_PLAYER_CAST_METEOR_SWARM"
+ MP_CONCEPT_PLAYER_CAST_SKELETON_HORDE, // "TLK_PLAYER_CAST_SKELETON_HORDE"
+
+ MP_CONCEPT_PLAYER_SPELL_FIREBALL, // "TLK_PLAYER_SPELL_FIREBALL"
+ MP_CONCEPT_PLAYER_SPELL_MERASMUS_ZAP, // "TLK_PLAYER_SPELL_MERASMUS_ZAP"
+ MP_CONCEPT_PLAYER_SPELL_SELF_HEAL, // "TLK_PLAYER_SPELL_SELF_HEAL"
+ MP_CONCEPT_PLAYER_SPELL_MIRV, // "TLK_PLAYER_SPELL_MIRV"
+ MP_CONCEPT_PLAYER_SPELL_BLAST_JUMP, // "TLK_PLAYER_SPELL_BLAST_JUMP"
+ MP_CONCEPT_PLAYER_SPELL_STEALTH, // "TLK_PLAYER_SPELL_STEALTH"
+ MP_CONCEPT_PLAYER_SPELL_TELEPORT, // "TLK_PLAYER_SPELL_TELEPORT"
+ MP_CONCEPT_PLAYER_SPELL_LIGHTNING_BALL, // "TLK_PLAYER_SPELL_LIGHTNING_BALL"
+ MP_CONCEPT_PLAYER_SPELL_MOVEMENT_BUFF, // "TLK_PLAYER_SPELL_MOVEMENT_BUFF"
+ MP_CONCEPT_PLAYER_SPELL_MONOCULOUS, // "TLK_PLAYER_SPELL_MONOCULOUS"
+ MP_CONCEPT_PLAYER_SPELL_METEOR_SWARM, // "TLK_PLAYER_SPELL_METEOR_SWARM"
+ MP_CONCEPT_PLAYER_SPELL_SKELETON_HORDE, // "TLK_PLAYER_SPELL_SKELETON_HORDE"
+
+ // Events.
+ MP_CONCEPT_PLAYER_SPELL_PICKUP_COMMON, // "TLK_PLAYER_SPELL_PICKUP_COMMON"
+ MP_CONCEPT_PLAYER_SPELL_PICKUP_RARE, // "TLK_PLAYER_SPELL_PICKUP_RARE"
+ MP_CONCEPT_PLAYER_HELLTOWER_MIDNIGHT, // "TLK_PLAYER_HELLTOWER_MIDNIGHT"
+ MP_CONCEPT_PLAYER_SKELETON_KING_APPEAR, // "TLK_PLAYER_SKELETON_KING_APPEAR"
+
+ MP_CONCEPT_MANNHATTAN_GATE_ATK, // "TLK_MANNHATTAN_GATE_ATK"
+ MP_CONCEPT_MANNHATTAN_GATE_TAKE, // "TLK_MANNHATTAN_GATE_TAKE"
+ MP_CONCEPT_RESURRECTED, // "TLK_RESURRECTED"
+ MP_CONCEPT_MVM_LOOT_COMMON, // "TLK_MVM_LOOT_COMMON"
+ MP_CONCEPT_MVM_LOOT_RARE, // "TLK_MVM_LOOT_RARE"
+ MP_CONCEPT_MVM_LOOT_ULTRARARE, // "TLK_MVM_LOOT_ULTRARARE"
+ MP_CONCEPT_MEDIC_HEAL_SHIELD, // "TLK_MEDIC_HEAL_SHIELD"
+
MP_TF_CONCEPT_COUNT
// Other MP_CONCEPT_* start he using MP_TF_CONCEPT_COUNT + 1 as start.
diff --git a/mp/src/game/shared/multiplay_gamerules.cpp b/mp/src/game/shared/multiplay_gamerules.cpp
index 409f2362..07932e92 100644
--- a/mp/src/game/shared/multiplay_gamerules.cpp
+++ b/mp/src/game/shared/multiplay_gamerules.cpp
@@ -641,7 +641,7 @@ ConVarRef suitcharger( "sk_suitcharger" );
//=========================================================
//=========================================================
- bool CMultiplayRules::FPlayerCanTakeDamage( CBasePlayer *pPlayer, CBaseEntity *pAttacker )
+ bool CMultiplayRules::FPlayerCanTakeDamage( CBasePlayer *pPlayer, CBaseEntity *pAttacker, const CTakeDamageInfo &info )
{
return true;
}
@@ -834,7 +834,11 @@ ConVarRef suitcharger( "sk_suitcharger" );
// If the inflictor is the killer, then it must be their current weapon doing the damage
if ( pScorer->GetActiveWeapon() )
{
+#ifdef HL1MP_DLL
+ killer_weapon_name = pScorer->GetActiveWeapon()->GetClassname();
+#else
killer_weapon_name = pScorer->GetActiveWeapon()->GetDeathNoticeName();
+#endif
}
}
else
@@ -870,7 +874,9 @@ ConVarRef suitcharger( "sk_suitcharger" );
event->SetInt("attacker", killer_ID );
event->SetInt("customkill", info.GetDamageCustom() );
event->SetInt("priority", 7 ); // HLTV event priority, not transmitted
-
+#ifdef HL1MP_DLL
+ event->SetString("weapon", killer_weapon_name );
+#endif
gameeventmanager->FireEvent( event );
}
@@ -1748,6 +1754,37 @@ ConVarRef suitcharger( "sk_suitcharger" );
}
}
+ void CMultiplayRules::RandomPlayersSpeakConceptIfAllowed( int iConcept, int iNumRandomPlayer /*= 1*/, int iTeam /*= TEAM_UNASSIGNED*/, const char *modifiers /*= NULL*/ )
+ {
+ CUtlVector< CBaseMultiplayerPlayer* > speakCandidates;
+
+ CBaseMultiplayerPlayer *pPlayer;
+ for ( int i = 1; i <= gpGlobals->maxClients; i++ )
+ {
+ pPlayer = ToBaseMultiplayerPlayer( UTIL_PlayerByIndex( i ) );
+
+ if ( !pPlayer )
+ continue;
+
+ if ( iTeam != TEAM_UNASSIGNED )
+ {
+ if ( pPlayer->GetTeamNumber() != iTeam )
+ continue;
+ }
+
+ speakCandidates.AddToTail( pPlayer );
+ }
+
+ int iSpeaker = iNumRandomPlayer;
+ while ( iSpeaker > 0 && speakCandidates.Count() > 0 )
+ {
+ int iRandomSpeaker = RandomInt( 0, speakCandidates.Count() - 1 );
+ speakCandidates[ iRandomSpeaker ]->SpeakConceptIfAllowed( iConcept, modifiers );
+ speakCandidates.FastRemove( iRandomSpeaker );
+ iSpeaker--;
+ }
+ }
+
void CMultiplayRules::ClientSettingsChanged( CBasePlayer *pPlayer )
{
// NVNT see if this user is still or has began using a haptic device
diff --git a/mp/src/game/shared/multiplay_gamerules.h b/mp/src/game/shared/multiplay_gamerules.h
index 4512c9c9..08e06e4a 100644
--- a/mp/src/game/shared/multiplay_gamerules.h
+++ b/mp/src/game/shared/multiplay_gamerules.h
@@ -136,7 +136,7 @@ public:
// Client damage rules
virtual float FlPlayerFallDamage( CBasePlayer *pPlayer );
- virtual bool FPlayerCanTakeDamage( CBasePlayer *pPlayer, CBaseEntity *pAttacker );
+ virtual bool FPlayerCanTakeDamage( CBasePlayer *pPlayer, CBaseEntity *pAttacker, const CTakeDamageInfo &info );
virtual bool AllowDamage( CBaseEntity *pVictim, const CTakeDamageInfo &info );
// Client spawn/respawn control
@@ -215,6 +215,7 @@ public:
void IncrementMapCycleIndex();
void HaveAllPlayersSpeakConceptIfAllowed( int iConcept, int iTeam = TEAM_UNASSIGNED, const char *modifiers = NULL );
+ void RandomPlayersSpeakConceptIfAllowed( int iConcept, int iNumRandomPlayer = 1, int iTeam = TEAM_UNASSIGNED, const char *modifiers = NULL );
virtual void GetTaggedConVarList( KeyValues *pCvarTagList );
diff --git a/mp/src/game/shared/particle_property.cpp b/mp/src/game/shared/particle_property.cpp
index e5a5487d..8ddc9784 100644
--- a/mp/src/game/shared/particle_property.cpp
+++ b/mp/src/game/shared/particle_property.cpp
@@ -557,6 +557,14 @@ void CParticleProperty::UpdateControlPoint( ParticleEffectList_t *pEffect, int i
if ( bUseHeadOrigin > 0 )
{
int iBone = Studio_BoneIndexByName( pAnimating->GetModelPtr(), "bip_head" );
+ if ( iBone < 0 )
+ {
+ iBone = Studio_BoneIndexByName( pAnimating->GetModelPtr(), "prp_helmet" );
+ if ( iBone < 0 )
+ {
+ iBone = Studio_BoneIndexByName( pAnimating->GetModelPtr(), "prp_hat" );
+ }
+ }
if ( iBone >= 0 )
{
bUsingHeadOrigin = true;
@@ -587,18 +595,23 @@ void CParticleProperty::UpdateControlPoint( ParticleEffectList_t *pEffect, int i
if ( !pAnimating->GetAttachment( pPoint->iAttachmentPoint, attachmentToWorld ) )
{
- Warning( "Cannot update control point %d for effect '%s'.\n", pPoint->iAttachmentPoint, pEffect->pParticleEffect->GetEffectName() );
- attachmentToWorld = pAnimating->RenderableToWorldTransform();
+ // try C_BaseAnimating if attach point is not on the weapon
+ if ( !pAnimating->C_BaseAnimating::GetAttachment( pPoint->iAttachmentPoint, attachmentToWorld ) )
+ {
+ Warning( "Cannot update control point %d for effect '%s'.\n", pPoint->iAttachmentPoint, pEffect->pParticleEffect->GetEffectName() );
+ attachmentToWorld = pAnimating->RenderableToWorldTransform();
+ }
}
- MatrixVectors( attachmentToWorld, &vecForward, &vecRight, &vecUp );
- MatrixPosition( attachmentToWorld, vecOrigin );
+ VMatrix vMat(attachmentToWorld);
+ MatrixTranslate( vMat, pPoint->vecOriginOffset );
+ MatrixVectors( vMat.As3x4(), &vecForward, &vecRight, &vecUp );
+ MatrixPosition( vMat.As3x4(), vecOrigin );
if ( pEffect->pParticleEffect->m_pDef->IsViewModelEffect() )
{
FormatViewModelAttachment( vecOrigin, true );
}
-
}
}
break;
diff --git a/mp/src/game/shared/props_shared.cpp b/mp/src/game/shared/props_shared.cpp
index 7cf4489b..6d0f9209 100644
--- a/mp/src/game/shared/props_shared.cpp
+++ b/mp/src/game/shared/props_shared.cpp
@@ -1323,7 +1323,7 @@ CBaseEntity *CreateGibsFromList( CUtlVector<breakmodel_t> &list, int modelindex,
if ( !pCollide )
return NULL;
- int nSkin = 0;
+ int nSkin = params.nDefaultSkin;
CBaseEntity *pOwnerEntity = pEntity;
CBaseAnimating *pOwnerAnim = NULL;
if ( pPhysics )
diff --git a/mp/src/game/shared/props_shared.h b/mp/src/game/shared/props_shared.h
index ee849ed2..c63cb212 100644
--- a/mp/src/game/shared/props_shared.h
+++ b/mp/src/game/shared/props_shared.h
@@ -227,6 +227,7 @@ struct breakablepropparams_t
impactEnergyScale = 0;
defBurstScale = 0;
defCollisionGroup = COLLISION_GROUP_NONE;
+ nDefaultSkin = 0;
}
const Vector &origin;
@@ -236,6 +237,7 @@ struct breakablepropparams_t
float impactEnergyScale;
float defBurstScale;
int defCollisionGroup;
+ int nDefaultSkin;
};
const char *GetMassEquivalent(float flMass);
diff --git a/mp/src/game/shared/shareddefs.h b/mp/src/game/shared/shareddefs.h
index b7103be3..842d2f06 100644
--- a/mp/src/game/shared/shareddefs.h
+++ b/mp/src/game/shared/shareddefs.h
@@ -151,8 +151,20 @@ typedef enum
VOTE_FAILED_MAP_NOT_VALID,
VOTE_FAILED_CANNOT_KICK_FOR_TIME,
VOTE_FAILED_CANNOT_KICK_DURING_ROUND,
+
+ // TF-specific?
+ VOTE_FAILED_MODIFICATION_ALREADY_ACTIVE,
} vote_create_failed_t;
+enum
+{
+#ifdef STAGING_ONLY
+ SERVER_MODIFICATION_ITEM_DURATION_IN_MINUTES = 2
+#else
+ SERVER_MODIFICATION_ITEM_DURATION_IN_MINUTES = 120
+#endif
+};
+
#define MAX_VOTE_DETAILS_LENGTH 64
#define INVALID_ISSUE -1
#define MAX_VOTE_OPTIONS 5
diff --git a/mp/src/game/shared/takedamageinfo.cpp b/mp/src/game/shared/takedamageinfo.cpp
index e83878cf..e9062d80 100644
--- a/mp/src/game/shared/takedamageinfo.cpp
+++ b/mp/src/game/shared/takedamageinfo.cpp
@@ -58,9 +58,9 @@ void CTakeDamageInfo::Init( CBaseEntity *pInflictor, CBaseEntity *pAttacker, CBa
m_vecReportedPosition = reportedPosition;
m_iAmmoType = -1;
m_iDamagedOtherPlayers = 0;
-
m_iPlayerPenetrationCount = 0;
m_flDamageBonus = 0.f;
+ m_bForceFriendlyFire = false;
}
CTakeDamageInfo::CTakeDamageInfo()
diff --git a/mp/src/game/shared/takedamageinfo.h b/mp/src/game/shared/takedamageinfo.h
index a4c01826..702e9322 100644
--- a/mp/src/game/shared/takedamageinfo.h
+++ b/mp/src/game/shared/takedamageinfo.h
@@ -77,6 +77,8 @@ public:
void SetDamageCustom( int iDamageCustom );
int GetDamageStats( void ) const;
void SetDamageStats( int iDamageStats );
+ void SetForceFriendlyFire( bool bValue ) { m_bForceFriendlyFire = bValue; }
+ bool IsForceFriendlyFire( void ) const { return m_bForceFriendlyFire; }
int GetAmmoType() const;
void SetAmmoType( int iAmmoType );
@@ -123,6 +125,7 @@ protected:
int m_iDamagedOtherPlayers;
int m_iPlayerPenetrationCount;
float m_flDamageBonus; // Anything that increases damage (crit) - store the delta
+ bool m_bForceFriendlyFire; // Ideally this would be a dmg type, but we can't add more
DECLARE_SIMPLE_DATADESC();
};
diff --git a/mp/src/game/shared/teamplay_gamerules.cpp b/mp/src/game/shared/teamplay_gamerules.cpp
index 1cbe368a..171313b3 100644
--- a/mp/src/game/shared/teamplay_gamerules.cpp
+++ b/mp/src/game/shared/teamplay_gamerules.cpp
@@ -352,9 +352,9 @@ bool CTeamplayRules::IsTeamplay( void )
return true;
}
-bool CTeamplayRules::FPlayerCanTakeDamage( CBasePlayer *pPlayer, CBaseEntity *pAttacker )
+bool CTeamplayRules::FPlayerCanTakeDamage( CBasePlayer *pPlayer, CBaseEntity *pAttacker, const CTakeDamageInfo &info )
{
- if ( pAttacker && PlayerRelationship( pPlayer, pAttacker ) == GR_TEAMMATE )
+ if ( pAttacker && PlayerRelationship( pPlayer, pAttacker ) == GR_TEAMMATE && !info.IsForceFriendlyFire() )
{
// my teammate hit me.
if ( (friendlyfire.GetInt() == 0) && (pAttacker != pPlayer) )
@@ -364,7 +364,7 @@ bool CTeamplayRules::FPlayerCanTakeDamage( CBasePlayer *pPlayer, CBaseEntity *pA
}
}
- return BaseClass::FPlayerCanTakeDamage( pPlayer, pAttacker );
+ return BaseClass::FPlayerCanTakeDamage( pPlayer, pAttacker, info );
}
//=========================================================
diff --git a/mp/src/game/shared/teamplay_gamerules.h b/mp/src/game/shared/teamplay_gamerules.h
index 10f953e1..952895eb 100644
--- a/mp/src/game/shared/teamplay_gamerules.h
+++ b/mp/src/game/shared/teamplay_gamerules.h
@@ -67,7 +67,7 @@ public:
virtual bool ClientCommand( CBaseEntity *pEdict, const CCommand &args );
virtual void ClientSettingsChanged( CBasePlayer *pPlayer );
virtual bool IsTeamplay( void );
- virtual bool FPlayerCanTakeDamage( CBasePlayer *pPlayer, CBaseEntity *pAttacker );
+ virtual bool FPlayerCanTakeDamage( CBasePlayer *pPlayer, CBaseEntity *pAttacker, const CTakeDamageInfo &info );
virtual int PlayerRelationship( CBaseEntity *pPlayer, CBaseEntity *pTarget );
virtual bool PlayerCanHearChat( CBasePlayer *pListener, CBasePlayer *pSpeaker );
virtual const char *GetTeamID( CBaseEntity *pEntity );
diff --git a/mp/src/game/shared/teamplay_round_timer.cpp b/mp/src/game/shared/teamplay_round_timer.cpp
index 63098cd6..f993749a 100644
--- a/mp/src/game/shared/teamplay_round_timer.cpp
+++ b/mp/src/game/shared/teamplay_round_timer.cpp
@@ -636,6 +636,12 @@ const char *CTeamRoundTimer::GetTimeWarningSound( int nWarning )
//-----------------------------------------------------------------------------
void CTeamRoundTimer::SendTimeWarning( int nWarning )
{
+#if defined( TF_CLIENT_DLL )
+ // don't play any time warnings for Helltower
+ if ( TFGameRules() && TFGameRules()->IsHalloweenScenario( CTFGameRules::HALLOWEEN_SCENARIO_HIGHTOWER ) )
+ return;
+#endif
+
// don't play sounds if the level designer has turned them off or if it's during the WaitingForPlayers time
if ( !m_bTimerPaused && m_bAutoCountdown && !TeamplayRoundBasedRules()->IsInWaitingForPlayers() )
{
diff --git a/mp/src/game/shared/teamplayroundbased_gamerules.cpp b/mp/src/game/shared/teamplayroundbased_gamerules.cpp
index 38f1294d..26a75b18 100644
--- a/mp/src/game/shared/teamplayroundbased_gamerules.cpp
+++ b/mp/src/game/shared/teamplayroundbased_gamerules.cpp
@@ -1267,7 +1267,7 @@ CGameRulesRoundStateInfo* CTeamplayRoundBasedRules::State_LookupInfo( gamerules_
{ GR_STATE_INIT, "GR_STATE_INIT", &CTeamplayRoundBasedRules::State_Enter_INIT, NULL, &CTeamplayRoundBasedRules::State_Think_INIT },
{ GR_STATE_PREGAME, "GR_STATE_PREGAME", &CTeamplayRoundBasedRules::State_Enter_PREGAME, NULL, &CTeamplayRoundBasedRules::State_Think_PREGAME },
{ GR_STATE_STARTGAME, "GR_STATE_STARTGAME", &CTeamplayRoundBasedRules::State_Enter_STARTGAME, NULL, &CTeamplayRoundBasedRules::State_Think_STARTGAME },
- { GR_STATE_PREROUND, "GR_STATE_PREROUND", &CTeamplayRoundBasedRules::State_Enter_PREROUND, NULL, &CTeamplayRoundBasedRules::State_Think_PREROUND },
+ { GR_STATE_PREROUND, "GR_STATE_PREROUND", &CTeamplayRoundBasedRules::State_Enter_PREROUND, &CTeamplayRoundBasedRules::State_Leave_PREROUND, &CTeamplayRoundBasedRules::State_Think_PREROUND },
{ GR_STATE_RND_RUNNING, "GR_STATE_RND_RUNNING", &CTeamplayRoundBasedRules::State_Enter_RND_RUNNING, NULL, &CTeamplayRoundBasedRules::State_Think_RND_RUNNING },
{ GR_STATE_TEAM_WIN, "GR_STATE_TEAM_WIN", &CTeamplayRoundBasedRules::State_Enter_TEAM_WIN, NULL, &CTeamplayRoundBasedRules::State_Think_TEAM_WIN },
{ GR_STATE_RESTART, "GR_STATE_RESTART", &CTeamplayRoundBasedRules::State_Enter_RESTART, NULL, &CTeamplayRoundBasedRules::State_Think_RESTART },
@@ -1427,6 +1427,14 @@ void CTeamplayRoundBasedRules::State_Enter_PREROUND( void )
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
+void CTeamplayRoundBasedRules::State_Leave_PREROUND( void )
+{
+ PreRound_End();
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
void CTeamplayRoundBasedRules::State_Think_PREROUND( void )
{
if( gpGlobals->curtime > m_flStateTransitionTime )
@@ -2159,6 +2167,7 @@ void CTeamplayRoundBasedRules::SetWinningTeam( int team, int iWinReason, bool bF
if ( event )
{
event->SetInt( "team", team );
+ event->SetInt( "winreason", iWinReason );
event->SetBool( "full_round", bForceMapReset );
event->SetFloat( "round_time", gpGlobals->curtime - m_flRoundStartTime );
event->SetBool( "was_sudden_death", bWasSuddenDeath );
@@ -3062,11 +3071,11 @@ void CTeamplayRoundBasedRules::PlayWinSong( int team )
{
if ( i == team )
{
- BroadcastSound( i, "Game.YourTeamWon" );
+ BroadcastSound( i, WinSongName( i ) );
}
else
{
- const char *pchLoseSong = LoseSongName();
+ const char *pchLoseSong = LoseSongName( i );
if ( pchLoseSong )
{
BroadcastSound( i, pchLoseSong );
@@ -3094,11 +3103,11 @@ void CTeamplayRoundBasedRules::PlaySuddenDeathSong( void )
//-----------------------------------------------------------------------------
void CTeamplayRoundBasedRules::PlayStalemateSong( void )
{
- BroadcastSound( TEAM_UNASSIGNED, "Game.Stalemate" );
+ BroadcastSound( TEAM_UNASSIGNED, GetStalemateSong( TEAM_UNASSIGNED ) );
for ( int i = FIRST_GAME_TEAM; i < GetNumberOfTeams(); i++ )
{
- BroadcastSound( i, "Game.Stalemate" );
+ BroadcastSound( i, GetStalemateSong( i ) );
}
}
diff --git a/mp/src/game/shared/teamplayroundbased_gamerules.h b/mp/src/game/shared/teamplayroundbased_gamerules.h
index 61567d49..cf584092 100644
--- a/mp/src/game/shared/teamplayroundbased_gamerules.h
+++ b/mp/src/game/shared/teamplayroundbased_gamerules.h
@@ -297,6 +297,8 @@ public:
virtual void BetweenRounds_End( void ) { return; }
virtual void BetweenRounds_Think( void ) { return; }
+ virtual void PreRound_End( void ) { return; }
+
bool PrevRoundWasWaitingForPlayers() { return m_bPrevRoundWasWaitingForPlayers; }
virtual bool ShouldScorePerRound( void ){ return true; }
@@ -415,6 +417,7 @@ protected:
void State_Think_STARTGAME( void );
void State_Enter_PREROUND( void );
+ void State_Leave_PREROUND( void );
void State_Think_PREROUND( void );
void State_Enter_RND_RUNNING( void );
@@ -456,7 +459,9 @@ protected:
void PlayStalemateSong( void );
void PlaySuddenDeathSong( void );
- virtual const char* LoseSongName( void ) { return "Game.YourTeamLost"; }
+ virtual const char* GetStalemateSong( int nTeam ) { return "Game.Stalemate"; }
+ virtual const char* WinSongName( int nTeam ) { return "Game.YourTeamWon"; }
+ virtual const char* LoseSongName( int nTeam ) { return "Game.YourTeamLost"; }
virtual void RespawnTeam( int iTeam ) { RespawnPlayers( false, true, iTeam ); }
diff --git a/mp/src/game/shared/voice_banmgr.cpp b/mp/src/game/shared/voice_banmgr.cpp
index 7f4864d7..d362d58f 100644
--- a/mp/src/game/shared/voice_banmgr.cpp
+++ b/mp/src/game/shared/voice_banmgr.cpp
@@ -54,11 +54,9 @@ bool CVoiceBanMgr::Init(const char *pGameDir)
{
int version;
filesystem->Read(&version, sizeof(version), fh);
- if(version == BANMGR_FILEVERSION)
+ if(version == BANMGR_FILEVERSION && filesystem->Size(fh) > 4 )
{
- filesystem->Seek(fh, 0, FILESYSTEM_SEEK_TAIL);
- int nIDs = (filesystem->Tell(fh) - sizeof(version)) / SIGNED_GUID_LEN;
- filesystem->Seek(fh, sizeof(version), FILESYSTEM_SEEK_CURRENT);
+ int nIDs = ( filesystem->Size( fh ) - sizeof(version)) / SIGNED_GUID_LEN;
for(int i=0; i < nIDs; i++)
{