Skip to content
Draft
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
5 changes: 5 additions & 0 deletions src/game/client/c_baseplayer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -736,7 +736,12 @@ bool C_BasePlayer::IsValidObserverTarget(CBaseEntity* target)

if (player->m_lifeState == LIFE_DEAD || player->m_lifeState == LIFE_DYING)
{
#ifdef NEO
constexpr int DEATH_SPEC_TIME = 3.0f; // OGNT switches spectator targets much faster than the DEATH_ANIMATION_TIME
if ((player->m_flDeathTime + DEATH_SPEC_TIME) < gpGlobals->curtime)
#else
if ((player->m_flDeathTime + DEATH_ANIMATION_TIME) < gpGlobals->curtime)
#endif // NEO
{
return false; // allow watching until 3 seconds after death to see death animation
}
Expand Down
41 changes: 41 additions & 0 deletions src/game/client/clientmode_shared.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -823,6 +823,47 @@ int ClientModeShared::HandleSpectatorKeyInput( int down, ButtonCode_t keynum, co
engine->ClientCmd( "spec_prev" );
return 0;
}
#ifdef NEO
else if (down && pszCurrentBinding && Q_strcmp(pszCurrentBinding, "+specmouseplayer") == 0)
{
C_NEO_Player *pNeoPlayer = C_NEO_Player::GetLocalNEOPlayer();
if (!pNeoPlayer)
{
Assert(false);
return 0;
}

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())
{
Vector vecForward;
AngleVectors( pNeoPlayer->EyeAngles(), &vecForward );

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

if (target)
{
engine->ClientCmd( VarArgs("spec_player_entity_number %d", target->entindex()) );
}

return 0;
}
#endif // NEO
else if ( down && pszCurrentBinding && Q_strcmp( pszCurrentBinding, "+jump" ) == 0 )
{
engine->ClientCmd( "spec_mode" );
Expand Down
7 changes: 7 additions & 0 deletions src/game/client/in_main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -157,6 +157,7 @@ static kbutton_t in_thermoptic;
static kbutton_t in_vision;
static kbutton_t in_spec_next;
static kbutton_t in_spec_prev;
static kbutton_t in_spec_mouse_player;
#endif

/*
Expand Down Expand Up @@ -637,6 +638,9 @@ void IN_SpecNextDown(const CCommand &args) { KeyDown(&in_spec_next, args[1]); }
void IN_SpecPrevUp(const CCommand &args) { KeyUp(&in_spec_prev, args[1]); }
void IN_SpecPrevDown(const CCommand &args) { KeyDown(&in_spec_prev, args[1]); }

void IN_SpecMousePlayerDown(const CCommand &args) { KeyUp(&in_spec_mouse_player, args[1]); }
void IN_SpecMousePlayerUp(const CCommand &args) { KeyDown(&in_spec_mouse_player, args[1]); }

void IN_AimToggle(const CCommand& args)
{
if (::input->KeyState(&in_aim))
Expand Down Expand Up @@ -1887,6 +1891,9 @@ static ConCommand endspecnextplayer("-specnextplayer", IN_SpecNextUp);

static ConCommand startspecprevplayer("+specprevplayer", IN_SpecPrevDown);
static ConCommand endspecprevplayer("-specprevplayer", IN_SpecPrevUp);

static ConCommand startspecmouseplayer("+specmouseplayer", IN_SpecMousePlayerDown);
static ConCommand endspecmouseplayer("-specmouseplayer", IN_SpecMousePlayerUp);
#endif

/*
Expand Down
16 changes: 16 additions & 0 deletions src/game/server/player.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6951,6 +6951,22 @@ bool CBasePlayer::ClientCommand( const CCommand &args )

return true;
}
#ifdef NEO
else if (stricmp(cmd, "spec_player_entity_number") == 0)
{
if (GetObserverMode() > OBS_MODE_FIXED && args.ArgC() == 2)
{
int targetEntIndex = atoi( args[1] );
CBasePlayer* target = UTIL_PlayerByIndex(targetEntIndex);

if (SetObserverTarget( target )) {
m_bForcedObserverMode = false;
SetObserverMode(OBS_MODE_IN_EYE);
}
}
return true;
}
#endif // NEO
else if ( stricmp( cmd, "spec_player" ) == 0 ) // chase next player
{
if ( GetObserverMode() > OBS_MODE_FIXED && args.ArgC() == 2 )
Expand Down