//========= Copyright © 1996-2005, Valve Corporation, All rights reserved. ============// // // Purpose: // //=============================================================================// #ifndef TRAINS_H #define TRAINS_H #ifdef _WIN32 #pragma once #endif #include "entityoutput.h" #include "pathtrack.h" // Spawnflags of CPathCorner #define SF_CORNER_WAITFORTRIG 0x001 #define SF_CORNER_TELEPORT 0x002 // Tracktrain spawn flags #define SF_TRACKTRAIN_NOPITCH 0x0001 #define SF_TRACKTRAIN_NOCONTROL 0x0002 #define SF_TRACKTRAIN_FORWARDONLY 0x0004 #define SF_TRACKTRAIN_PASSABLE 0x0008 #define SF_TRACKTRAIN_FIXED_ORIENTATION 0x0010 #define SF_TRACKTRAIN_HL1TRAIN 0x0080 #define SF_TRACKTRAIN_USE_MAXSPEED_FOR_PITCH 0x0100 #define SF_TRACKTRAIN_UNBLOCKABLE_BY_PLAYER 0x0200 #define TRAIN_ACTIVE 0x80 #define TRAIN_NEW 0xc0 #define TRAIN_OFF 0x00 #define TRAIN_NEUTRAL 0x01 #define TRAIN_SLOW 0x02 #define TRAIN_MEDIUM 0x03 #define TRAIN_FAST 0x04 #define TRAIN_BACK 0x05 enum TrainVelocityType_t { TrainVelocity_Instantaneous = 0, TrainVelocity_LinearBlend, TrainVelocity_EaseInEaseOut, }; enum TrainOrientationType_t { TrainOrientation_Fixed = 0, TrainOrientation_AtPathTracks, TrainOrientation_LinearBlend, TrainOrientation_EaseInEaseOut, }; class CFuncTrackTrain : public CBaseEntity { DECLARE_CLASS( CFuncTrackTrain, CBaseEntity ); DECLARE_SERVERCLASS(); public: CFuncTrackTrain(); void Spawn( void ); bool CreateVPhysics( void ); void Precache( void ); void UpdateOnRemove(); void MoveDone(); void Blocked( CBaseEntity *pOther ); bool KeyValue( const char *szKeyName, const char *szValue ); virtual int DrawDebugTextOverlays(); void DrawDebugGeometryOverlays(); void Next( void ); void Find( void ); void NearestPath( void ); void DeadEnd( void ); void SetTrack( CPathTrack *track ) { m_ppath = track->Nearest(GetLocalOrigin()); } void SetControls( CBaseEntity *pControls ); bool OnControls( CBaseEntity *pControls ); void SoundStop( void ); void SoundUpdate( void ); void Start( void ); void Stop( void ); bool IsDirForward(); void SetDirForward( bool bForward ); void SetSpeed( float flSpeed, bool bAccel = false ); void Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value ); // Input handlers void InputSetSpeed( inputdata_t &inputdata ); void InputSetSpeedDir( inputdata_t &inputdata ); void InputSetSpeedReal( inputdata_t &inputdata ); void InputStop( inputdata_t &inputdata ); void InputResume( inputdata_t &inputdata ); void InputReverse( inputdata_t &inputdata ); void InputStartForward( inputdata_t &inputdata ); void InputStartBackward( inputdata_t &inputdata ); void InputToggle( inputdata_t &inputdata ); void InputSetSpeedDirAccel( inputdata_t &inputdata ); static CFuncTrackTrain *Instance( edict_t *pent ); DECLARE_DATADESC(); virtual int ObjectCaps( void ) { return BaseClass::ObjectCaps() | FCAP_DIRECTIONAL_USE | FCAP_USE_ONGROUND; } virtual void OnRestore( void ); float GetMaxSpeed() const { return m_maxSpeed; } float GetCurrentSpeed() const { return m_flSpeed; } float GetDesiredSpeed() const { return m_flDesiredSpeed;} virtual bool IsBaseTrain( void ) const { return true; } private: void ArriveAtNode( CPathTrack *pNode ); void FirePassInputs( CPathTrack *pStart, CPathTrack *pEnd, bool forward ); public: // UNDONE: Add accessors? CPathTrack *m_ppath; float m_length; private: TrainVelocityType_t GetTrainVelocityType(); void UpdateTrainVelocity( CPathTrack *pnext, CPathTrack *pNextNext, const Vector &nextPos, float flInterval ); TrainOrientationType_t GetTrainOrientationType(); void UpdateTrainOrientation( CPathTrack *pnext, CPathTrack *pNextNext, const Vector &nextPos, float flInterval ); void UpdateOrientationAtPathTracks( CPathTrack *pnext, CPathTrack *pNextNext, const Vector &nextPos, float flInterval ); void UpdateOrientationBlend( TrainOrientationType_t eOrientationType, CPathTrack *pPrev, CPathTrack *pNext, const Vector &nextPos, float flInterval ); void DoUpdateOrientation( const QAngle &curAngles, const QAngle &angles, float flInterval ); void TeleportToPathTrack( CPathTrack *pTeleport ); Vector m_controlMins; Vector m_controlMaxs; Vector m_lastBlockPos; // These are used to build a heuristic decision about being temporarily blocked by physics objects int m_lastBlockTick; // ^^^^^^^ float m_flVolume; float m_flBank; float m_oldSpeed; float m_flBlockDamage; // Damage to inflict when blocked. float m_height; float m_maxSpeed; float m_dir; string_t m_iszSoundMove; // Looping sound to play while moving. Pitch shifted based on speed. string_t m_iszSoundMovePing; // Ping sound to play while moving. Interval decreased based on speed. string_t m_iszSoundStart; // Sound to play when starting to move. string_t m_iszSoundStop; // Sound to play when stopping. float m_flMoveSoundMinTime; // The most often to play the move 'ping' sound (used at max speed) float m_flMoveSoundMaxTime; // The least often to play the move 'ping' sound (used approaching zero speed) float m_flNextMoveSoundTime; int m_nMoveSoundMinPitch; // The sound pitch to approach as we come to a stop int m_nMoveSoundMaxPitch; // The sound pitch to approach as we approach our max speed (actually, it's hardcoded to 1000 in/sec) TrainOrientationType_t m_eOrientationType; TrainVelocityType_t m_eVelocityType; bool m_bSoundPlaying; COutputEvent m_OnStart,m_OnNext; bool m_bManualSpeedChanges; // set when we want to send entity IO to govern speed and obey our TrainVelocityType_t float m_flDesiredSpeed; // target speed, when m_bManualSpeedChanges is set float m_flSpeedChangeTime; float m_flAccelSpeed; float m_flDecelSpeed; bool m_bAccelToSpeed; float m_flNextMPSoundTime; }; #endif // TRAINS_H