// Handle buttons in observer mode void CBasePlayer::Observer_HandleButtons() { // Slow down mouse clicks if ( m_flNextObserverInput > gpGlobals->time ) return; // Jump changes from modes: Chase to Roaming if ( m_afButtonPressed & IN_JUMP ) { if ( pev->iuser1 == OBS_ROAMING ) Observer_SetMode( OBS_CHASE_LOCKED ); else if ( pev->iuser1 == OBS_CHASE_LOCKED ) Observer_SetMode( OBS_CHASE_FREE ); else Observer_SetMode( OBS_ROAMING ); m_flNextObserverInput = gpGlobals->time + 0.2; } // Attack moves to the next player if ( m_afButtonPressed & IN_ATTACK && pev->iuser1 != OBS_ROAMING ) { Observer_FindNextPlayer( false ); m_flNextObserverInput = gpGlobals->time + 0.2; } // Attack2 moves to the prev player if ( m_afButtonPressed & IN_ATTACK2 && pev->iuser1 != OBS_ROAMING ) { Observer_FindNextPlayer( true ); m_flNextObserverInput = gpGlobals->time + 0.2; } }
/* <11c9d3> ../cstrike/dlls/observer.cpp:304 */ void CBasePlayer::Observer_CheckTarget() { if (pev->iuser1 == OBS_ROAMING && !m_bWasFollowing) return; if (m_bWasFollowing) { Observer_FindNextPlayer(false); if (m_hObserverTarget) Observer_SetMode(m_iObserverLastMode); } else { int lastMode; // try to find a traget if we have no current one if (!m_hObserverTarget) Observer_FindNextPlayer(false); if (m_hObserverTarget) { int iPlayerIndex = ENTINDEX(m_hObserverTarget->edict()); CBasePlayer *target = static_cast<CBasePlayer *>(UTIL_PlayerByIndex(iPlayerIndex)); // check taget if (!target || target->pev->deadflag == DEAD_RESPAWNABLE || (target->pev->effects & EF_NODRAW)) Observer_FindNextPlayer(false); else if (target->pev->deadflag == DEAD_DEAD && gpGlobals->time > target->m_fDeadTime + 2.0f) { // 3 secs after death change target Observer_FindNextPlayer(false); if (!m_hObserverTarget) { lastMode = pev->iuser1; Observer_SetMode(OBS_ROAMING); m_iObserverLastMode = lastMode; m_bWasFollowing = true; } } } // no target found at all else { lastMode = pev->iuser1; Observer_SetMode(OBS_ROAMING); // don't overwrite users lastmode m_iObserverLastMode = lastMode; } } }
void CBasePlayer::Observer_CheckTarget() { if( pev->iuser1 == OBS_ROAMING ) return; // try to find a traget if we have no current one if ( m_hObserverTarget == NULL) { Observer_FindNextPlayer( false ); if (m_hObserverTarget == NULL) { // no target found at all int lastMode = pev->iuser1; Observer_SetMode( OBS_ROAMING ); m_iObserverLastMode = lastMode; // don't overwrite users lastmode return; // we still have np target return } } CBasePlayer* target = (CBasePlayer*)(UTIL_PlayerByIndex( ENTINDEX(m_hObserverTarget->edict()))); if ( !target ) { Observer_FindNextPlayer( false ); return; } // check taget if (target->pev->deadflag == DEAD_DEAD) { if ( (target->m_fDeadTime + 2.0f ) < gpGlobals->time ) { // 3 secs after death change target Observer_FindNextPlayer( false ); return; } } }
/* <11c9ac> ../cstrike/dlls/observer.cpp:254 */ void CBasePlayer::Observer_HandleButtons() { // Slow down mouse clicks if (m_flNextObserverInput > gpGlobals->time) return; // Jump changes from modes: Chase to Roaming if (m_afButtonPressed & IN_JUMP) { switch (pev->iuser1) { case OBS_CHASE_LOCKED: Observer_SetMode(OBS_IN_EYE); break; case OBS_CHASE_FREE: Observer_SetMode(OBS_IN_EYE); break; case OBS_IN_EYE: Observer_SetMode(OBS_ROAMING); break; case OBS_ROAMING: Observer_SetMode(OBS_MAP_FREE); break; case OBS_MAP_FREE: Observer_SetMode(OBS_MAP_CHASE); break; default: Observer_SetMode(m_bObserverAutoDirector ? OBS_CHASE_LOCKED : OBS_CHASE_FREE); break; } m_flNextObserverInput = gpGlobals->time + 0.2f; } // Attack moves to the next player if (m_afButtonPressed & IN_ATTACK) { Observer_FindNextPlayer(false); m_flNextObserverInput = gpGlobals->time + 0.2f; } // Attack2 moves to the prev player if (m_afButtonPressed & IN_ATTACK2) { Observer_FindNextPlayer(true); m_flNextObserverInput = gpGlobals->time + 0.2f; } }
// Attempt to change the observer mode void CBasePlayer::Observer_SetMode( int iMode ) { // Just abort if we're changing to the mode we're already in if ( iMode == pev->iuser1 ) return; // Changing to Roaming? if ( iMode == OBS_ROAMING ) { // MOD AUTHORS: If you don't want to allow roaming observers at all in your mod, just abort here. pev->iuser1 = OBS_ROAMING; pev->iuser2 = 0; ClientPrint( pev, HUD_PRINTCENTER, "#Spec_Mode3" ); pev->maxspeed = 320; return; } // Changing to Chase Lock? if ( iMode == OBS_CHASE_LOCKED ) { // If changing from Roaming, or starting observing, make sure there is a target if ( m_hObserverTarget == NULL ) Observer_FindNextPlayer( false ); if (m_hObserverTarget) { pev->iuser1 = OBS_CHASE_LOCKED; pev->iuser2 = ENTINDEX( m_hObserverTarget->edict() ); ClientPrint( pev, HUD_PRINTCENTER, "#Spec_Mode1" ); pev->maxspeed = 0; } else { ClientPrint( pev, HUD_PRINTCENTER, "#Spec_NoTarget" ); Observer_SetMode(OBS_ROAMING); } return; } // Changing to Chase Freelook? if ( iMode == OBS_CHASE_FREE ) { // If changing from Roaming, or starting observing, make sure there is a target if ( m_hObserverTarget == NULL ) Observer_FindNextPlayer( false ); if (m_hObserverTarget) { pev->iuser1 = OBS_CHASE_FREE; pev->iuser2 = ENTINDEX( m_hObserverTarget->edict() ); ClientPrint( pev, HUD_PRINTCENTER, "#Spec_Mode2" ); pev->maxspeed = 0; } else { ClientPrint( pev, HUD_PRINTCENTER, "#Spec_NoTarget" ); Observer_SetMode(OBS_ROAMING); } return; } }
// Player has become a spectator. Set it up. // This was moved from player.cpp. void CBasePlayer::StartObserver( Vector vecPosition, Vector vecViewAngle ) { if( pev->iuser1 ) return; // clear any clientside entities attached to this player MESSAGE_BEGIN( MSG_PAS, SVC_TEMPENTITY, pev->origin ); WRITE_BYTE( TE_KILLPLAYERATTACHMENTS ); WRITE_BYTE( (BYTE)entindex() ); MESSAGE_END(); // Holster weapon immediately, to allow it to cleanup if (m_pActiveItem) m_pActiveItem->Holster( ); if ( m_pTank != NULL ) { m_pTank->Use( this, this, USE_OFF, 0 ); m_pTank = NULL; } // clear out the suit message cache so we don't keep chattering SetSuitUpdate(NULL, FALSE, 0); // Tell Ammo Hud that the player is dead MESSAGE_BEGIN( MSG_ONE, gmsgCurWeapon, NULL, pev ); WRITE_BYTE(0); WRITE_BYTE(0XFF); WRITE_BYTE(0xFF); MESSAGE_END(); // reset FOV and scope m_iFOV = m_iClientFOV = 0; pev->fov = m_iFOV; MESSAGE_BEGIN( MSG_ONE, gmsgSetFOV, NULL, pev ); WRITE_BYTE(0); MESSAGE_END(); MESSAGE_BEGIN( MSG_ONE, gmsgScopeToggle, NULL, pev ); WRITE_BYTE( 0 ); MESSAGE_END(); // Setup flags m_iHideHUD = (HIDEHUD_HEALTH | HIDEHUD_WEAPONS); m_afPhysicsFlags |= PFLAG_OBSERVER; pev->effects = EF_NODRAW; pev->view_ofs = g_vecZero; pev->angles = pev->v_angle = vecViewAngle; pev->fixangle = TRUE; pev->solid = SOLID_NOT; pev->takedamage = DAMAGE_NO; pev->movetype = MOVETYPE_NONE; ClearBits( m_afPhysicsFlags, PFLAG_DUCKING ); ClearBits( pev->flags, FL_DUCKING ); pev->deadflag = DEAD_RESPAWNABLE; pev->health = 1; // Clear out the status bar m_fInitHUD = TRUE; // Remove all the player's stuff RemoveAllItems( FALSE ); // Move them to the new position UTIL_SetOrigin( pev, vecPosition ); // Find a player to watch m_flNextObserverInput = 0; Observer_SetMode(OBS_CHASE_LOCKED); // Tell all clients this player is now a spectator // Update Team Status pev->team = 0; MESSAGE_BEGIN( MSG_ALL, gmsgScoreInfo ); WRITE_BYTE( ENTINDEX( edict() ) ); // client number WRITE_SHORT( pev->frags ); WRITE_SHORT( m_iDeaths ); WRITE_SHORT( 1 ); WRITE_SHORT( pev->team ); MESSAGE_END(); }