Team Fortress 2 Source Code as on 22/4/2020
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.

272 lines
6.5 KiB

  1. //========= Copyright Valve Corporation, All rights reserved. ============//
  2. // c_eyeball_boss.cpp
  3. #include "cbase.h"
  4. #include "NextBot/C_NextBot.h"
  5. #include "c_eyeball_boss.h"
  6. #include "tf_shareddefs.h"
  7. // memdbgon must be the last include file in a .cpp file!!!
  8. #include "tier0/memdbgon.h"
  9. #undef NextBot
  10. #ifdef STAGING_ONLY
  11. static ConVar cl_eyeball_boss_debug( "cl_eyeball_boss_debug", "0" );
  12. #endif
  13. //-----------------------------------------------------------------------------
  14. IMPLEMENT_CLIENTCLASS_DT( C_EyeballBoss, DT_EyeballBoss, CEyeballBoss )
  15. RecvPropVector( RECVINFO( m_lookAtSpot ) ),
  16. RecvPropInt( RECVINFO( m_attitude ) ),
  17. END_RECV_TABLE()
  18. //-----------------------------------------------------------------------------
  19. C_EyeballBoss::C_EyeballBoss()
  20. {
  21. m_ghostEffect = NULL;
  22. m_auraEffect = NULL;
  23. m_attitude = EYEBALL_CALM;
  24. m_priorAttitude = m_attitude;
  25. }
  26. //-----------------------------------------------------------------------------
  27. C_EyeballBoss::~C_EyeballBoss()
  28. {
  29. if ( m_ghostEffect )
  30. {
  31. ParticleProp()->StopEmission( m_ghostEffect );
  32. m_ghostEffect = NULL;
  33. }
  34. if ( m_auraEffect )
  35. {
  36. ParticleProp()->StopEmission( m_auraEffect );
  37. m_auraEffect = NULL;
  38. }
  39. }
  40. //-----------------------------------------------------------------------------
  41. void C_EyeballBoss::Spawn( void )
  42. {
  43. BaseClass::Spawn();
  44. m_leftRightPoseParameter = -1;
  45. m_upDownPoseParameter = -1;
  46. m_myAngles = vec3_angle;
  47. m_attitude = EYEBALL_CALM;
  48. m_priorAttitude = m_attitude;
  49. SetNextClientThink( CLIENT_THINK_ALWAYS );
  50. }
  51. //-----------------------------------------------------------------------------
  52. void C_EyeballBoss::OnPreDataChanged( DataUpdateType_t updateType )
  53. {
  54. BaseClass::OnPreDataChanged( updateType );
  55. m_priorAttitude = m_attitude;
  56. }
  57. //-----------------------------------------------------------------------------
  58. void C_EyeballBoss::OnDataChanged( DataUpdateType_t updateType )
  59. {
  60. BaseClass::OnDataChanged( updateType );
  61. if ( updateType == DATA_UPDATE_CREATED )
  62. {
  63. const char *pszMaterial = NULL;
  64. const char *pszAuraEffect = "eyeboss_aura_calm";
  65. switch ( GetTeamNumber() )
  66. {
  67. case TF_TEAM_RED:
  68. {
  69. pszAuraEffect = "eyeboss_team_red";
  70. //pszMaterial = "models/effects/invulnfx_red.vmt";
  71. }
  72. break;
  73. case TF_TEAM_BLUE:
  74. {
  75. pszAuraEffect = "eyeboss_team_blue";
  76. //pszMaterial = "models/effects/invulnfx_blue.vmt";
  77. }
  78. break;
  79. default:
  80. {
  81. if ( !m_ghostEffect )
  82. {
  83. m_ghostEffect = ParticleProp()->Create( "ghost_pumpkin", PATTACH_ABSORIGIN_FOLLOW );
  84. }
  85. }
  86. break;
  87. }
  88. if ( !m_auraEffect )
  89. {
  90. m_auraEffect = ParticleProp()->Create( pszAuraEffect, PATTACH_ABSORIGIN_FOLLOW );
  91. }
  92. if ( pszMaterial )
  93. {
  94. m_InvulnerableMaterial.Init( pszMaterial, TEXTURE_GROUP_CLIENT_EFFECTS );
  95. }
  96. else
  97. {
  98. m_InvulnerableMaterial.Shutdown();
  99. }
  100. }
  101. else if ( GetTeamNumber() == TF_TEAM_HALLOWEEN )
  102. {
  103. // update eyeball aura
  104. if ( m_attitude != m_priorAttitude )
  105. {
  106. // kill the old aura
  107. if ( m_auraEffect )
  108. {
  109. ParticleProp()->StopEmission( m_auraEffect );
  110. }
  111. switch( m_attitude )
  112. {
  113. case EYEBALL_CALM:
  114. m_auraEffect = ParticleProp()->Create( "eyeboss_aura_calm", PATTACH_ABSORIGIN_FOLLOW );
  115. break;
  116. case EYEBALL_GRUMPY:
  117. m_auraEffect = ParticleProp()->Create( "eyeboss_aura_grumpy", PATTACH_ABSORIGIN_FOLLOW );
  118. break;
  119. case EYEBALL_ANGRY:
  120. m_auraEffect = ParticleProp()->Create( "eyeboss_aura_angry", PATTACH_ABSORIGIN_FOLLOW );
  121. break;
  122. }
  123. m_priorAttitude = m_attitude;
  124. }
  125. }
  126. }
  127. //-----------------------------------------------------------------------------
  128. void C_EyeballBoss::ClientThink( void )
  129. {
  130. // update eyeball aim
  131. if ( m_leftRightPoseParameter < 0 )
  132. {
  133. m_leftRightPoseParameter = LookupPoseParameter( "left_right" );
  134. }
  135. if ( m_upDownPoseParameter < 0 )
  136. {
  137. m_upDownPoseParameter = LookupPoseParameter( "up_down" );
  138. }
  139. Vector myForward, myRight, myUp;
  140. AngleVectors( m_myAngles, &myForward, &myRight, &myUp );
  141. #ifdef STAGING_ONLY
  142. if ( cl_eyeball_boss_debug.GetBool() )
  143. {
  144. QAngle myAbsAngles = GetAbsAngles();
  145. DevMsg( "%3.2f: EYEBALL BEFORE AIM m_myAngles( %f, %f, %f ), myForward( %f, %f, %f ), GetAbsAngles( %f, %f, %f )\n",
  146. gpGlobals->curtime, m_myAngles.x, m_myAngles.y, m_myAngles.z, myForward.x, myForward.y, myForward.z,
  147. myAbsAngles.x, myAbsAngles.y, myAbsAngles.z );
  148. }
  149. #endif
  150. const float myApproachRate = 3.0f; // 1.0f;
  151. Vector toTarget = m_lookAtSpot - WorldSpaceCenter();
  152. toTarget.NormalizeInPlace();
  153. myForward += toTarget * myApproachRate * gpGlobals->frametime;
  154. myForward.NormalizeInPlace();
  155. QAngle myNewAngles;
  156. VectorAngles( myForward, myNewAngles );
  157. SetAbsAngles( myNewAngles );
  158. m_myAngles = myNewAngles;
  159. #ifdef STAGING_ONLY
  160. if ( cl_eyeball_boss_debug.GetBool() )
  161. {
  162. QAngle myAbsAngles = GetAbsAngles();
  163. DevMsg( "%3.2f: EYEBALL AFTER AIM m_myAngles( %f, %f, %f ), myForward( %f, %f, %f ), GetAbsAngles( %f, %f, %f )\n",
  164. gpGlobals->curtime, m_myAngles.x, m_myAngles.y, m_myAngles.z, myForward.x, myForward.y, myForward.z,
  165. myAbsAngles.x, myAbsAngles.y, myAbsAngles.z );
  166. }
  167. #endif
  168. // set pose parameters to aim pupil directly at target
  169. float toTargetRight = DotProduct( myRight, toTarget );
  170. float toTargetUp = DotProduct( myUp, toTarget );
  171. if ( m_leftRightPoseParameter >= 0 )
  172. {
  173. int angle = -50 * toTargetRight;
  174. SetPoseParameter( m_leftRightPoseParameter, angle );
  175. }
  176. if ( m_upDownPoseParameter >= 0 )
  177. {
  178. int angle = -50 * toTargetUp;
  179. SetPoseParameter( m_upDownPoseParameter, angle );
  180. }
  181. }
  182. //-----------------------------------------------------------------------------
  183. void C_EyeballBoss::SetDormant( bool bDormant )
  184. {
  185. BaseClass::SetDormant( bDormant );
  186. }
  187. //-----------------------------------------------------------------------------
  188. void C_EyeballBoss::FireEvent( const Vector& origin, const QAngle& angles, int event, const char *options )
  189. {
  190. }
  191. //-----------------------------------------------------------------------------
  192. QAngle const &C_EyeballBoss::GetRenderAngles( void )
  193. {
  194. return m_myAngles;
  195. }
  196. //-----------------------------------------------------------------------------
  197. // Purpose:
  198. //-----------------------------------------------------------------------------
  199. int C_EyeballBoss::InternalDrawModel( int flags )
  200. {
  201. bool bUseInvulnMaterial = ( GetTeamNumber() == TF_TEAM_RED ) || ( GetTeamNumber() == TF_TEAM_BLUE );
  202. if ( bUseInvulnMaterial )
  203. {
  204. modelrender->ForcedMaterialOverride( m_InvulnerableMaterial );
  205. }
  206. int ret = BaseClass::InternalDrawModel( flags );
  207. if ( bUseInvulnMaterial )
  208. {
  209. modelrender->ForcedMaterialOverride( NULL );
  210. }
  211. return ret;
  212. }