Counter Strike : Global Offensive Source Code
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

199 lines
5.4 KiB

  1. //========= Copyright � 1996-2005, Valve Corporation, All rights reserved. ============//
  2. //
  3. // Purpose:
  4. //
  5. // $NoKeywords: $
  6. //=============================================================================//
  7. #include "cbase.h"
  8. #include "c_ai_basenpc.h"
  9. #include "engine/ivdebugoverlay.h"
  10. #if defined( HL2_DLL ) || defined( HL2_EPISODIC )
  11. #include "c_basehlplayer.h"
  12. #endif
  13. #include "death_pose.h"
  14. // memdbgon must be the last include file in a .cpp file!!!
  15. #include "tier0/memdbgon.h"
  16. #define PING_MAX_TIME 2.0
  17. //
  18. // Global accessors for GLaDOS for lighted mouth proxy
  19. //
  20. CHandle<C_BaseAnimating> g_GLaDOSActor;
  21. void SetGLaDOSActor( C_BaseAnimating *pActor )
  22. {
  23. g_GLaDOSActor = pActor;
  24. }
  25. C_BaseAnimating *GetGLaDOSActor( void )
  26. {
  27. return g_GLaDOSActor;
  28. }
  29. IMPLEMENT_CLIENTCLASS_DT( C_AI_BaseNPC, DT_AI_BaseNPC, CAI_BaseNPC )
  30. RecvPropInt( RECVINFO( m_lifeState ) ),
  31. RecvPropBool( RECVINFO( m_bPerformAvoidance ) ),
  32. RecvPropBool( RECVINFO( m_bIsMoving ) ),
  33. RecvPropBool( RECVINFO( m_bFadeCorpse ) ),
  34. RecvPropInt( RECVINFO ( m_iDeathPose) ),
  35. RecvPropInt( RECVINFO( m_iDeathFrame) ),
  36. RecvPropInt( RECVINFO( m_iSpeedModRadius ) ),
  37. RecvPropInt( RECVINFO( m_iSpeedModSpeed ) ),
  38. RecvPropInt( RECVINFO( m_bSpeedModActive ) ),
  39. RecvPropBool( RECVINFO( m_bImportanRagdoll ) ),
  40. RecvPropFloat( RECVINFO( m_flTimePingEffect ) ),
  41. END_RECV_TABLE()
  42. extern ConVar cl_npc_speedmod_intime;
  43. bool NPC_IsImportantNPC( C_BaseAnimating *pAnimating )
  44. {
  45. C_AI_BaseNPC *pBaseNPC = pAnimating->MyNPCPointer();
  46. if ( pBaseNPC == NULL )
  47. return false;
  48. return pBaseNPC->ImportantRagdoll();
  49. }
  50. C_AI_BaseNPC::C_AI_BaseNPC()
  51. {
  52. }
  53. //-----------------------------------------------------------------------------
  54. // Makes ragdolls ignore npcclip brushes
  55. //-----------------------------------------------------------------------------
  56. unsigned int C_AI_BaseNPC::PhysicsSolidMaskForEntity( void ) const
  57. {
  58. // This allows ragdolls to move through npcclip brushes
  59. if ( !IsRagdoll() )
  60. {
  61. return MASK_NPCSOLID;
  62. }
  63. return MASK_SOLID;
  64. }
  65. void C_AI_BaseNPC::ClientThink( void )
  66. {
  67. BaseClass::ClientThink();
  68. #ifdef HL2_DLL
  69. C_BaseHLPlayer *pPlayer = dynamic_cast<C_BaseHLPlayer*>( C_BasePlayer::GetLocalPlayer() );
  70. if ( ShouldModifyPlayerSpeed() == true )
  71. {
  72. if ( pPlayer )
  73. {
  74. float flDist = (GetAbsOrigin() - pPlayer->GetAbsOrigin()).LengthSqr();
  75. if ( flDist <= GetSpeedModifyRadius() )
  76. {
  77. if ( pPlayer->m_hClosestNPC )
  78. {
  79. if ( pPlayer->m_hClosestNPC != this )
  80. {
  81. float flDistOther = (pPlayer->m_hClosestNPC->GetAbsOrigin() - pPlayer->GetAbsOrigin()).Length();
  82. //If I'm closer than the other NPC then replace it with myself.
  83. if ( flDist < flDistOther )
  84. {
  85. pPlayer->m_hClosestNPC = this;
  86. pPlayer->m_flSpeedModTime = gpGlobals->curtime + cl_npc_speedmod_intime.GetFloat();
  87. }
  88. }
  89. }
  90. else
  91. {
  92. pPlayer->m_hClosestNPC = this;
  93. pPlayer->m_flSpeedModTime = gpGlobals->curtime + cl_npc_speedmod_intime.GetFloat();
  94. }
  95. }
  96. }
  97. }
  98. #endif // HL2_DLL
  99. #ifdef HL2_EPISODIC
  100. C_BaseHLPlayer *pPlayer = dynamic_cast<C_BaseHLPlayer*>( C_BasePlayer::GetLocalPlayer() );
  101. if ( pPlayer && m_flTimePingEffect > gpGlobals->curtime )
  102. {
  103. float fPingEffectTime = m_flTimePingEffect - gpGlobals->curtime;
  104. if ( fPingEffectTime > 0.0f )
  105. {
  106. Vector vRight, vUp;
  107. Vector vMins, vMaxs;
  108. float fFade;
  109. if( fPingEffectTime <= 1.0f )
  110. {
  111. fFade = 1.0f - (1.0f - fPingEffectTime);
  112. }
  113. else
  114. {
  115. fFade = 1.0f;
  116. }
  117. GetRenderBounds( vMins, vMaxs );
  118. AngleVectors (pPlayer->GetAbsAngles(), NULL, &vRight, &vUp );
  119. Vector p1 = GetAbsOrigin() + vRight * vMins.x + vUp * vMins.z;
  120. Vector p2 = GetAbsOrigin() + vRight * vMaxs.x + vUp * vMins.z;
  121. Vector p3 = GetAbsOrigin() + vUp * vMaxs.z;
  122. int r = 0 * fFade;
  123. int g = 255 * fFade;
  124. int b = 0 * fFade;
  125. debugoverlay->AddLineOverlay( p1, p2, r, g, b, true, 0.05f );
  126. debugoverlay->AddLineOverlay( p2, p3, r, g, b, true, 0.05f );
  127. debugoverlay->AddLineOverlay( p3, p1, r, g, b, true, 0.05f );
  128. }
  129. }
  130. #endif
  131. }
  132. void C_AI_BaseNPC::OnDataChanged( DataUpdateType_t type )
  133. {
  134. BaseClass::OnDataChanged( type );
  135. // Make sure we're thinking
  136. if ( type == DATA_UPDATE_CREATED )
  137. {
  138. // If this is the GLaDOS actor, then setup a handle to it, globally
  139. if ( FStrEq( STRING( GetEntityName() ), "@glados" ) || FStrEq( STRING( GetEntityName() ), "@actor_potatos" ) )
  140. {
  141. SetGLaDOSActor( this );
  142. MouthInfo().ActivateEnvelope();
  143. }
  144. }
  145. if ( ( ShouldModifyPlayerSpeed() == true ) || ( m_flTimePingEffect > gpGlobals->curtime ) )
  146. {
  147. SetNextClientThink( CLIENT_THINK_ALWAYS );
  148. }
  149. }
  150. void C_AI_BaseNPC::GetRagdollInitBoneArrays( matrix3x4a_t *pDeltaBones0, matrix3x4a_t *pDeltaBones1, matrix3x4a_t *pCurrentBones, float boneDt )
  151. {
  152. ForceSetupBonesAtTime( pDeltaBones0, gpGlobals->curtime - boneDt );
  153. GetRagdollCurSequenceWithDeathPose( this, pDeltaBones1, gpGlobals->curtime, m_iDeathPose, m_iDeathFrame );
  154. float ragdollCreateTime = PhysGetSyncCreateTime();
  155. if ( ragdollCreateTime != gpGlobals->curtime )
  156. {
  157. // The next simulation frame begins before the end of this frame
  158. // so initialize the ragdoll at that time so that it will reach the current
  159. // position at curtime. Otherwise the ragdoll will simulate forward from curtime
  160. // and pop into the future a bit at this point of transition
  161. ForceSetupBonesAtTime( pCurrentBones, ragdollCreateTime );
  162. }
  163. else
  164. {
  165. SetupBones( pCurrentBones, MAXSTUDIOBONES, BONE_USED_BY_ANYTHING, gpGlobals->curtime );
  166. }
  167. }