mirror of
https://github.com/ENSL/NS.git
synced 2024-11-25 14:01:03 +00:00
Fix broken roaming spectator mode
* Added server cvar (mp_freespectatormode) which controls when a player can enter a free spectator mode (orbit cam, or free roaming). 0 = never, 1 = only when spectator, 2 = Always * Free roaming will now be part of the cycle when pressing the jump key * The overlay is now toggled with the crouch button * Strafing in free roaming no longer snaps to different players * Fixed bug that would break spectating completely if returning to the ready room while in free roam * You can no longer enter free roaming using the "specmode" and "spec_mode" console commands if it's disabled by the server
This commit is contained in:
parent
019045c5c7
commit
4f32271532
7 changed files with 85 additions and 68 deletions
|
@ -853,58 +853,41 @@ void CHudSpectator::HandleButtonsDown( int ButtonPressed )
|
|||
|
||||
int theNewMainMode = g_iUser1;
|
||||
|
||||
// Jump changes main window modes
|
||||
// Crouch toggles the overview mode
|
||||
if (gHUD.GetIsNSMode() && ButtonPressed & IN_DUCK)
|
||||
{
|
||||
bool theInOverviewMode = gHUD.m_Spectator.IsInOverviewMode();
|
||||
gHUD.m_Spectator.SetOverviewMode(!theInOverviewMode);
|
||||
}
|
||||
|
||||
// Jump changes spectator modes
|
||||
if ( ButtonPressed & IN_JUMP )
|
||||
{
|
||||
bool theFirstPerson = (g_iUser1 == OBS_IN_EYE);
|
||||
bool theInOverviewMode = gHUD.m_Spectator.IsInOverviewMode();
|
||||
theNewMainMode++;
|
||||
|
||||
// NS
|
||||
if(gHUD.GetIsNSMode())
|
||||
{
|
||||
// First-person full -> chase camera full -> firstperson with overview -> chase camera with overview
|
||||
if(theFirstPerson && !theInOverviewMode)
|
||||
{
|
||||
gHUD.m_Spectator.SetMode(OBS_CHASE_LOCKED);
|
||||
//gHUD.m_Spectator.SetOverviewMode(false);
|
||||
}
|
||||
else if(!theFirstPerson && !theInOverviewMode)
|
||||
{
|
||||
gHUD.m_Spectator.SetMode(OBS_IN_EYE);
|
||||
gHUD.m_Spectator.SetOverviewMode(true);
|
||||
}
|
||||
else if(theFirstPerson && theInOverviewMode)
|
||||
{
|
||||
gHUD.m_Spectator.SetMode(OBS_CHASE_LOCKED);
|
||||
//gHUD.m_Spectator.SetOverviewMode(true);
|
||||
}
|
||||
else if(!theFirstPerson && theInOverviewMode)
|
||||
{
|
||||
gHUD.m_Spectator.SetMode(OBS_IN_EYE);
|
||||
gHUD.m_Spectator.SetOverviewMode(false);
|
||||
}
|
||||
}
|
||||
// Combat
|
||||
else
|
||||
{
|
||||
// First-person full -> chase camera full
|
||||
if(theFirstPerson)
|
||||
{
|
||||
gHUD.m_Spectator.SetMode(OBS_CHASE_LOCKED);
|
||||
gHUD.m_Spectator.SetOverviewMode(false);
|
||||
}
|
||||
else
|
||||
{
|
||||
gHUD.m_Spectator.SetMode(OBS_IN_EYE);
|
||||
gHUD.m_Spectator.SetOverviewMode(false);
|
||||
}
|
||||
}
|
||||
AvHPlayMode CurrPlayMode = gHUD.GetPlayMode();
|
||||
|
||||
float FreeSpecMode = gHUD.GetServerVariableFloat("mp_freespectatormode");
|
||||
if (FreeSpecMode == 0 || (FreeSpecMode == 1 && gHUD.GetPlayMode() != PLAYMODE_OBSERVER))
|
||||
{
|
||||
while (theNewMainMode == OBS_CHASE_FREE || theNewMainMode == OBS_ROAMING)
|
||||
{
|
||||
theNewMainMode++;
|
||||
}
|
||||
}
|
||||
|
||||
if (theNewMainMode > OBS_IN_EYE)
|
||||
{
|
||||
theNewMainMode = OBS_CHASE_LOCKED;
|
||||
}
|
||||
|
||||
gHUD.m_Spectator.SetMode(theNewMainMode);
|
||||
}
|
||||
|
||||
//g_iUser1 = theNewMainMode;
|
||||
|
||||
// Attack moves to the next player
|
||||
if ( ButtonPressed & (IN_MOVELEFT | IN_MOVERIGHT) )
|
||||
if (g_iUser1 != OBS_ROAMING && ButtonPressed & (IN_MOVELEFT | IN_MOVERIGHT) )
|
||||
{
|
||||
FindNextPlayer( (ButtonPressed & IN_MOVELEFT) ? true:false );
|
||||
|
||||
|
@ -1037,25 +1020,43 @@ void CHudSpectator::HandleButtonsUp( int ButtonPressed )
|
|||
|
||||
void CHudSpectator::SetMode(int iNewMainMode)
|
||||
{
|
||||
int NewMode = iNewMainMode;
|
||||
|
||||
if (NewMode == OBS_CHASE_FREE || NewMode == OBS_ROAMING)
|
||||
{
|
||||
float FreeSpecMode = gHUD.GetServerVariableFloat("mp_freespectatormode");
|
||||
if (FreeSpecMode == 0 || (FreeSpecMode == 1 && gHUD.GetPlayMode() != PLAYMODE_OBSERVER))
|
||||
{
|
||||
if (g_iUser1 != OBS_CHASE_FREE && g_iUser1 != OBS_ROAMING)
|
||||
{
|
||||
NewMode = g_iUser1;
|
||||
}
|
||||
else
|
||||
{
|
||||
NewMode = OBS_IN_EYE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// if value == -1 keep old value
|
||||
if ( iNewMainMode == -1 )
|
||||
iNewMainMode = g_iUser1;
|
||||
if (NewMode == -1 )
|
||||
NewMode = g_iUser1;
|
||||
|
||||
// main modes ettings will override inset window settings
|
||||
if ( iNewMainMode != g_iUser1 )
|
||||
if (NewMode != g_iUser1 )
|
||||
{
|
||||
// if we are NOT in HLTV mode, main spectator mode is set on server
|
||||
if ( !gEngfuncs.IsSpectateOnly() )
|
||||
{
|
||||
char cmdstring[32];
|
||||
// forward command to server
|
||||
sprintf(cmdstring,"specmode %i",iNewMainMode );
|
||||
sprintf(cmdstring,"specmode %i", NewMode);
|
||||
gEngfuncs.pfnServerCmd(cmdstring);
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( !g_iUser2 && (iNewMainMode !=OBS_ROAMING ) ) // make sure we have a target
|
||||
if ( !g_iUser2 && (NewMode != OBS_ROAMING ) ) // make sure we have a target
|
||||
{
|
||||
// choose last Director object if still available
|
||||
if ( IsActivePlayer( gEngfuncs.GetEntityByIndex( m_lastPrimaryObject ) ) )
|
||||
|
@ -1069,7 +1070,7 @@ void CHudSpectator::SetMode(int iNewMainMode)
|
|||
}
|
||||
}
|
||||
|
||||
switch ( iNewMainMode )
|
||||
switch (NewMode)
|
||||
{
|
||||
case OBS_CHASE_LOCKED:
|
||||
g_iUser1 = OBS_CHASE_LOCKED;
|
||||
|
|
|
@ -670,7 +670,7 @@ void ClientCommand( edict_t *pEntity )
|
|||
else if (FStrEq( pcmd, "follow")) // follow a specific player
|
||||
{
|
||||
CBasePlayer * pPlayer = GetClassPtr((CBasePlayer *)pev);
|
||||
if ( pPlayer->IsObserver() )
|
||||
if ( pPlayer->IsObserver() && pPlayer->pev->iuser1 != OBS_ROAMING )
|
||||
{
|
||||
pPlayer->Observer_SpectatePlayer(atoi( CMD_ARGV(1) ));
|
||||
pPlayer->SetDefaultSpectatingSettings(pPlayer->pev->iuser1, pPlayer->pev->iuser2);
|
||||
|
@ -679,7 +679,7 @@ void ClientCommand( edict_t *pEntity )
|
|||
else if ( FStrEq( pcmd, "follownext" ) ) // follow next player
|
||||
{
|
||||
CBasePlayer * pPlayer = GetClassPtr((CBasePlayer *)pev);
|
||||
if ( pPlayer->IsObserver() )
|
||||
if ( pPlayer->IsObserver() && pPlayer->pev->iuser1 != OBS_ROAMING)
|
||||
{
|
||||
pPlayer->Observer_FindNextPlayer(atoi( CMD_ARGV(1) ));
|
||||
pPlayer->SetDefaultSpectatingSettings(pPlayer->pev->iuser1, pPlayer->pev->iuser2);
|
||||
|
|
|
@ -125,6 +125,7 @@ cvar_t avh_jumpmode = {kvJumpMode, "1", FCVAR_SERVER};
|
|||
cvar_t avh_version = {kvVersion, "330", FCVAR_SERVER};
|
||||
cvar_t avh_widescreenclamp = {kvWidescreenClamp, "0", FCVAR_SERVER};
|
||||
cvar_t avh_randomrfk = {kvRandomRfk, "0", FCVAR_SERVER};
|
||||
cvar_t avh_freespectatormode = {kvFreeSpectatorMode, "1", FCVAR_SERVER };
|
||||
|
||||
// AI Player Settings
|
||||
cvar_t avh_botsenabled = { kvBotsEnabled,"0", FCVAR_SERVER }; // Bots can be added to the server Y/N
|
||||
|
@ -285,6 +286,7 @@ void GameDLLInit( void )
|
|||
// TODO: Remove
|
||||
CVAR_REGISTER (&avh_ironman);
|
||||
CVAR_REGISTER (&avh_ironmantime);
|
||||
CVAR_REGISTER (&avh_freespectatormode);
|
||||
|
||||
#ifdef DEBUG
|
||||
CVAR_REGISTER (&avh_spawninvulnerabletime);
|
||||
|
|
|
@ -25,6 +25,8 @@
|
|||
|
||||
const float kNextTargetInterval = .2f;
|
||||
|
||||
extern cvar_t avh_freespectatormode;
|
||||
|
||||
// Find the next client in the game for this player to spectate
|
||||
bool CBasePlayer::Observer_FindNextPlayer(bool inReverse)
|
||||
{
|
||||
|
@ -270,46 +272,55 @@ void CBasePlayer::Observer_SetMode( int iMode )
|
|||
|
||||
bool theIsObserving = (thePlayer->GetPlayMode() == PLAYMODE_OBSERVER);
|
||||
|
||||
if(!theIsObserving)
|
||||
int NewMode = iMode;
|
||||
|
||||
float FreeSpecMode = avh_freespectatormode.value;
|
||||
|
||||
if (FreeSpecMode == 0 || (FreeSpecMode == 1 && !theIsObserving))
|
||||
{
|
||||
if((iMode == OBS_ROAMING) /*|| (iMode == OBS_MAP_FREE) || (iMode == OBS_MAP_CHASE)*/)
|
||||
if (NewMode == OBS_CHASE_FREE || NewMode == OBS_ROAMING)
|
||||
{
|
||||
return;
|
||||
NewMode = (pev->iuser1 == OBS_CHASE_LOCKED || pev->iuser1 == OBS_IN_EYE) ? pev->iuser1 : OBS_IN_EYE;
|
||||
}
|
||||
}
|
||||
|
||||
// Just abort if we're changing to the mode we're already in
|
||||
if ( iMode == pev->iuser1 )
|
||||
if (NewMode == pev->iuser1 )
|
||||
return;
|
||||
|
||||
// Removed by mmcguire.
|
||||
|
||||
// is valid mode ?
|
||||
if ( iMode < OBS_CHASE_LOCKED || iMode > OBS_IN_EYE )
|
||||
iMode = OBS_IN_EYE; // now it is
|
||||
if (NewMode < OBS_CHASE_LOCKED || NewMode > OBS_IN_EYE )
|
||||
NewMode = OBS_IN_EYE; // now it is
|
||||
|
||||
// if we are not roaming, we need a valid target to track
|
||||
if ( (iMode != OBS_ROAMING) && (m_hObserverTarget == NULL) )
|
||||
if ( (NewMode != OBS_ROAMING) && (m_hObserverTarget == NULL) )
|
||||
{
|
||||
Observer_FindNextPlayer();
|
||||
|
||||
// if we didn't find a valid target switch to roaming
|
||||
if (m_hObserverTarget == NULL)
|
||||
{
|
||||
iMode = OBS_ROAMING;
|
||||
NewMode = OBS_ROAMING;
|
||||
}
|
||||
}
|
||||
|
||||
// set spectator mode
|
||||
pev->iuser1 = iMode;
|
||||
pev->iuser1 = NewMode;
|
||||
|
||||
// set target if not roaming
|
||||
if (iMode == OBS_ROAMING)
|
||||
if (NewMode == OBS_ROAMING)
|
||||
{
|
||||
pev->iuser2 = 0;
|
||||
}
|
||||
else
|
||||
pev->iuser2 = ENTINDEX( m_hObserverTarget->edict() );
|
||||
{
|
||||
pev->iuser2 = ENTINDEX(m_hObserverTarget->edict());
|
||||
// Make sure our target is valid (go backward then forward)
|
||||
Observer_FindNextPlayer(true);
|
||||
Observer_FindNextPlayer(false);
|
||||
}
|
||||
|
||||
|
||||
// Make sure our target is valid (go backward then forward)
|
||||
Observer_FindNextPlayer(true);
|
||||
Observer_FindNextPlayer(false);
|
||||
}
|
|
@ -1694,7 +1694,7 @@ void CBasePlayer::StartObserver( Vector vecPosition, Vector vecViewAngle )
|
|||
pev->deadflag = DEAD_RESPAWNABLE;
|
||||
|
||||
// Tell the physics code that this player's now in observer mode
|
||||
Observer_SetMode(this->GetDefaultSpectatingMode());
|
||||
Observer_SetMode(OBS_IN_EYE);
|
||||
Observer_SpectatePlayer(this->GetDefaultSpectatingTarget());
|
||||
m_flNextObserverInput = 0;
|
||||
}
|
||||
|
|
|
@ -231,6 +231,7 @@ extern cvar_t avh_ironman;
|
|||
extern cvar_t avh_mapvoteratio;
|
||||
extern cvar_t avh_structurelimit;
|
||||
extern cvar_t avh_version;
|
||||
extern cvar_t avh_freespectatormode;
|
||||
|
||||
extern cvar_t avh_botsenabled;
|
||||
extern cvar_t avh_botautomode;
|
||||
|
@ -348,6 +349,7 @@ AvHGamerules::AvHGamerules() : mTeamA(TEAM_ONE), mTeamB(TEAM_TWO)
|
|||
RegisterServerVariable(&avh_structurelimit);
|
||||
RegisterServerVariable(&avh_version);
|
||||
RegisterServerVariable(&avh_widescreenclamp);
|
||||
RegisterServerVariable(&avh_freespectatormode);
|
||||
|
||||
//playtest cvars
|
||||
RegisterServerVariable(&avh_fastjp);
|
||||
|
|
|
@ -142,6 +142,7 @@ float ns_cvar_float(const cvar_t *cvar);
|
|||
#define kvPerformance "mp_performance"
|
||||
#define kvIronMan "mp_ironman"
|
||||
#define kvIronManTime "mp_ironmantime"
|
||||
#define kvFreeSpectatorMode "mp_freespectatormode"
|
||||
|
||||
#define kvBotsEnabled "mp_botsenabled"
|
||||
#define kvBotMinPlayers "mp_botminplayers"
|
||||
|
|
Loading…
Reference in a new issue