Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 10 additions & 7 deletions src/game/client/c_baseanimating.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3619,16 +3619,19 @@ int C_BaseAnimating::InternalDrawModel( int flags )
#ifdef NEO
if (IsViewModel())
{ // view models become dark when standing close to and facing a wall, change lighting origin
auto pOwner = UTIL_PlayerByIndex(GetLocalPlayerIndex());
if (pOwner)
if (!engine->IsHLTV())
{
static Vector ownerOrigin;
ownerOrigin = pOwner->EyePosition();
pInfo->pLightingOrigin = &ownerOrigin;
auto pOwner = UTIL_PlayerByIndex(GetLocalPlayerIndex());
if (pOwner)
{
static Vector ownerOrigin;
ownerOrigin = pOwner->EyePosition();
pInfo->pLightingOrigin = &ownerOrigin;
}
}
}
else if (IsBaseCombatWeapon())
{
else if (IsBaseCombatWeapon() && !GetMoveParent())
{ // dropped weapons can become dark when they rotate such that their origin falls through the floor
static Vector worldSpaceCenter;
worldSpaceCenter = WorldSpaceCenter();
pInfo->pLightingOrigin = &worldSpaceCenter;
Expand Down
83 changes: 57 additions & 26 deletions src/game/client/game_controls/SpectatorGUI.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,8 @@ void AddSubKeyNamed( KeyValues *pKeys, const char *pszName );
#include "c_team.h"
#include "neo_gamerules.h"
#include "c_neo_player.h"
#include "view.h"
#include "hltvcamera.h"
#endif

// memdbgon must be the last include file in a .cpp file!!!
Expand Down Expand Up @@ -986,48 +988,77 @@ CON_COMMAND_F( spec_player, "Spectate player by partial name, steamid, or userid
}
}

#ifdef NEO
#ifdef NEO
CON_COMMAND_F( spec_player_under_mouse, "Spectate player by partial name, steamid, or userid", FCVAR_CLIENTCMD_CAN_EXECUTE )
{
if (engine->IsHLTV() && HLTVCamera()->IsPVSLocked())
{
ConMsg( "%s: HLTV Camera is PVS locked\n", __FUNCTION__ );
return;
}

C_NEO_Player *pNeoPlayer = C_NEO_Player::GetLocalNEOPlayer();
if ( !pNeoPlayer || !pNeoPlayer->IsObserver() )
return;

if (!engine->IsHLTV() || !HLTVCamera()->IsPVSLocked())
C_BaseEntity* currentTarget = pNeoPlayer->GetObserverTarget();
C_NEO_Player *target = nullptr;
float targetDotProduct = -1;
for (int i = 1; i <= gpGlobals->maxClients; i++)
{
C_BaseEntity* currentTarget = pNeoPlayer->GetObserverTarget();
C_NEO_Player *target = nullptr;
float targetDotProduct = -1;
for (int i = 1; i < gpGlobals->maxClients; i++)
C_NEO_Player* pPlayer = ToNEOPlayer(UTIL_PlayerByIndex(i));
if (currentTarget != pPlayer && pNeoPlayer->IsValidObserverTarget(pPlayer) && pPlayer->IsAlive())
{
C_NEO_Player* pPlayer = ToNEOPlayer(UTIL_PlayerByIndex(i));
if (currentTarget != pPlayer && pNeoPlayer->IsValidObserverTarget(pPlayer) && pPlayer->IsAlive())
Vector vecToTarget = pPlayer->WorldSpaceCenter() - MainViewOrigin();
vecToTarget.NormalizeInPlace();
float dotProduct = DotProduct(MainViewForward(), vecToTarget);
if (dotProduct > targetDotProduct && dotProduct > 0.5)
{
Vector vecForward;
AngleVectors( pNeoPlayer->EyeAngles(), &vecForward );

Vector vecToTarget = pPlayer->WorldSpaceCenter() - pNeoPlayer->EyePosition();
vecToTarget.NormalizeInPlace();
float dotProduct = DotProduct(vecForward, vecToTarget);
if (dotProduct > targetDotProduct && dotProduct > 0.5)
{
targetDotProduct = dotProduct;
target = pPlayer;
}
targetDotProduct = dotProduct;
target = pPlayer;
}
}
}

if (target)
{
engine->IsHLTV() ? HLTVCamera()->SetPrimaryTarget(target->entindex()) : engine->ClientCmd(VarArgs("spec_player_entity_number %d", target->entindex()));
}
}

if (target)
CON_COMMAND_F( spec_fastest_player, "Spectate the fastest player", FCVAR_CLIENTCMD_CAN_EXECUTE )
{
C_NEO_Player *pNeoPlayer = C_NEO_Player::GetLocalNEOPlayer();
if ( !pNeoPlayer || !pNeoPlayer->IsObserver() )
return;

if (engine->IsHLTV())
{
if (HLTVCamera()->IsPVSLocked())
{
if (engine->IsHLTV())
{
HLTVCamera()->SetPrimaryTarget(target->entindex());
}
else
ConMsg( "%s: HLTV Camera is PVS locked\n", __FUNCTION__ );
return;
}

// We have up to date information on all the players, just do it here
float fastestSpeedSquared = 0;
CBasePlayer* pFastestEntity = nullptr;
for (int i = 1; i <= gpGlobals->maxClients; i++)
{
CBasePlayer* pPlayer = UTIL_PlayerByIndex(i);
if (pPlayer && !pPlayer->IsObserver() && pPlayer->GetAbsVelocity().LengthSqr() > fastestSpeedSquared)
{
engine->ClientCmd( VarArgs("spec_player_entity_number %d", target->entindex()) );
fastestSpeedSquared = pPlayer->GetAbsVelocity().LengthSqr();
pFastestEntity = pPlayer;
}
}

if (pFastestEntity)
HLTVCamera()->SetPrimaryTarget(pFastestEntity->entindex());
}
else
{
engine->ClientCmd(VarArgs("spectate_fastest_player"));
}
}
#endif // NEO
Expand Down
138 changes: 137 additions & 1 deletion src/game/client/hltvcamera.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,12 @@
#include "c_cs_player.h"
#endif

#ifdef NEO
#include "neo_gamerules.h"
#include "c_neo_player.h"
#include "shareddefs.h"
#endif // NEO

ConVar spec_autodirector( "spec_autodirector", "1", FCVAR_CLIENTDLL | FCVAR_CLIENTCMD_CAN_EXECUTE, "Auto-director chooses best view modes while spectating" );

// memdbgon must be the last include file in a .cpp file!!!
Expand Down Expand Up @@ -74,6 +80,9 @@ void C_HLTVCamera::Init()
ListenForGameEvent( "hltv_message" );
ListenForGameEvent( "hltv_title" );
ListenForGameEvent( "hltv_status" );
#ifdef NEO
ListenForGameEvent( "player_death" );
#endif // NEO

Reset();

Expand Down Expand Up @@ -306,7 +315,11 @@ C_BaseEntity *C_HLTVCamera::GetCameraMan()

void C_HLTVCamera::CalcInEyeCamView( Vector& eyeOrigin, QAngle& eyeAngles, float& fov )
{
#ifdef NEO
C_NEO_Player *pPlayer = static_cast<C_NEO_Player*>(UTIL_PlayerByIndex( m_iTraget1 ));
#else
C_BasePlayer *pPlayer = UTIL_PlayerByIndex( m_iTraget1 );
#endif // NEO

if ( !pPlayer )
return;
Expand All @@ -324,11 +337,19 @@ void C_HLTVCamera::CalcInEyeCamView( Vector& eyeOrigin, QAngle& eyeAngles, float

if ( pPlayer->GetFlags() & FL_DUCKING )
{
#ifdef NEO
m_vCamOrigin += VEC_DUCK_VIEW_NEOSCALE(pPlayer);
#else
m_vCamOrigin += VEC_DUCK_VIEW;
#endif // NEO
}
else
{
#ifdef NEO
m_vCamOrigin += VEC_VIEW_NEOSCALE(pPlayer);
#else
m_vCamOrigin += VEC_VIEW;
#endif // NEO
}

eyeOrigin = m_vCamOrigin;
Expand Down Expand Up @@ -375,6 +396,9 @@ void C_HLTVCamera::Accelerate( Vector& wishdir, float wishspeed, float accel )
}


#ifdef NEO
extern ConVar neo_fov;
#endif // NEO
// movement code is a copy of CGameMovement::FullNoClipMove()
void C_HLTVCamera::CalcRoamingView(Vector& eyeOrigin, QAngle& eyeAngles, float& fov)
{
Expand All @@ -399,7 +423,22 @@ void C_HLTVCamera::CalcRoamingView(Vector& eyeOrigin, QAngle& eyeAngles, float&
// Copy movement amounts
float fmove = m_LastCmd.forwardmove * factor;
float smove = m_LastCmd.sidemove * factor;


#ifdef NEO
const bool bDroneMove = m_LastCmd.buttons & IN_WALK;
if (bDroneMove)
{
forward.z = 0;
if (fmove && smove)
{
const float absFMove = fabs(fmove);
const float absSMove = fabs(smove);
const float moveMagnitude = FastSqrt((absFMove * absFMove) + (absSMove * absSMove));
fmove *= absFMove / moveMagnitude;
smove *= absSMove / moveMagnitude;
}
}
#endif // NEO
VectorNormalize (forward); // Normalize remainder of vectors
VectorNormalize (right); //

Expand Down Expand Up @@ -470,7 +509,11 @@ void C_HLTVCamera::CalcRoamingView(Vector& eyeOrigin, QAngle& eyeAngles, float&

eyeOrigin = m_vCamOrigin;
eyeAngles = m_aCamAngle;
#ifdef NEO
fov = neo_fov.GetFloat();
#else
fov = m_flFOV;
#endif // NEO
}

void C_HLTVCamera::CalcFixedView(Vector& eyeOrigin, QAngle& eyeAngles, float& fov)
Expand Down Expand Up @@ -551,6 +594,10 @@ void C_HLTVCamera::CalcView(Vector& origin, QAngle& angles, float& fov)
}
}

#ifdef NEO
ConVar cl_neo_hltvcamera_spectate_next_target_on_set_mode("cl_neo_hltvcamera_spectate_next_target_on_set_mode", "1", FCVAR_ARCHIVE, "Spectate next target when changing to in-eye or chase and don't have a valid target", true, 0, true, 1);
static bool bAllowChangingModeWhenSettingPrimaryTarget = true;
#endif // NEO
void C_HLTVCamera::SetMode(int iMode)
{
if ( m_nCameraMode == iMode )
Expand All @@ -561,6 +608,14 @@ void C_HLTVCamera::SetMode(int iMode)
int iOldMode = m_nCameraMode;
m_nCameraMode = iMode;

#ifdef NEO
if (cl_neo_hltvcamera_spectate_next_target_on_set_mode.GetBool() && (iMode == OBS_MODE_IN_EYE || iMode == OBS_MODE_CHASE) && !GetPrimaryTarget())
{
bAllowChangingModeWhenSettingPrimaryTarget = false;
SpecNextPlayer(false);
bAllowChangingModeWhenSettingPrimaryTarget = true;
}
#endif // NEO
IGameEvent *event = gameeventmanager->CreateEvent( "hltv_changed_mode" );
if ( event )
{
Expand All @@ -571,6 +626,17 @@ void C_HLTVCamera::SetMode(int iMode)
}
}

#ifdef NEO
enum
{
NEO_HLTV_ON_TARGET_MODE_NOTHING = 0,
NEO_HLTV_ON_TARGET_MODE_IN_EYE,
NEO_HLTV_ON_TARGET_MODE_CHASE,

NEO_HLTV_ON_TARGET_MODE__TOTAL = NEO_HLTV_ON_TARGET_MODE_CHASE
};
ConVar cl_neo_hltvcamera_default_mode_when_setting_primary_target("cl_neo_hltvcamera_default_mode_when_setting_primary_target", "1", FCVAR_ARCHIVE, "What to do if changing primary targets and not in in-eye or chase. 0 = do nothing, 1 = switch to in-eye, 2 = switch to chase", true, 0, true, NEO_HLTV_ON_TARGET_MODE__TOTAL);
#endif // NEO
void C_HLTVCamera::SetPrimaryTarget( int nEntity )
{
if ( m_iTraget1 == nEntity )
Expand All @@ -579,6 +645,24 @@ void C_HLTVCamera::SetPrimaryTarget( int nEntity )
int iOldTarget = m_iTraget1;
m_iTraget1 = nEntity;

#ifdef NEO
if (GetMode() != OBS_MODE_IN_EYE && GetMode() != OBS_MODE_CHASE && bAllowChangingModeWhenSettingPrimaryTarget)
{
switch (cl_neo_hltvcamera_default_mode_when_setting_primary_target.GetInt())
{
case NEO_HLTV_ON_TARGET_MODE_IN_EYE:
SetMode(OBS_MODE_IN_EYE);
break;
case NEO_HLTV_ON_TARGET_MODE_CHASE:
SetMode(OBS_MODE_CHASE);
break;
case NEO_HLTV_ON_TARGET_MODE_NOTHING:
default:
break;
}
}

#endif // NEO
if ( GetMode() == OBS_MODE_ROAMING )
{
Vector vOrigin;
Expand Down Expand Up @@ -609,6 +693,37 @@ void C_HLTVCamera::SetPrimaryTarget( int nEntity )
gameeventmanager->FireEventClientSide( event );
}
}
#ifdef NEO
void C_HLTVCamera::SpectateEvent(NeoSpectateEvent event)
{
int entIndexLastPlayerMatchingEvent = -1;
switch (event)
{
case NEO_SPECTATE_EVENT_LAST_HURT:
entIndexLastPlayerMatchingEvent = NEORules()->GetLastHurt();
break;
case NEO_SPECTATE_EVENT_LAST_SHOOTER:
entIndexLastPlayerMatchingEvent = NEORules()->GetLastShooter();
break;
case NEO_SPECTATE_EVENT_LAST_ATTACKER:
entIndexLastPlayerMatchingEvent = NEORules()->GetLastAttacker();
break;
case NEO_SPECTATE_EVENT_LAST_KILLER:
entIndexLastPlayerMatchingEvent = NEORules()->GetLastKiller();
break;
case NEO_SPECTATE_EVENT_LAST_GHOSTER:
entIndexLastPlayerMatchingEvent = NEORules()->GetLastGhoster();
break;
case NEO_SPECTATE_EVENT_LAST_EVENT:
default:
entIndexLastPlayerMatchingEvent = NEORules()->GetLastEvent();
break;
}

if (entIndexLastPlayerMatchingEvent > 0)
SetPrimaryTarget(entIndexLastPlayerMatchingEvent);
}
#endif // NEO

void C_HLTVCamera::SpecNextPlayer( bool bInverse )
{
Expand Down Expand Up @@ -668,6 +783,9 @@ void C_HLTVCamera::SpecPlayerByPredicate( const char *szSearch )
return;
}

#ifdef NEO
ConVar cl_neo_hltvcamera_auto_observe_killer_if_observing_victim("cl_neo_hltvcamera_auto_observe_killer_if_observing_victim", "1", FCVAR_ARCHIVE, "If the current observer target is killed when in eye or following, switch observer target to the killer", true, 0, true, 1);
#endif // NEO
void C_HLTVCamera::FireGameEvent( IGameEvent * event)
{
if ( !engine->IsHLTV() )
Expand All @@ -683,6 +801,7 @@ void C_HLTVCamera::FireGameEvent( IGameEvent * event)
if ( !gViewPortInterface )
return;

#ifndef NEO
if ( engine->IsPlayingDemo() )
{
// for demo playback show full menu
Expand All @@ -691,6 +810,7 @@ void C_HLTVCamera::FireGameEvent( IGameEvent * event)
SetMode( OBS_MODE_ROAMING );
}
else
#endif // NEO
{
// during live broadcast only show black bars
gViewPortInterface->ShowPanel( PANEL_SPECGUI, true );
Expand Down Expand Up @@ -735,6 +855,22 @@ void C_HLTVCamera::FireGameEvent( IGameEvent * event)
return;
}

#ifdef NEO
if (Q_strcmp("player_death", type) == 0)
{
if (!cl_neo_hltvcamera_auto_observe_killer_if_observing_victim.GetBool() || (m_nCameraMode != OBS_MODE_IN_EYE && m_nCameraMode != OBS_MODE_CHASE))
return;

const int victimIndex = engine->GetPlayerForUserID(event->GetInt("userid"));
const int killerIndex = engine->GetPlayerForUserID(event->GetInt("attacker"));
if (victimIndex && m_iTraget1 == victimIndex && killerIndex)
{
SetPrimaryTarget( killerIndex );
}
return;
}

#endif // NEO
// after this only auto-director commands follow
// don't execute them if autodirector is off and PVS is unlocked
if ( !spec_autodirector.GetBool() && !IsPVSLocked() )
Expand Down
Loading
Loading