diff options
| author | FluorescentCIAAfricanAmerican <[email protected]> | 2020-04-22 12:56:21 -0400 |
|---|---|---|
| committer | FluorescentCIAAfricanAmerican <[email protected]> | 2020-04-22 12:56:21 -0400 |
| commit | 3bf9df6b2785fa6d951086978a3e66f49427166a (patch) | |
| tree | 2c0f1f0c63c4832882bc93814ebd2c2b1c6224e5 /game/server/hl1/hl1_npc_gman.cpp | |
| download | archived-source-engine-2018-hl2-src-master.tar.xz archived-source-engine-2018-hl2-src-master.zip | |
Diffstat (limited to 'game/server/hl1/hl1_npc_gman.cpp')
| -rw-r--r-- | game/server/hl1/hl1_npc_gman.cpp | 232 |
1 files changed, 232 insertions, 0 deletions
diff --git a/game/server/hl1/hl1_npc_gman.cpp b/game/server/hl1/hl1_npc_gman.cpp new file mode 100644 index 0000000..5ea95cd --- /dev/null +++ b/game/server/hl1/hl1_npc_gman.cpp @@ -0,0 +1,232 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +// $NoKeywords: $ +// +//=============================================================================// +//========================================================= +// GMan - misunderstood servant of the people +//========================================================= + +#include "cbase.h" +#include "ai_default.h" +#include "ai_task.h" +#include "ai_schedule.h" +#include "ai_node.h" +#include "ai_hull.h" +#include "ai_hint.h" +#include "ai_memory.h" +#include "ai_route.h" +#include "ai_motor.h" +#include "soundent.h" +#include "game.h" +#include "npcevent.h" +#include "entitylist.h" +#include "activitylist.h" +#include "animation.h" +#include "IEffects.h" +#include "vstdlib/random.h" +#include "ai_baseactor.h" + +//========================================================= +// Monster's Anim Events Go Here +//========================================================= + +class CNPC_GMan : public CAI_BaseActor +{ + DECLARE_CLASS( CNPC_GMan, CAI_BaseActor ); +public: + + void Spawn( void ); + void Precache( void ); + float MaxYawSpeed( void ){ return 90.0f; } + Class_T Classify ( void ); + void HandleAnimEvent( animevent_t *pEvent ); + int GetSoundInterests ( void ); + + bool IsInC5A1(); + + void StartTask( const Task_t *pTask ); + void RunTask( const Task_t *pTask ); + int OnTakeDamage_Alive( const CTakeDamageInfo &inputInfo ); + void TraceAttack( CBaseEntity *pAttacker, float flDamage, const Vector &vecDir, trace_t *ptr, int bitsDamageType); + + virtual int PlayScriptedSentence( const char *pszSentence, float duration, float volume, soundlevel_t soundlevel, bool bConcurrent, CBaseEntity *pListener ); + + EHANDLE m_hPlayer; + EHANDLE m_hTalkTarget; + float m_flTalkTime; +}; + +LINK_ENTITY_TO_CLASS( monster_gman, CNPC_GMan ); + +//========================================================= +// Hack that tells us whether the GMan is in the final map +//========================================================= +bool CNPC_GMan::IsInC5A1() +{ + const char *pMapName = STRING(gpGlobals->mapname); + + if( pMapName ) + { + return !Q_strnicmp( pMapName, "c5a1", 4 ); + } + + return false; +} + +//========================================================= +// Classify - indicates this monster's place in the +// relationship table. +//========================================================= +Class_T CNPC_GMan::Classify ( void ) +{ + return CLASS_NONE; +} + + +//========================================================= +// HandleAnimEvent - catches the monster-specific messages +// that occur when tagged animation frames are played. +//========================================================= +void CNPC_GMan::HandleAnimEvent( animevent_t *pEvent ) +{ + switch( pEvent->event ) + { + case 1: + default: + BaseClass::HandleAnimEvent( pEvent ); + break; + } +} + +//========================================================= +// GetSoundInterests - generic monster can't hear. +//========================================================= +int CNPC_GMan::GetSoundInterests ( void ) +{ + return NULL; +} + +//========================================================= +// Spawn +//========================================================= +void CNPC_GMan::Spawn() +{ + Precache(); + + BaseClass::Spawn(); + + SetModel( "models/gman.mdl" ); + + SetHullType(HULL_HUMAN); + SetHullSizeNormal(); + + SetSolid( SOLID_BBOX ); + AddSolidFlags( FSOLID_NOT_STANDABLE ); + SetMoveType( MOVETYPE_STEP ); + SetBloodColor( BLOOD_COLOR_MECH ); + m_iHealth = 8; + m_flFieldOfView = 0.5;// indicates the width of this NPC's forward view cone ( as a dotproduct result ) + m_NPCState = NPC_STATE_NONE; + + CapabilitiesAdd( bits_CAP_MOVE_GROUND | bits_CAP_OPEN_DOORS | bits_CAP_USE_WEAPONS | bits_CAP_ANIMATEDFACE | bits_CAP_TURN_HEAD); + + NPCInit(); +} + +//========================================================= +// Precache - precaches all resources this monster needs +//========================================================= +void CNPC_GMan::Precache() +{ + PrecacheModel( "models/gman.mdl" ); +} + + +//========================================================= +// AI Schedules Specific to this monster +//========================================================= + + +void CNPC_GMan::StartTask( const Task_t *pTask ) +{ + switch( pTask->iTask ) + { + case TASK_WAIT: + if (m_hPlayer == NULL) + { + m_hPlayer = gEntList.FindEntityByClassname( NULL, "player" ); + } + break; + } + + BaseClass::StartTask( pTask ); +} + +void CNPC_GMan::RunTask( const Task_t *pTask ) +{ + switch( pTask->iTask ) + { + case TASK_WAIT: + // look at who I'm talking to + if (m_flTalkTime > gpGlobals->curtime && m_hTalkTarget != NULL) + { + AddLookTarget( m_hTalkTarget->GetAbsOrigin(), 1.0, 2.0 ); + } + // look at player, but only if playing a "safe" idle animation + else if (m_hPlayer != NULL && (GetSequence() == 0 || IsInC5A1()) ) + { + AddLookTarget( m_hPlayer->EyePosition(), 1.0, 3.0 ); + } + else + { + // Just center the head forward. + Vector forward; + GetVectors( &forward, NULL, NULL ); + + AddLookTarget( GetAbsOrigin() + forward * 12.0f, 1.0, 1.0 ); + SetBoneController( 0, 0 ); + } + BaseClass::RunTask( pTask ); + break; + } + + SetBoneController( 0, 0 ); + BaseClass::RunTask( pTask ); +} + + +//========================================================= +// Override all damage +//========================================================= +int CNPC_GMan::OnTakeDamage_Alive( const CTakeDamageInfo &inputInfo ) +{ + m_iHealth = m_iMaxHealth / 2; // always trigger the 50% damage aitrigger + + if ( inputInfo.GetDamage() > 0 ) + SetCondition( COND_LIGHT_DAMAGE ); + + if ( inputInfo.GetDamage() >= 20 ) + SetCondition( COND_HEAVY_DAMAGE ); + + return TRUE; +} + + +void CNPC_GMan::TraceAttack( CBaseEntity *pAttacker, float flDamage, const Vector &vecDir, trace_t *ptr, int bitsDamageType) +{ + g_pEffects->Ricochet( ptr->endpos, ptr->plane.normal ); +// AddMultiDamage( pevAttacker, this, flDamage, bitsDamageType ); +} + +int CNPC_GMan::PlayScriptedSentence( const char *pszSentence, float delay, float volume, soundlevel_t soundlevel, bool bConcurrent, CBaseEntity *pListener ) +{ + BaseClass::PlayScriptedSentence( pszSentence, delay, volume, soundlevel, bConcurrent, pListener ); + + m_flTalkTime = gpGlobals->curtime + delay; + m_hTalkTarget = pListener; + + return 1; +} |