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.

95 lines
2.5 KiB

  1. //========= Copyright Valve Corporation, All rights reserved. ============//
  2. //
  3. // Purpose:
  4. //
  5. //=============================================================================//
  6. #ifndef SHOT_MANIPULATOR_H
  7. #define SHOT_MANIPULATOR_H
  8. #ifdef _WIN32
  9. #pragma once
  10. #endif
  11. #include "mathlib/vector.h"
  12. extern ConVar ai_shot_bias_min;
  13. extern ConVar ai_shot_bias_max;
  14. //---------------------------------------------------------
  15. // Caches off a shot direction and allows you to perform
  16. // various operations on it without having to recalculate
  17. // vecRight and vecUp each time.
  18. //---------------------------------------------------------
  19. class CShotManipulator
  20. {
  21. public:
  22. CShotManipulator( const Vector &vecForward )
  23. {
  24. SetShootDir( vecForward );
  25. };
  26. void SetShootDir( const Vector &vecForward )
  27. {
  28. m_vecShotDirection = vecForward;
  29. VectorVectors( m_vecShotDirection, m_vecRight, m_vecUp );
  30. }
  31. const Vector &ApplySpread( const Vector &vecSpread, float bias = 1.0 );
  32. const Vector &GetShotDirection() { return m_vecShotDirection; }
  33. const Vector &GetResult() { return m_vecResult; }
  34. const Vector &GetRightVector() { return m_vecRight; }
  35. const Vector &GetUpVector() { return m_vecUp;}
  36. private:
  37. Vector m_vecShotDirection;
  38. Vector m_vecRight;
  39. Vector m_vecUp;
  40. Vector m_vecResult;
  41. };
  42. //---------------------------------------------------------
  43. // Take a vector (direction) and another vector (spread)
  44. // and modify the direction to point somewhere within the
  45. // spread. This used to live inside FireBullets.
  46. //---------------------------------------------------------
  47. inline const Vector &CShotManipulator::ApplySpread( const Vector &vecSpread, float bias )
  48. {
  49. // get circular gaussian spread
  50. float x, y, z;
  51. if ( bias > 1.0 )
  52. bias = 1.0;
  53. else if ( bias < 0.0 )
  54. bias = 0.0;
  55. float shotBiasMin = ai_shot_bias_min.GetFloat();
  56. float shotBiasMax = ai_shot_bias_max.GetFloat();
  57. // 1.0 gaussian, 0.0 is flat, -1.0 is inverse gaussian
  58. float shotBias = ( ( shotBiasMax - shotBiasMin ) * bias ) + shotBiasMin;
  59. float flatness = ( fabsf(shotBias) * 0.5 );
  60. do
  61. {
  62. x = random->RandomFloat(-1,1) * flatness + random->RandomFloat(-1,1) * (1 - flatness);
  63. y = random->RandomFloat(-1,1) * flatness + random->RandomFloat(-1,1) * (1 - flatness);
  64. if ( shotBias < 0 )
  65. {
  66. x = ( x >= 0 ) ? 1.0 - x : -1.0 - x;
  67. y = ( y >= 0 ) ? 1.0 - y : -1.0 - y;
  68. }
  69. z = x*x+y*y;
  70. } while (z > 1);
  71. m_vecResult = m_vecShotDirection + x * vecSpread.x * m_vecRight + y * vecSpread.y * m_vecUp;
  72. return m_vecResult;
  73. }
  74. #endif // SHOT_MANIPULATOR_H