mirror of
https://github.com/nillerusr/source-engine.git
synced 2026-08-14 12:46:58 +00:00
1
This commit is contained in:
@@ -0,0 +1,735 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
//=============================================================================//
|
||||
|
||||
#include "cbase.h"
|
||||
#include "npcevent.h"
|
||||
#include "vehicle_base.h"
|
||||
#include "engine/IEngineSound.h"
|
||||
#include "in_buttons.h"
|
||||
#include "soundenvelope.h"
|
||||
#include "soundent.h"
|
||||
#include "physics_saverestore.h"
|
||||
#include "vphysics/constraints.h"
|
||||
#include "vcollide_parse.h"
|
||||
#include "ndebugoverlay.h"
|
||||
#include "hl2_player.h"
|
||||
#include "props.h"
|
||||
|
||||
// memdbgon must be the last include file in a .cpp file!!!
|
||||
#include "tier0/memdbgon.h"
|
||||
|
||||
#define VEHICLE_HITBOX_DRIVER 1
|
||||
|
||||
|
||||
//
|
||||
// Anim events.
|
||||
//
|
||||
enum
|
||||
{
|
||||
AE_POD_OPEN = 1, // The pod is now open and can be entered or exited.
|
||||
AE_POD_CLOSE = 2, // The pod is now closed and cannot be entered or exited.
|
||||
};
|
||||
|
||||
|
||||
extern ConVar g_debug_vehicledriver;
|
||||
|
||||
|
||||
class CPropVehiclePrisonerPod;
|
||||
|
||||
|
||||
// Pod bones that have physics followers
|
||||
static const char *pPodFollowerBoneNames[] =
|
||||
{
|
||||
"base",
|
||||
};
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
class CPrisonerPodServerVehicle : public CBaseServerVehicle
|
||||
{
|
||||
typedef CBaseServerVehicle BaseClass;
|
||||
|
||||
// IServerVehicle
|
||||
public:
|
||||
void GetVehicleViewPosition( int nRole, Vector *pAbsOrigin, QAngle *pAbsAngles, float *pFOV = NULL );
|
||||
virtual void ItemPostFrame( CBasePlayer *pPlayer );
|
||||
|
||||
virtual bool IsPassengerEntering( void ) { return false; } // NOTE: This mimics the scenario HL2 would have seen
|
||||
virtual bool IsPassengerExiting( void ) { return false; }
|
||||
|
||||
protected:
|
||||
|
||||
CPropVehiclePrisonerPod *GetPod( void );
|
||||
};
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
class CPropVehiclePrisonerPod : public CPhysicsProp, public IDrivableVehicle
|
||||
{
|
||||
DECLARE_CLASS( CPropVehiclePrisonerPod, CPhysicsProp );
|
||||
|
||||
public:
|
||||
DECLARE_DATADESC();
|
||||
DECLARE_SERVERCLASS();
|
||||
|
||||
CPropVehiclePrisonerPod( void )
|
||||
{
|
||||
m_ServerVehicle.SetVehicle( this );
|
||||
}
|
||||
|
||||
~CPropVehiclePrisonerPod( void )
|
||||
{
|
||||
}
|
||||
|
||||
// CBaseEntity
|
||||
virtual void Precache( void );
|
||||
void Spawn( void );
|
||||
void Think(void);
|
||||
virtual int ObjectCaps( void ) { return BaseClass::ObjectCaps() | FCAP_IMPULSE_USE; };
|
||||
virtual void Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value );
|
||||
virtual void DrawDebugGeometryOverlays( void );
|
||||
|
||||
virtual Vector BodyTarget( const Vector &posSrc, bool bNoisy = true );
|
||||
virtual void TraceAttack( const CTakeDamageInfo &info, const Vector &vecDir, trace_t *ptr, CDmgAccumulator *pAccumulator );
|
||||
virtual int OnTakeDamage( const CTakeDamageInfo &info );
|
||||
|
||||
void PlayerControlInit( CBasePlayer *pPlayer );
|
||||
void PlayerControlShutdown( void );
|
||||
void ResetUseKey( CBasePlayer *pPlayer );
|
||||
|
||||
virtual bool OverridePropdata() { return true; }
|
||||
|
||||
void GetVectors(Vector* pForward, Vector* pRight, Vector* pUp) const;
|
||||
|
||||
bool ShouldForceExit() { return m_bForcedExit; }
|
||||
void ClearForcedExit() { m_bForcedExit = false; }
|
||||
|
||||
// CBaseAnimating
|
||||
void HandleAnimEvent( animevent_t *pEvent );
|
||||
|
||||
// Inputs
|
||||
void InputEnterVehicleImmediate( inputdata_t &inputdata );
|
||||
void InputEnterVehicle( inputdata_t &inputdata );
|
||||
void InputExitVehicle( inputdata_t &inputdata );
|
||||
void InputLock( inputdata_t &inputdata );
|
||||
void InputUnlock( inputdata_t &inputdata );
|
||||
void InputOpen( inputdata_t &inputdata );
|
||||
void InputClose( inputdata_t &inputdata );
|
||||
|
||||
CNetworkHandle( CBasePlayer, m_hPlayer );
|
||||
|
||||
// IDrivableVehicle
|
||||
public:
|
||||
|
||||
virtual bool PassengerShouldReceiveDamage( CTakeDamageInfo &info )
|
||||
{
|
||||
if ( info.GetDamageType() & DMG_VEHICLE )
|
||||
return true;
|
||||
|
||||
return (info.GetDamageType() & (DMG_RADIATION|DMG_BLAST) ) == 0;
|
||||
}
|
||||
|
||||
virtual CBaseEntity *GetDriver( void );
|
||||
virtual void ProcessMovement( CBasePlayer *pPlayer, CMoveData *pMoveData ) { return; }
|
||||
virtual void FinishMove( CBasePlayer *player, CUserCmd *ucmd, CMoveData *move ) { return; }
|
||||
virtual bool CanEnterVehicle( CBaseEntity *pEntity );
|
||||
virtual bool CanExitVehicle( CBaseEntity *pEntity );
|
||||
virtual void SetVehicleEntryAnim( bool bOn );
|
||||
virtual void SetVehicleExitAnim( bool bOn, Vector vecEyeExitEndpoint ) { m_bExitAnimOn = bOn; if ( bOn ) m_vecEyeExitEndpoint = vecEyeExitEndpoint; }
|
||||
virtual void EnterVehicle( CBaseCombatCharacter *pPassenger );
|
||||
|
||||
virtual bool AllowBlockedExit( CBaseCombatCharacter *pPassenger, int nRole ) { return true; }
|
||||
virtual bool AllowMidairExit( CBaseCombatCharacter *pPassenger, int nRole ) { return true; }
|
||||
virtual void PreExitVehicle( CBaseCombatCharacter *pPassenger, int nRole ) {}
|
||||
virtual void ExitVehicle( int nRole );
|
||||
|
||||
virtual void ItemPostFrame( CBasePlayer *pPlayer ) {}
|
||||
virtual void SetupMove( CBasePlayer *player, CUserCmd *ucmd, IMoveHelper *pHelper, CMoveData *move ) {}
|
||||
virtual string_t GetVehicleScriptName() { return m_vehicleScript; }
|
||||
|
||||
// If this is a vehicle, returns the vehicle interface
|
||||
virtual IServerVehicle *GetServerVehicle() { return &m_ServerVehicle; }
|
||||
|
||||
protected:
|
||||
|
||||
// Contained IServerVehicle
|
||||
CPrisonerPodServerVehicle m_ServerVehicle;
|
||||
|
||||
private:
|
||||
|
||||
// Entering / Exiting
|
||||
bool m_bLocked;
|
||||
CNetworkVar( bool, m_bEnterAnimOn );
|
||||
CNetworkVar( bool, m_bExitAnimOn );
|
||||
CNetworkVector( m_vecEyeExitEndpoint );
|
||||
bool m_bForcedExit;
|
||||
|
||||
// Vehicle script filename
|
||||
string_t m_vehicleScript;
|
||||
|
||||
COutputEvent m_playerOn;
|
||||
COutputEvent m_playerOff;
|
||||
COutputEvent m_OnOpen;
|
||||
COutputEvent m_OnClose;
|
||||
};
|
||||
|
||||
LINK_ENTITY_TO_CLASS( prop_vehicle_prisoner_pod, CPropVehiclePrisonerPod );
|
||||
|
||||
|
||||
BEGIN_DATADESC( CPropVehiclePrisonerPod )
|
||||
|
||||
// Inputs
|
||||
DEFINE_INPUTFUNC( FIELD_VOID, "Lock", InputLock ),
|
||||
DEFINE_INPUTFUNC( FIELD_VOID, "Unlock", InputUnlock ),
|
||||
DEFINE_INPUTFUNC( FIELD_VOID, "EnterVehicle", InputEnterVehicle ),
|
||||
DEFINE_INPUTFUNC( FIELD_VOID, "EnterVehicleImmediate", InputEnterVehicleImmediate ),
|
||||
DEFINE_INPUTFUNC( FIELD_VOID, "ExitVehicle", InputExitVehicle ),
|
||||
DEFINE_INPUTFUNC( FIELD_VOID, "Open", InputOpen ),
|
||||
DEFINE_INPUTFUNC( FIELD_VOID, "Close", InputClose ),
|
||||
|
||||
// Keys
|
||||
DEFINE_EMBEDDED( m_ServerVehicle ),
|
||||
|
||||
DEFINE_FIELD( m_hPlayer, FIELD_EHANDLE ),
|
||||
DEFINE_FIELD( m_bEnterAnimOn, FIELD_BOOLEAN ),
|
||||
DEFINE_FIELD( m_bExitAnimOn, FIELD_BOOLEAN ),
|
||||
DEFINE_FIELD( m_bForcedExit, FIELD_BOOLEAN ),
|
||||
DEFINE_FIELD( m_vecEyeExitEndpoint, FIELD_POSITION_VECTOR ),
|
||||
|
||||
DEFINE_KEYFIELD( m_vehicleScript, FIELD_STRING, "vehiclescript" ),
|
||||
DEFINE_KEYFIELD( m_bLocked, FIELD_BOOLEAN, "vehiclelocked" ),
|
||||
|
||||
DEFINE_OUTPUT( m_playerOn, "PlayerOn" ),
|
||||
DEFINE_OUTPUT( m_playerOff, "PlayerOff" ),
|
||||
DEFINE_OUTPUT( m_OnOpen, "OnOpen" ),
|
||||
DEFINE_OUTPUT( m_OnClose, "OnClose" ),
|
||||
|
||||
END_DATADESC()
|
||||
|
||||
IMPLEMENT_SERVERCLASS_ST(CPropVehiclePrisonerPod, DT_PropVehiclePrisonerPod)
|
||||
SendPropEHandle(SENDINFO(m_hPlayer)),
|
||||
SendPropBool(SENDINFO(m_bEnterAnimOn)),
|
||||
SendPropBool(SENDINFO(m_bExitAnimOn)),
|
||||
SendPropVector(SENDINFO(m_vecEyeExitEndpoint), -1, SPROP_COORD),
|
||||
END_SEND_TABLE();
|
||||
|
||||
|
||||
//------------------------------------------------
|
||||
// Precache
|
||||
//------------------------------------------------
|
||||
void CPropVehiclePrisonerPod::Precache( void )
|
||||
{
|
||||
BaseClass::Precache();
|
||||
|
||||
PrecacheScriptSound( "d3_citadel.pod_open" );
|
||||
PrecacheScriptSound( "d3_citadel.pod_close" );
|
||||
|
||||
m_ServerVehicle.Initialize( STRING(m_vehicleScript) );
|
||||
}
|
||||
|
||||
|
||||
//------------------------------------------------
|
||||
// Spawn
|
||||
//------------------------------------------------
|
||||
void CPropVehiclePrisonerPod::Spawn( void )
|
||||
{
|
||||
Precache();
|
||||
SetModel( STRING( GetModelName() ) );
|
||||
SetCollisionGroup( COLLISION_GROUP_VEHICLE );
|
||||
|
||||
BaseClass::Spawn();
|
||||
|
||||
m_takedamage = DAMAGE_EVENTS_ONLY;
|
||||
|
||||
SetNextThink( gpGlobals->curtime );
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void CPropVehiclePrisonerPod::TraceAttack( const CTakeDamageInfo &info, const Vector &vecDir, trace_t *ptr, CDmgAccumulator *pAccumulator )
|
||||
{
|
||||
if ( ptr->hitbox == VEHICLE_HITBOX_DRIVER )
|
||||
{
|
||||
if ( m_hPlayer != NULL )
|
||||
{
|
||||
m_hPlayer->TakeDamage( info );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
int CPropVehiclePrisonerPod::OnTakeDamage( const CTakeDamageInfo &inputInfo )
|
||||
{
|
||||
// Do scaled up physics damage to the pod
|
||||
CTakeDamageInfo info = inputInfo;
|
||||
info.ScaleDamage( 25 );
|
||||
|
||||
// reset the damage
|
||||
info.SetDamage( inputInfo.GetDamage() );
|
||||
|
||||
// Check to do damage to prisoner
|
||||
if ( m_hPlayer != NULL )
|
||||
{
|
||||
// Take no damage from physics damages
|
||||
if ( info.GetDamageType() & DMG_CRUSH )
|
||||
return 0;
|
||||
|
||||
// Take the damage
|
||||
m_hPlayer->TakeDamage( info );
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
Vector CPropVehiclePrisonerPod::BodyTarget( const Vector &posSrc, bool bNoisy )
|
||||
{
|
||||
Vector shotPos;
|
||||
matrix3x4_t matrix;
|
||||
|
||||
int eyeAttachmentIndex = LookupAttachment("vehicle_driver_eyes");
|
||||
GetAttachment( eyeAttachmentIndex, matrix );
|
||||
MatrixGetColumn( matrix, 3, shotPos );
|
||||
|
||||
if ( bNoisy )
|
||||
{
|
||||
shotPos[0] += random->RandomFloat( -8.0f, 8.0f );
|
||||
shotPos[1] += random->RandomFloat( -8.0f, 8.0f );
|
||||
shotPos[2] += random->RandomFloat( -8.0f, 8.0f );
|
||||
}
|
||||
|
||||
return shotPos;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void CPropVehiclePrisonerPod::Think(void)
|
||||
{
|
||||
SetNextThink( gpGlobals->curtime + 0.1 );
|
||||
|
||||
if ( GetDriver() )
|
||||
{
|
||||
BaseClass::Think();
|
||||
|
||||
// If the enter or exit animation has finished, tell the server vehicle
|
||||
if ( IsSequenceFinished() && (m_bExitAnimOn || m_bEnterAnimOn) )
|
||||
{
|
||||
GetServerVehicle()->HandleEntryExitFinish( m_bExitAnimOn, true );
|
||||
}
|
||||
}
|
||||
|
||||
StudioFrameAdvance();
|
||||
DispatchAnimEvents( this );
|
||||
}
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//------------------------------------------------------------------------------
|
||||
void CPropVehiclePrisonerPod::InputOpen( inputdata_t &inputdata )
|
||||
{
|
||||
int nSequence = LookupSequence( "open" );
|
||||
|
||||
// Set to the desired anim, or default anim if the desired is not present
|
||||
if ( nSequence > ACTIVITY_NOT_AVAILABLE )
|
||||
{
|
||||
SetCycle( 0 );
|
||||
m_flAnimTime = gpGlobals->curtime;
|
||||
ResetSequence( nSequence );
|
||||
ResetClientsideFrame();
|
||||
EmitSound( "d3_citadel.pod_open" );
|
||||
}
|
||||
else
|
||||
{
|
||||
// Not available try to get default anim
|
||||
Msg( "Prisoner pod %s: missing open sequence\n", GetDebugName() );
|
||||
SetSequence( 0 );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//------------------------------------------------------------------------------
|
||||
void CPropVehiclePrisonerPod::InputClose( inputdata_t &inputdata )
|
||||
{
|
||||
// The enter anim closes the pod, so don't do this redundantly!
|
||||
if ( m_bLocked || m_bEnterAnimOn )
|
||||
return;
|
||||
|
||||
int nSequence = LookupSequence( "close" );
|
||||
|
||||
// Set to the desired anim, or default anim if the desired is not present
|
||||
if ( nSequence > ACTIVITY_NOT_AVAILABLE )
|
||||
{
|
||||
SetCycle( 0 );
|
||||
m_flAnimTime = gpGlobals->curtime;
|
||||
ResetSequence( nSequence );
|
||||
ResetClientsideFrame();
|
||||
EmitSound( "d3_citadel.pod_close" );
|
||||
}
|
||||
else
|
||||
{
|
||||
// Not available try to get default anim
|
||||
Msg( "Prisoner pod %s: missing close sequence\n", GetDebugName() );
|
||||
SetSequence( 0 );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void CPropVehiclePrisonerPod::HandleAnimEvent( animevent_t *pEvent )
|
||||
{
|
||||
if ( pEvent->event == AE_POD_OPEN )
|
||||
{
|
||||
m_OnOpen.FireOutput( this, this );
|
||||
m_bLocked = false;
|
||||
}
|
||||
else if ( pEvent->event == AE_POD_CLOSE )
|
||||
{
|
||||
m_OnClose.FireOutput( this, this );
|
||||
m_bLocked = true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void CPropVehiclePrisonerPod::Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value )
|
||||
{
|
||||
CBasePlayer *pPlayer = ToBasePlayer( pActivator );
|
||||
if ( !pPlayer )
|
||||
return;
|
||||
|
||||
ResetUseKey( pPlayer );
|
||||
|
||||
GetServerVehicle()->HandlePassengerEntry( pPlayer, (value > 0) );
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Return true of the player's allowed to enter / exit the vehicle
|
||||
//-----------------------------------------------------------------------------
|
||||
bool CPropVehiclePrisonerPod::CanEnterVehicle( CBaseEntity *pEntity )
|
||||
{
|
||||
// Prevent entering if the vehicle's being driven by an NPC
|
||||
if ( GetDriver() && GetDriver() != pEntity )
|
||||
return false;
|
||||
|
||||
// Prevent entering if the vehicle's locked
|
||||
return !m_bLocked;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Return true of the player is allowed to exit the vehicle.
|
||||
//-----------------------------------------------------------------------------
|
||||
bool CPropVehiclePrisonerPod::CanExitVehicle( CBaseEntity *pEntity )
|
||||
{
|
||||
// Prevent exiting if the vehicle's locked, rotating, or playing an entry/exit anim.
|
||||
return ( !m_bLocked && (GetLocalAngularVelocity() == vec3_angle) && !m_bEnterAnimOn && !m_bExitAnimOn );
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Override base class to add display
|
||||
//-----------------------------------------------------------------------------
|
||||
void CPropVehiclePrisonerPod::DrawDebugGeometryOverlays(void)
|
||||
{
|
||||
// Draw if BBOX is on
|
||||
if ( m_debugOverlays & OVERLAY_BBOX_BIT )
|
||||
{
|
||||
}
|
||||
|
||||
BaseClass::DrawDebugGeometryOverlays();
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void CPropVehiclePrisonerPod::EnterVehicle( CBaseCombatCharacter *pPassenger )
|
||||
{
|
||||
if ( pPassenger == NULL )
|
||||
return;
|
||||
|
||||
CBasePlayer *pPlayer = ToBasePlayer( pPassenger );
|
||||
if ( pPlayer != NULL )
|
||||
{
|
||||
// Remove any player who may be in the vehicle at the moment
|
||||
if ( m_hPlayer )
|
||||
{
|
||||
ExitVehicle( VEHICLE_ROLE_DRIVER );
|
||||
}
|
||||
|
||||
m_hPlayer = pPlayer;
|
||||
m_playerOn.FireOutput( pPlayer, this, 0 );
|
||||
|
||||
m_ServerVehicle.SoundStart();
|
||||
}
|
||||
else
|
||||
{
|
||||
// NPCs are not supported yet - jdw
|
||||
Assert( 0 );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void CPropVehiclePrisonerPod::SetVehicleEntryAnim( bool bOn )
|
||||
{
|
||||
m_bEnterAnimOn = bOn;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void CPropVehiclePrisonerPod::ExitVehicle( int nRole )
|
||||
{
|
||||
CBasePlayer *pPlayer = m_hPlayer;
|
||||
if ( !pPlayer )
|
||||
return;
|
||||
|
||||
m_hPlayer = NULL;
|
||||
ResetUseKey( pPlayer );
|
||||
|
||||
m_playerOff.FireOutput( pPlayer, this, 0 );
|
||||
m_bEnterAnimOn = false;
|
||||
|
||||
m_ServerVehicle.SoundShutdown( 1.0 );
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void CPropVehiclePrisonerPod::ResetUseKey( CBasePlayer *pPlayer )
|
||||
{
|
||||
pPlayer->m_afButtonPressed &= ~IN_USE;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Vehicles are permanently oriented off angle for vphysics.
|
||||
//-----------------------------------------------------------------------------
|
||||
void CPropVehiclePrisonerPod::GetVectors(Vector* pForward, Vector* pRight, Vector* pUp) const
|
||||
{
|
||||
// This call is necessary to cause m_rgflCoordinateFrame to be recomputed
|
||||
const matrix3x4_t &entityToWorld = EntityToWorldTransform();
|
||||
|
||||
if (pForward != NULL)
|
||||
{
|
||||
MatrixGetColumn( entityToWorld, 1, *pForward );
|
||||
}
|
||||
|
||||
if (pRight != NULL)
|
||||
{
|
||||
MatrixGetColumn( entityToWorld, 0, *pRight );
|
||||
}
|
||||
|
||||
if (pUp != NULL)
|
||||
{
|
||||
MatrixGetColumn( entityToWorld, 2, *pUp );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
CBaseEntity *CPropVehiclePrisonerPod::GetDriver( void )
|
||||
{
|
||||
return m_hPlayer;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Prevent the player from entering / exiting the vehicle
|
||||
//-----------------------------------------------------------------------------
|
||||
void CPropVehiclePrisonerPod::InputLock( inputdata_t &inputdata )
|
||||
{
|
||||
m_bLocked = true;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Allow the player to enter / exit the vehicle
|
||||
//-----------------------------------------------------------------------------
|
||||
void CPropVehiclePrisonerPod::InputUnlock( inputdata_t &inputdata )
|
||||
{
|
||||
m_bLocked = false;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Force the player to enter the vehicle.
|
||||
//-----------------------------------------------------------------------------
|
||||
void CPropVehiclePrisonerPod::InputEnterVehicle( inputdata_t &inputdata )
|
||||
{
|
||||
if ( m_bEnterAnimOn )
|
||||
return;
|
||||
|
||||
// Try the activator first & use them if they are a player.
|
||||
CBaseCombatCharacter *pPassenger = ToBaseCombatCharacter( inputdata.pActivator );
|
||||
if ( pPassenger == NULL )
|
||||
{
|
||||
// Activator was not a player, just grab the singleplayer player.
|
||||
pPassenger = UTIL_PlayerByIndex( 1 );
|
||||
if ( pPassenger == NULL )
|
||||
return;
|
||||
}
|
||||
|
||||
// FIXME: I hate code like this. I should really add a parameter to HandlePassengerEntry
|
||||
// to allow entry into locked vehicles
|
||||
bool bWasLocked = m_bLocked;
|
||||
m_bLocked = false;
|
||||
GetServerVehicle()->HandlePassengerEntry( pPassenger, true );
|
||||
m_bLocked = bWasLocked;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
// Input : &inputdata -
|
||||
//-----------------------------------------------------------------------------
|
||||
void CPropVehiclePrisonerPod::InputEnterVehicleImmediate( inputdata_t &inputdata )
|
||||
{
|
||||
if ( m_bEnterAnimOn )
|
||||
return;
|
||||
|
||||
// Try the activator first & use them if they are a player.
|
||||
CBaseCombatCharacter *pPassenger = ToBaseCombatCharacter( inputdata.pActivator );
|
||||
if ( pPassenger == NULL )
|
||||
{
|
||||
// Activator was not a player, just grab the singleplayer player.
|
||||
pPassenger = UTIL_PlayerByIndex( 1 );
|
||||
if ( pPassenger == NULL )
|
||||
return;
|
||||
}
|
||||
|
||||
CBasePlayer *pPlayer = ToBasePlayer( pPassenger );
|
||||
if ( pPlayer != NULL )
|
||||
{
|
||||
if ( pPlayer->IsInAVehicle() )
|
||||
{
|
||||
// Force the player out of whatever vehicle they are in.
|
||||
pPlayer->LeaveVehicle();
|
||||
}
|
||||
|
||||
pPlayer->GetInVehicle( GetServerVehicle(), VEHICLE_ROLE_DRIVER );
|
||||
}
|
||||
else
|
||||
{
|
||||
// NPCs are not currently supported - jdw
|
||||
Assert( 0 );
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Force the player to exit the vehicle.
|
||||
//-----------------------------------------------------------------------------
|
||||
void CPropVehiclePrisonerPod::InputExitVehicle( inputdata_t &inputdata )
|
||||
{
|
||||
m_bForcedExit = true;
|
||||
}
|
||||
|
||||
|
||||
//========================================================================================================================================
|
||||
// CRANE VEHICLE SERVER VEHICLE
|
||||
//========================================================================================================================================
|
||||
CPropVehiclePrisonerPod *CPrisonerPodServerVehicle::GetPod( void )
|
||||
{
|
||||
return (CPropVehiclePrisonerPod *)GetDrivableVehicle();
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
// Input : pPlayer -
|
||||
//-----------------------------------------------------------------------------
|
||||
void CPrisonerPodServerVehicle::ItemPostFrame( CBasePlayer *player )
|
||||
{
|
||||
Assert( player == GetDriver() );
|
||||
|
||||
GetDrivableVehicle()->ItemPostFrame( player );
|
||||
|
||||
if (( player->m_afButtonPressed & IN_USE ) || GetPod()->ShouldForceExit() )
|
||||
{
|
||||
GetPod()->ClearForcedExit();
|
||||
if ( GetDrivableVehicle()->CanExitVehicle(player) )
|
||||
{
|
||||
// Let the vehicle try to play the exit animation
|
||||
if ( !HandlePassengerExit( player ) && ( player != NULL ) )
|
||||
{
|
||||
player->PlayUseDenySound();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void CPrisonerPodServerVehicle::GetVehicleViewPosition( int nRole, Vector *pAbsOrigin, QAngle *pAbsAngles, float *pFOV /*= NULL*/ )
|
||||
{
|
||||
// FIXME: This needs to be reconciled with the other versions of this function!
|
||||
Assert( nRole == VEHICLE_ROLE_DRIVER );
|
||||
CBasePlayer *pPlayer = ToBasePlayer( GetDrivableVehicle()->GetDriver() );
|
||||
Assert( pPlayer );
|
||||
|
||||
*pAbsAngles = pPlayer->EyeAngles(); // yuck. this is an in/out parameter.
|
||||
|
||||
float flPitchFactor = 1.0;
|
||||
matrix3x4_t vehicleEyePosToWorld;
|
||||
Vector vehicleEyeOrigin;
|
||||
QAngle vehicleEyeAngles;
|
||||
GetPod()->GetAttachment( "vehicle_driver_eyes", vehicleEyeOrigin, vehicleEyeAngles );
|
||||
AngleMatrix( vehicleEyeAngles, vehicleEyePosToWorld );
|
||||
|
||||
// Compute the relative rotation between the unperterbed eye attachment + the eye angles
|
||||
matrix3x4_t cameraToWorld;
|
||||
AngleMatrix( *pAbsAngles, cameraToWorld );
|
||||
|
||||
matrix3x4_t worldToEyePos;
|
||||
MatrixInvert( vehicleEyePosToWorld, worldToEyePos );
|
||||
|
||||
matrix3x4_t vehicleCameraToEyePos;
|
||||
ConcatTransforms( worldToEyePos, cameraToWorld, vehicleCameraToEyePos );
|
||||
|
||||
// Now perterb the attachment point
|
||||
vehicleEyeAngles.x = RemapAngleRange( PITCH_CURVE_ZERO * flPitchFactor, PITCH_CURVE_LINEAR, vehicleEyeAngles.x );
|
||||
vehicleEyeAngles.z = RemapAngleRange( ROLL_CURVE_ZERO * flPitchFactor, ROLL_CURVE_LINEAR, vehicleEyeAngles.z );
|
||||
AngleMatrix( vehicleEyeAngles, vehicleEyeOrigin, vehicleEyePosToWorld );
|
||||
|
||||
// Now treat the relative eye angles as being relative to this new, perterbed view position...
|
||||
matrix3x4_t newCameraToWorld;
|
||||
ConcatTransforms( vehicleEyePosToWorld, vehicleCameraToEyePos, newCameraToWorld );
|
||||
|
||||
// output new view abs angles
|
||||
MatrixAngles( newCameraToWorld, *pAbsAngles );
|
||||
|
||||
// UNDONE: *pOrigin would already be correct in single player if the HandleView() on the server ran after vphysics
|
||||
MatrixGetColumn( newCameraToWorld, 3, *pAbsOrigin );
|
||||
}
|
||||
Reference in New Issue
Block a user