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.

424 lines
13 KiB

  1. //========= Copyright � 1996-2005, Valve Corporation, All rights reserved. ============//
  2. //
  3. // Purpose:
  4. //
  5. // $NoKeywords: $
  6. //=============================================================================//
  7. // Author: Michael S. Booth ([email protected]), 2003
  8. #ifndef _BOT_PROFILE_H_
  9. #define _BOT_PROFILE_H_
  10. #pragma warning( disable : 4786 ) // long STL names get truncated in browse info.
  11. #include "bot_constants.h"
  12. #include "bot_util.h"
  13. #include "cs_weapon_parse.h"
  14. enum
  15. {
  16. FirstCustomSkin = 100,
  17. NumCustomSkins = 100,
  18. LastCustomSkin = FirstCustomSkin + NumCustomSkins - 1,
  19. };
  20. //--------------------------------------------------------------------------------------------------------------
  21. /**
  22. * A BotProfile describes the "personality" of a given bot
  23. */
  24. class BotProfile
  25. {
  26. public:
  27. BotProfile( void )
  28. {
  29. m_name = NULL;
  30. m_aggression = 0.0f;
  31. m_skill = 0.0f;
  32. m_teamwork = 0.0f;
  33. m_weaponPreferenceCount = 0;
  34. m_aimFocusInitial = 0.0f;
  35. m_aimFocusDecay = 1.0f;
  36. m_aimFocusOffsetScale = 0.0f;
  37. m_aimFocusInterval = .5f;
  38. m_cost = 0;
  39. m_skin = 0;
  40. m_difficultyFlags = 0;
  41. m_voicePitch = 100;
  42. m_reactionTime = 0.3f;
  43. m_attackDelay = 0.0f;
  44. m_lookAngleMaxAccelNormal = 0.0f;
  45. m_lookAngleStiffnessNormal = 0.0f;
  46. m_lookAngleDampingNormal = 0.0f;
  47. m_lookAngleMaxAccelAttacking = 0.0f;
  48. m_lookAngleStiffnessAttacking = 0.0f;
  49. m_lookAngleDampingAttacking = 0.0f;
  50. m_teams = TEAM_UNASSIGNED;
  51. m_voiceBank = 0;
  52. m_prefersSilencer = false;
  53. }
  54. ~BotProfile( void )
  55. {
  56. if ( m_name )
  57. delete [] m_name;
  58. }
  59. const char *GetName( void ) const { return m_name; } ///< return bot's name
  60. float GetAggression() const;
  61. float GetSkill() const;
  62. float GetTeamwork() const;
  63. float GetAimFocusInitial() const { return m_aimFocusInitial; }
  64. float GetAimFocusDecay() const { return m_aimFocusDecay; }
  65. float GetAimFocusOffsetScale() const { return m_aimFocusOffsetScale; }
  66. float GetAimFocusInterval() const { return m_aimFocusInterval; }
  67. CSWeaponID GetWeaponPreference(int i ) const;
  68. const char *GetWeaponPreferenceAsString( int i ) const;
  69. int GetWeaponPreferenceCount() const;
  70. bool HasPrimaryPreference() const; ///< return true if this profile has a primary weapon preference
  71. bool HasPistolPreference() const; ///< return true if this profile has a pistol weapon preference
  72. int GetCost() const;
  73. int GetSkin() const;
  74. int GetMaxDifficulty() const; ///< return maximum difficulty flag value
  75. bool IsDifficulty( BotDifficultyType diff ) const; ///< return true if this profile can be used for the given difficulty level
  76. bool IsMaxDifficulty( BotDifficultyType diff ) const; ///< return true if this profile's highest difficulty matches the incoming difficulty level
  77. int GetVoicePitch() const;
  78. float GetReactionTime() const;
  79. float GetAttackDelay() const;
  80. int GetVoiceBank() const { return m_voiceBank; }
  81. unsigned char GetDifficultyFlags() const;
  82. int GetTeams( void ) const { return m_teams; }
  83. float GetLookAngleMaxAccelerationNormal() const;
  84. float GetLookAngleStiffnessNormal() const;
  85. float GetLookAngleDampingNormal() const;
  86. float GetLookAngleMaxAccelerationAttacking() const;
  87. float GetLookAngleStiffnessAttacking() const;
  88. float GetLookAngleDampingAttacking() const;
  89. bool IsValidForTeam( int team ) const;
  90. bool PrefersSilencer() const { return m_prefersSilencer; }
  91. bool InheritsFrom( const char *name ) const;
  92. void Clone( const BotProfile* source_profile );
  93. void SetName( const char* name );
  94. void SetVoicePitch( int pitch );
  95. int GetTemplatesCount( void ) const { return m_templates.Count(); }
  96. const BotProfile* GetTemplate( int index ) const;
  97. private:
  98. friend class BotProfileManager; ///< for loading profiles
  99. void Inherit( const BotProfile *parent, const BotProfile *baseline ); ///< copy values from parent if they differ from baseline
  100. char *m_name; // the bot's name
  101. float m_aggression; // percentage: 0 = coward, 1 = berserker
  102. float m_skill; // percentage: 0 = terrible, 1 = expert
  103. float m_teamwork; // percentage: 0 = rogue, 1 = complete obeyance to team, lots of comm
  104. float m_aimFocusInitial; // initial minimum aim error on first attack
  105. float m_aimFocusDecay; // how quickly our focus error decays (scale/sec)
  106. float m_aimFocusOffsetScale; // how much aim focus error we get based on maximum angle distance from our view angle
  107. float m_aimFocusInterval; // how frequently we update our focus
  108. enum { MAX_WEAPON_PREFS = 16 };
  109. CSWeaponID m_weaponPreference[ MAX_WEAPON_PREFS ]; ///< which weapons this bot likes to use, in order of priority
  110. int m_weaponPreferenceCount;
  111. int m_cost; ///< reputation point cost for career mode
  112. int m_skin; ///< "skin" index
  113. unsigned char m_difficultyFlags; ///< bits set correspond to difficulty levels this is valid for
  114. int m_voicePitch; ///< the pitch shift for bot chatter (100 = normal)
  115. float m_reactionTime; ///< our reaction time in seconds
  116. float m_attackDelay; ///< time in seconds from when we notice an enemy to when we open fire
  117. int m_teams; ///< teams for which this profile is valid
  118. bool m_prefersSilencer; ///< does the bot prefer to use silencers?
  119. int m_voiceBank; ///< Index of the BotChatter.db voice bank this profile uses (0 is the default)
  120. float m_lookAngleMaxAccelNormal; // Acceleration of look angle spring under normal conditions
  121. float m_lookAngleStiffnessNormal; // Stiffness of look angle spring under normal conditions
  122. float m_lookAngleDampingNormal; // Damping of look angle spring under normal conditions
  123. float m_lookAngleMaxAccelAttacking; // Acceleration of look angle spring under attack conditions
  124. float m_lookAngleStiffnessAttacking; // Stiffness of look angle spring under attack conditions
  125. float m_lookAngleDampingAttacking; // Damping of look angle spring under attack conditions
  126. CUtlVector< const BotProfile * > m_templates; ///< List of templates we inherit from
  127. };
  128. typedef CUtlLinkedList<BotProfile *> BotProfileList;
  129. inline int BotProfile::GetMaxDifficulty() const
  130. {
  131. for ( int i = NUM_DIFFICULTY_LEVELS - 1; i >= BOT_EASY; --i )
  132. {
  133. if ( m_difficultyFlags & ( 1 << i ) )
  134. {
  135. return i;
  136. }
  137. }
  138. return BOT_EASY;
  139. }
  140. inline bool BotProfile::IsDifficulty( BotDifficultyType diff ) const
  141. {
  142. return (m_difficultyFlags & (1 << diff)) ? true : false;
  143. }
  144. inline bool BotProfile::IsMaxDifficulty( BotDifficultyType diff ) const
  145. {
  146. return ( ( m_difficultyFlags >> diff ) == 1 );
  147. }
  148. inline float BotProfile::GetAggression() const
  149. {
  150. return m_aggression;
  151. }
  152. inline float BotProfile::GetSkill() const
  153. {
  154. return m_skill;
  155. }
  156. inline float BotProfile::GetTeamwork() const
  157. {
  158. return m_teamwork;
  159. }
  160. inline CSWeaponID BotProfile::GetWeaponPreference( int i ) const
  161. {
  162. return m_weaponPreference[ i ];
  163. }
  164. inline int BotProfile::GetWeaponPreferenceCount() const
  165. {
  166. return m_weaponPreferenceCount;
  167. }
  168. inline int BotProfile::GetCost() const
  169. {
  170. return m_cost;
  171. }
  172. inline int BotProfile::GetSkin() const
  173. {
  174. return m_skin;
  175. }
  176. inline int BotProfile::GetVoicePitch() const
  177. {
  178. return m_voicePitch;
  179. }
  180. inline float BotProfile::GetReactionTime() const
  181. {
  182. return m_reactionTime;
  183. }
  184. inline float BotProfile::GetAttackDelay() const
  185. {
  186. return m_attackDelay;
  187. }
  188. inline unsigned char BotProfile::GetDifficultyFlags() const
  189. {
  190. return m_difficultyFlags;
  191. }
  192. inline float BotProfile::GetLookAngleMaxAccelerationNormal() const
  193. {
  194. return m_lookAngleMaxAccelNormal;
  195. }
  196. inline float BotProfile::GetLookAngleStiffnessNormal( ) const
  197. {
  198. return m_lookAngleStiffnessNormal;
  199. }
  200. inline float BotProfile::GetLookAngleDampingNormal() const
  201. {
  202. return m_lookAngleDampingNormal;
  203. }
  204. inline float BotProfile::GetLookAngleMaxAccelerationAttacking() const
  205. {
  206. return m_lookAngleMaxAccelAttacking;
  207. }
  208. inline float BotProfile::GetLookAngleStiffnessAttacking() const
  209. {
  210. return m_lookAngleStiffnessAttacking;
  211. }
  212. inline float BotProfile::GetLookAngleDampingAttacking() const
  213. {
  214. return m_lookAngleDampingAttacking;
  215. }
  216. inline void BotProfile::SetVoicePitch( int pitch )
  217. {
  218. m_voicePitch = pitch;
  219. }
  220. /**
  221. * Copy in data from parent if it differs from the baseline
  222. */
  223. inline void BotProfile::Inherit( const BotProfile *parent, const BotProfile *baseline )
  224. {
  225. if ( parent->m_aggression != baseline->m_aggression )
  226. m_aggression = parent->m_aggression;
  227. if ( parent->m_skill != baseline->m_skill )
  228. m_skill = parent->m_skill;
  229. if ( parent->m_teamwork != baseline->m_teamwork )
  230. m_teamwork = parent->m_teamwork;
  231. if ( parent->m_aimFocusInitial != baseline->m_aimFocusInitial )
  232. m_aimFocusInitial = parent->m_aimFocusInitial;
  233. if ( parent->m_aimFocusDecay != baseline->m_aimFocusDecay )
  234. m_aimFocusDecay = parent->m_aimFocusDecay;
  235. if ( parent->m_aimFocusOffsetScale != baseline->m_aimFocusOffsetScale )
  236. m_aimFocusOffsetScale = parent->m_aimFocusOffsetScale;
  237. if ( parent->m_aimFocusInterval != baseline->m_aimFocusInterval )
  238. m_aimFocusInterval = parent->m_aimFocusInterval;
  239. if (parent->m_weaponPreferenceCount != baseline->m_weaponPreferenceCount)
  240. {
  241. m_weaponPreferenceCount = parent->m_weaponPreferenceCount;
  242. for( int i=0; i<parent->m_weaponPreferenceCount; ++i )
  243. m_weaponPreference[i] = parent->m_weaponPreference[i];
  244. }
  245. if (parent->m_cost != baseline->m_cost)
  246. m_cost = parent->m_cost;
  247. if (parent->m_skin != baseline->m_skin)
  248. m_skin = parent->m_skin;
  249. if (parent->m_difficultyFlags != baseline->m_difficultyFlags)
  250. m_difficultyFlags = parent->m_difficultyFlags;
  251. if (parent->m_voicePitch != baseline->m_voicePitch)
  252. m_voicePitch = parent->m_voicePitch;
  253. if (parent->m_reactionTime != baseline->m_reactionTime)
  254. m_reactionTime = parent->m_reactionTime;
  255. if (parent->m_attackDelay != baseline->m_attackDelay)
  256. m_attackDelay = parent->m_attackDelay;
  257. if (parent->m_teams != baseline->m_teams)
  258. m_teams = parent->m_teams;
  259. if (parent->m_voiceBank != baseline->m_voiceBank)
  260. m_voiceBank = parent->m_voiceBank;
  261. m_templates.AddToTail( parent );
  262. }
  263. //--------------------------------------------------------------------------------------------------------------
  264. /**
  265. * The BotProfileManager defines the interface to accessing BotProfiles
  266. */
  267. class BotProfileManager
  268. {
  269. public:
  270. BotProfileManager( void );
  271. ~BotProfileManager( void );
  272. void Init( const char *filename, unsigned int *checksum = NULL );
  273. void Reset( void );
  274. /// given a name, return a profile
  275. const BotProfile *GetProfile( const char *name, int team ) const
  276. {
  277. FOR_EACH_LL( m_profileList, it )
  278. {
  279. BotProfile *profile = m_profileList[ it ];
  280. if ( !stricmp( name, profile->GetName() ) && profile->IsValidForTeam( team ) )
  281. return profile;
  282. }
  283. return NULL;
  284. }
  285. /// given a template name and difficulty, return a profile
  286. const BotProfile *GetProfileMatchingTemplate( const char *profileName, int team, BotDifficultyType difficulty, BotProfileDevice_t device, bool bAllowDupeNames = false ) const
  287. {
  288. FOR_EACH_LL( m_profileList, it )
  289. {
  290. BotProfile *profile = m_profileList[ it ];
  291. if ( !profile->InheritsFrom( profileName ) )
  292. continue;
  293. if ( !profile->IsValidForTeam( team ) )
  294. continue;
  295. if ( !profile->IsDifficulty( difficulty ) )
  296. continue;
  297. if ( bAllowDupeNames == false && UTIL_IsNameTaken( profile->GetName() ) )
  298. continue;
  299. return profile;
  300. }
  301. return NULL;
  302. }
  303. const BotProfileList *GetProfileList( void ) const { return &m_profileList; } ///< return list of all profiles
  304. const BotProfile *GetRandomProfile( BotDifficultyType difficulty, int team, CSWeaponType weaponType, bool forceMatchHighestDifficulty = false ) const; ///< return random unused profile that matches the given difficulty level
  305. const char * GetCustomSkin( int index ); ///< Returns custom skin name at a particular index
  306. const char * GetCustomSkinModelname( int index ); ///< Returns custom skin modelname at a particular index
  307. const char * GetCustomSkinFname( int index ); ///< Returns custom skin filename at a particular index
  308. int GetCustomSkinIndex( const char *name, const char *filename = NULL ); ///< Looks up a custom skin index by name
  309. typedef CUtlVector<char *> VoiceBankList;
  310. const VoiceBankList *GetVoiceBanks( void ) const { return &m_voiceBanks; }
  311. int FindVoiceBankIndex( const char *filename ); ///< return index of the (custom) bot phrase db, inserting it if needed
  312. protected:
  313. void ParseDifficultySetting( unsigned char &difficultyFlags, char* token);
  314. void ParseWeaponPreference( bool &isFirstWeaponPref, int &weaponPreferenceCount, CSWeaponID* weaponPreference, char* token );
  315. protected:
  316. BotProfileList m_profileList; ///< the list of all bot profiles
  317. BotProfileList m_templateList; ///< the list of all bot templates
  318. VoiceBankList m_voiceBanks;
  319. char *m_skins[ NumCustomSkins ]; ///< Custom skin names
  320. char *m_skinModelnames[ NumCustomSkins ]; ///< Custom skin modelnames
  321. char *m_skinFilenames[ NumCustomSkins ]; ///< Custom skin filenames
  322. int m_nextSkin; ///< Next custom skin to allocate
  323. };
  324. /// the global singleton for accessing BotProfiles
  325. extern BotProfileManager *TheBotProfiles;
  326. #endif // _BOT_PROFILE_H_