This repository has been archived by the owner on May 4, 2022. It is now read-only.
forked from FWGS/hlsdk-portable
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
a522ae2
commit ecaba0d
Showing
10 changed files
with
278 additions
and
27 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,268 @@ | ||
//=========== (C) Copyright 1999 Valve, L.L.C. All rights reserved. =========== | ||
// | ||
// The copyright to the contents herein is the property of Valve, L.L.C. | ||
// The contents may be used and/or copied only with the written permission of | ||
// Valve, L.L.C., or in accordance with the terms and conditions stipulated in | ||
// the agreement/contract under which the contents have been supplied. | ||
// | ||
// Purpose: Functionality for the observer chase camera | ||
// | ||
// $Workfile: $ | ||
// $Date: $ | ||
// | ||
//----------------------------------------------------------------------------- | ||
// $Log: $ | ||
// | ||
// $NoKeywords: $ | ||
//============================================================================= | ||
#include "extdll.h" | ||
#include "util.h" | ||
#include "cbase.h" | ||
#include "player.h" | ||
#include "weapons.h" | ||
#include "pm_shared.h" | ||
|
||
extern int gmsgCurWeapon; | ||
extern int gmsgSetFOV; | ||
// Find the next client in the game for this player to spectate | ||
void CBasePlayer::Observer_FindNextPlayer( bool bReverse ) | ||
{ | ||
// MOD AUTHORS: Modify the logic of this function if you want to restrict the observer to watching | ||
// only a subset of the players. e.g. Make it check the target's team. | ||
int iStart; | ||
if( m_hObserverTarget ) | ||
iStart = ENTINDEX( m_hObserverTarget->edict() ); | ||
else | ||
iStart = ENTINDEX( edict() ); | ||
int iCurrent = iStart; | ||
m_hObserverTarget = NULL; | ||
int iDir = bReverse ? -1 : 1; | ||
|
||
do | ||
{ | ||
iCurrent += iDir; | ||
|
||
// Loop through the clients | ||
if( iCurrent > gpGlobals->maxClients ) | ||
iCurrent = 1; | ||
if( iCurrent < 1 ) | ||
iCurrent = gpGlobals->maxClients; | ||
|
||
CBaseEntity *pEnt = UTIL_PlayerByIndex( iCurrent ); | ||
if( !pEnt ) | ||
continue; | ||
if( pEnt == this ) | ||
continue; | ||
// Don't spec observers or players who haven't picked a class yet | ||
if( ( (CBasePlayer*)pEnt )->IsObserver() || ( pEnt->pev->effects & EF_NODRAW ) ) | ||
continue; | ||
|
||
// MOD AUTHORS: Add checks on target here. | ||
m_hObserverTarget = pEnt; | ||
break; | ||
}while( iCurrent != iStart ); | ||
|
||
// Did we find a target? | ||
if( m_hObserverTarget ) | ||
{ | ||
// Move to the target | ||
UTIL_SetOrigin( pev, m_hObserverTarget->pev->origin ); | ||
|
||
// ALERT( at_console, "Now Tracking %s\n", STRING( m_hObserverTarget->pev->netname ) ); | ||
|
||
// Store the target in pev so the physics DLL can get to it | ||
if( pev->iuser1 != OBS_ROAMING ) | ||
pev->iuser2 = ENTINDEX( m_hObserverTarget->edict() ); | ||
} | ||
} | ||
|
||
// 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_CHASE_LOCKED ) | ||
Observer_SetMode( OBS_CHASE_FREE ); | ||
else if( pev->iuser1 == OBS_CHASE_FREE ) | ||
Observer_SetMode( OBS_IN_EYE ); | ||
else if( pev->iuser1 == OBS_IN_EYE ) | ||
Observer_SetMode( OBS_ROAMING ); | ||
else if( pev->iuser1 == OBS_ROAMING ) | ||
Observer_SetMode( OBS_MAP_FREE ); | ||
else if( pev->iuser1 == OBS_MAP_FREE ) | ||
Observer_SetMode( OBS_MAP_CHASE ); | ||
else | ||
Observer_SetMode( OBS_CHASE_FREE ); // don't use OBS_CHASE_LOCKED anymore | ||
|
||
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; | ||
} | ||
} | ||
|
||
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; | ||
} | ||
} | ||
} | ||
|
||
void CBasePlayer::Observer_CheckProperties() | ||
{ | ||
// try to find a traget if we have no current one | ||
if( pev->iuser1 == OBS_IN_EYE && m_hObserverTarget != NULL ) | ||
{ | ||
CBasePlayer* target = (CBasePlayer*)( UTIL_PlayerByIndex( ENTINDEX( m_hObserverTarget->edict() ) ) ); | ||
|
||
if( !target ) | ||
return; | ||
|
||
int weapon = ( target->m_pActiveItem != NULL ) ? target->m_pActiveItem->m_iId : 0; | ||
// use fov of tracked client | ||
if( m_iFOV != target->m_iFOV || m_iObserverWeapon != weapon ) | ||
{ | ||
m_iFOV = target->m_iFOV; | ||
m_iClientFOV = m_iFOV; | ||
// write fov before wepon data, so zoomed crosshair is set correctly | ||
MESSAGE_BEGIN( MSG_ONE, gmsgSetFOV, NULL, pev ); | ||
WRITE_BYTE( m_iFOV ); | ||
MESSAGE_END(); | ||
|
||
m_iObserverWeapon = weapon; | ||
//send weapon update | ||
MESSAGE_BEGIN( MSG_ONE, gmsgCurWeapon, NULL, pev ); | ||
WRITE_BYTE( 1 ); // 1 = current weapon, not on target | ||
WRITE_BYTE( m_iObserverWeapon ); | ||
WRITE_BYTE( 0 ); // clip | ||
MESSAGE_END(); | ||
} | ||
} | ||
else | ||
{ | ||
m_iFOV = 90; | ||
|
||
if( m_iObserverWeapon != 0 ) | ||
{ | ||
m_iObserverWeapon = 0; | ||
|
||
MESSAGE_BEGIN( MSG_ONE, gmsgCurWeapon, NULL, pev ); | ||
WRITE_BYTE( 1 ); // 1 = current weapon | ||
WRITE_BYTE( m_iObserverWeapon ); | ||
WRITE_BYTE( 0 ); // clip | ||
MESSAGE_END(); | ||
} | ||
} | ||
} | ||
|
||
// 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; | ||
|
||
// is valid mode ? | ||
if( iMode < OBS_CHASE_LOCKED || iMode > OBS_MAP_CHASE ) | ||
iMode = OBS_IN_EYE; // now it is | ||
// verify observer target again | ||
if( m_hObserverTarget != NULL ) | ||
{ | ||
CBaseEntity *pEnt = m_hObserverTarget; | ||
|
||
if( ( pEnt == this ) || ( pEnt == NULL ) ) | ||
m_hObserverTarget = NULL; | ||
else if( ( (CBasePlayer*)pEnt )->IsObserver() || ( pEnt->pev->effects & EF_NODRAW ) ) | ||
m_hObserverTarget = NULL; | ||
} | ||
|
||
// set spectator mode | ||
pev->iuser1 = iMode; | ||
|
||
// if we are not roaming, we need a valid target to track | ||
if( ( iMode != OBS_ROAMING ) && ( m_hObserverTarget == NULL ) ) | ||
{ | ||
Observer_FindNextPlayer( false ); | ||
|
||
// if we didn't find a valid target switch to roaming | ||
if( m_hObserverTarget == NULL ) | ||
{ | ||
ClientPrint( pev, HUD_PRINTCENTER, "#Spec_NoTarget" ); | ||
pev->iuser1 = OBS_ROAMING; | ||
} | ||
} | ||
|
||
// set target if not roaming | ||
if( pev->iuser1 == OBS_ROAMING ) | ||
{ | ||
pev->iuser2 = 0; | ||
} | ||
else | ||
pev->iuser2 = ENTINDEX( m_hObserverTarget->edict() ); | ||
|
||
pev->iuser3 = 0; // clear second target from death cam | ||
|
||
// print spepctaor mode on client screen | ||
|
||
char modemsg[16]; | ||
sprintf( modemsg,"#Spec_Mode%i", pev->iuser1 ); | ||
ClientPrint( pev, HUD_PRINTCENTER, modemsg ); | ||
|
||
m_iObserverLastMode = iMode; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters