home *** CD-ROM | disk | FTP | other *** search
/ Maximum CD 2007 September / maximum-cd-2007-09.iso / Assets / data / AssaultCube_v0.93.exe / source / src / bot / bot.h < prev    next >
Encoding:
C/C++ Source or Header  |  2007-04-11  |  14.5 KB  |  419 lines

  1. //
  2. // C++ Interface: bot
  3. //
  4. // Description: 
  5. //
  6. // Main bot header
  7. //
  8. //
  9. // Author:  Rick <rickhelmus@gmail.com>
  10. //
  11. //
  12. //
  13.  
  14.  
  15. /*
  16.  
  17.      TODO list
  18.      
  19.      -bots that "cover" each other in team matches ?
  20.      -If a bot gets ammo it should ignore that kind of ammo for the next 10 seconds. ?
  21.      -bots should ignore players that are too far away ?
  22.      -bots should dodge/jump when shot at
  23.      -If the bot's only weapon is the fist it should make looking for ammo its priority - Done ?
  24.      -bots should rocket jump to get quads and the 150 armor if normal jumping doesn't
  25.       work (only if health is x so they don't suicide).
  26.      -Make all the "UNDONE's" done :)
  27.      -Finish waypoint navigation
  28.      -Make bot personalities
  29.      -More advanced enemy scoring
  30.      -Bots should less bump into walls
  31.      -(Better) Coop support
  32.      -Check for reachable instead of visible in GetNearestWaypoint
  33.      -Waypoint experience file
  34.      -Bots should avoid team mates
  35.      -Handle failed goals better(ie remember them)
  36.      -Test multiplayer
  37.      -Fix bots getting stuck in each other
  38.      -Optimize hunting code
  39.      -Check/Fix msg code
  40. */
  41.  
  42. #ifndef BOT_H
  43. #define BOT_H
  44.  
  45. #include "../cube.h"
  46.  
  47. //#define RELEASE_BUILD // Set when you want to make a release build
  48.  
  49.  
  50. // Set for which mod the code is
  51.  
  52. //#define VANILLA_CUBE
  53. #define AC_CUBE
  54. //#define CUBE_X
  55.  
  56. #include "bot_util.h"
  57. #include "bot_waypoint.h"
  58.  
  59. extern bool dedserv;
  60. extern itemstat itemstats[];
  61.  
  62. #ifdef RELEASE_BUILD
  63. inline void condebug(const char *s, int a = 0, int b = 0, int c = 0) {};
  64. inline void debugnav(const char *s, int a = 0, int b = 0, int c = 0) {};
  65. inline void debugbeam(vec &s, vec &e) { };
  66. #else
  67. inline void condebug(const char *s, int a = 0, int b = 0, int c = 0) { /*conoutf(s, a, b, c);*/ };
  68. inline void debugnav(const char *s, int a = 0, int b = 0, int c = 0) { /*conoutf(s, a, b, c);*/ };
  69. inline void debugbeam(vec &s, vec &e) { /*if (!dedserv) particle_trail(1, 500, s, e);*/ };
  70. #endif
  71.  
  72. #define JUMP_HEIGHT      4.0f // NOT accurate
  73.  
  74. #define FORWARD       (1<<1)
  75. #define BACKWARD      (1<<2)
  76. #define LEFT          (1<<3)
  77. #define RIGHT         (1<<4)
  78. #define UP            (1<<5)
  79. #define DOWN          (1<<6)
  80. #define DIR_NONE      0
  81.  
  82. //fixmebot
  83. #define m_sp 1000
  84. #define m_classicsp 1000
  85.  
  86. enum EBotCommands // For voting of bot commands
  87. {
  88.      COMMAND_ADDBOT=0,
  89.      COMMAND_KICKBOT,
  90.      COMMAND_BOTSKILL
  91. };
  92.      
  93. struct bot_skill_s
  94. {
  95.      float flMinReactionDelay; // Minimal reaction time
  96.      float flMaxReactionDelay; // Maximal reaction time
  97.      float flMinAimXSpeed; // Minimal X aim speed in degrees(base value)
  98.      float flMaxAimXSpeed; // Maximal X aim speed in degrees(base value)
  99.      float flMinAimYSpeed; // Minimal Y aim speed in degrees(base value)
  100.      float flMaxAimYSpeed; // Maximal Y aim speed in degrees(base value)
  101.      float flMinAimXOffset; // Minimal X aim offset in degrees(base value)
  102.      float flMaxAimXOffset; // Maximal X aim offset in degrees(base value)
  103.      float flMinAimYOffset; // Minimal Y aim offset in degrees(base value)
  104.      float flMaxAimYOffset; // Maximal Y aim offset in degrees(base value)
  105.      float flMinAttackDelay; // Minimal delay for when a bot can attack again
  106.      float flMaxAttackDelay; // Maximal delay for when a bot can attack again
  107.      float flMinEnemySearchDelay; // Minimal delay for when a bot can search for an
  108.                                   // enemy again
  109.      float flMaxEnemySearchDelay; // Maximal delay for when a bot can search for an
  110.                                   // enemy again
  111.      short sShootAtFeetWithRLPercent; // Percent that a bot shoot with a rocket
  112.                                       // launcher at the enemy feet.
  113.      int iMaxHearVolume; // Max volume that bot can hear
  114.      bool bCanPredict; // Can this bot predict his enemy position?
  115.      bool bCircleStrafe; // Can this bot circle strafe?
  116.      bool bCanSearchItemsInCombat;
  117. };
  118.  
  119. enum EBotWeaponTypes
  120. {
  121.      TYPE_MELEE, // Fist, knife etc
  122.      TYPE_NORMAL, // Normal weapon, distance doesn't really matter(ie pistol)
  123.      TYPE_SHOTGUN,
  124.      TYPE_ROCKET,
  125.      TYPE_SNIPER, // Rifle, sniper etc
  126.      TYPE_GRENADE,
  127.      TYPE_AUTO // Chain gun, machine gun etc
  128. };
  129.  
  130. struct weaponinfo_s
  131. {
  132.      EBotWeaponTypes eWeaponType;
  133.      float flMinDesiredDistance;
  134.      float flMaxDesiredDistance;
  135.      float flMinFireDistance;
  136.      float flMaxFireDistance;
  137.      short sMinDesiredAmmo;
  138. };
  139.      
  140. enum ECurrentBotState
  141. {
  142.      STATE_ENEMY, // Bot has an enemy
  143.      STATE_HUNT, // Bot is hunting an enemy
  144.      STATE_ENT, // Bot is heading to an entity
  145.      STATE_SP, // Bot is doing sp specific stuff
  146.      STATE_NORMAL // Bot is doing normal navigation
  147. };
  148.  
  149. struct unreachable_ent_s
  150. {
  151.      entity *ent;
  152.      int time;
  153.      
  154.      unreachable_ent_s(entity *e, int t) : ent(e), time(t) { };
  155. };
  156.  
  157. class CBot
  158. {
  159. public:
  160.      botent *m_pMyEnt;
  161.      int m_iLastBotUpdate;
  162.         
  163.      // Combat variabels
  164.      playerent *m_pPrevEnemy;
  165.      int m_iShootDelay;
  166.      int m_iChangeWeaponDelay;
  167.      int m_iCombatNavTime;
  168.      int m_iEnemySearchDelay;
  169.      int m_iSawEnemyTime;
  170.      bool m_bCombatJump;
  171.      float m_iCombatJumpDelay;
  172.      bool m_bShootAtFeet;
  173.      
  174.      // Hunting variabeles
  175.      int m_iHuntDelay;
  176.      vec m_vHuntLocation, m_vPrevHuntLocation;
  177.      playerent *m_pHuntTarget;
  178.      float m_fPrevHuntDist;
  179.      int m_iHuntPauseTime, m_iHuntPlayerUpdateTime, m_iHuntLastTurnLessTime;
  180.      int m_iLookAroundDelay, m_iLookAroundTime, m_iLookAroundUpdateTime;
  181.      float m_fLookAroundYaw;
  182.      bool m_bLookLeft;
  183.      
  184.      // Navigation variabeles
  185.      int m_iCheckEnvDelay;
  186.      int m_iLastJumpPad;
  187.      vec m_vPrevOrigin;
  188.      float m_iStuckCheckDelay;
  189.      bool m_bStuck;
  190.      int m_iStuckTime;
  191.      int m_iStrafeTime;
  192.      int m_iStrafeCheckDelay;
  193.      int m_iMoveDir;
  194.      int m_iSPMoveTime;
  195.      bool m_bCalculatingAStarPath;
  196.      TLinkedList<waypoint_s *> m_AStarNodeList;
  197.      TPriorList<waypoint_s *, float> m_AStarOpenList[2];
  198.      TLinkedList<waypoint_s *> m_AStarClosedList[2];
  199.      vec m_vWaterGoal; // Place to go to when underwater
  200.         
  201.      // Waypoint variabeles
  202.      TLinkedList<waypoint_s *> m_WaypointList[MAX_MAP_GRIDS][MAX_MAP_GRIDS];
  203.      float m_iWaypointTime;
  204.      waypoint_s *m_pCurrentWaypoint;
  205.      waypoint_s *m_pCurrentGoalWaypoint;
  206.      vec m_vGoal;
  207.      waypoint_s *m_pPrevWaypoints[5];
  208.      int m_iRandomWaypointTime;
  209.      float m_fPrevWaypointDistance;
  210.      int m_iLookForWaypointTime;
  211.      int m_iWaypointHeadLastTurnLessTime; // Last time the didn't had to turn much wile
  212.                                           // heading to a WP
  213.      int m_iWaypointHeadPauseTime; // Pause time to give the bot time to aim.
  214.      bool m_bGoToDebugGoal;
  215.         
  216.      // Misc stuff
  217.      ECurrentBotState m_eCurrentBotState;
  218.      entity *m_pTargetEnt;
  219.      TLinkedList<unreachable_ent_s *> m_UnreachableEnts;
  220.      int m_iCheckTeleporterDelay;
  221.      int m_iCheckJumppadsDelay;
  222.      int m_iCheckEntsDelay;
  223.      int m_iCheckTriggersDelay;
  224.      int m_iAimDelay;
  225.      float m_fYawToTurn, m_fPitchToTurn;
  226.      bot_skill_s *m_pBotSkill; // Pointer to current bot skill
  227.      short m_sSkillNr; // Skill number, 0 == best 4 == worst
  228.         
  229.      void AimToVec(const vec &o);
  230.      void AimToIdeal(void);
  231.      float ChangeAngle(float speed, float ideal, float current);
  232.      bool SelectGun(int Gun);
  233.      virtual void CheckItemPickup(void) = 0;
  234.      void SendBotInfo(void);
  235.      float GetDistance(const vec &o);
  236.      float GetDistance(const vec &v1, const vec &v2);
  237.      float GetDistance(entity *e);
  238.      float Get2DDistance(const vec &v) { return ::Get2DDistance(m_pMyEnt->o, v); };
  239.      vec GetViewAngles(void) { return vec(m_pMyEnt->pitch, m_pMyEnt->yaw, m_pMyEnt->roll); };
  240.      void ResetMoveSpeed(void) { m_pMyEnt->move = m_pMyEnt->strafe = 0; };
  241.      void SetMoveDir(int iMoveDir, bool add);
  242.      void ResetCurrentTask();
  243.      
  244.      // AI Functions
  245.      bool FindEnemy(void);
  246.      void CheckReload(void);
  247.      void ShootEnemy(void);
  248.      bool CheckHunt(void);
  249.      bool HuntEnemy(void);
  250.      void DoCombatNav(void);
  251.      void MainAI(void);
  252.      bool CheckStuck(void);
  253.      bool CheckJump(void);
  254.      bool CheckStrafe(void);
  255.      void CheckFOV(void);
  256.      bool IsVisible(const vec &o, bool CheckPlayers = false) { return ::IsVisible(m_pMyEnt->o, o,
  257.                                                                       (CheckPlayers) ? m_pMyEnt :
  258.                                                                        NULL); };
  259.      bool IsVisible(playerent *d, bool CheckPlayers = false) { return ::IsVisible(m_pMyEnt->o, d->o,
  260.                                                                                (CheckPlayers) ?
  261.                                                                                 m_pMyEnt : NULL); };
  262.      bool IsVisible(entity *e, bool CheckPlayers = false);
  263.      bool IsVisible(vec o, int Dir, float flDist, bool CheckPlayers, float *pEndDist = NULL);
  264.      bool IsVisible(int Dir, float flDist, bool CheckPlayers)
  265.                           { return IsVisible(m_pMyEnt->o, Dir, flDist, CheckPlayers); };
  266.      bool IsInFOV(const vec &o);
  267.      bool IsInFOV(playerent *d) { return IsInFOV(d->o); };       
  268.      int GetShootDelay(void);
  269.      virtual bool ChoosePreferredWeapon(void);
  270.      virtual entity *SearchForEnts(bool bUseWPs, float flRange=9999.0f,
  271.                                    float flMaxHeight=JUMP_HEIGHT) = NULL;
  272.      virtual bool HeadToTargetEnt(void) = 0;
  273.      bool CheckItems(void);
  274.      bool InUnreachableList(entity *e);
  275.      virtual bool DoSPStuff(void) = 0;
  276.      vec GetEnemyPos(playerent *d);
  277.      bool AStar(void);
  278.      float AStarCost(waypoint_s *pWP1, waypoint_s *pWP2);
  279.      void CleanAStarLists(bool bPathFailed);
  280.      bool IsReachable(vec to, float flMaxHeight=JUMP_HEIGHT);
  281.      bool WaterNav(void);
  282.      void HearSound(int n, vec *o);
  283.         
  284.      // Waypoint functions
  285.      bool HeadToWaypoint(void);
  286.      bool FindWaypoint(void);
  287.      void ResetWaypointVars(void);
  288.      void SetCurrentWaypoint(node_s *pWP);
  289.      void SetCurrentWaypoint(waypoint_s *pWP);
  290.      void SetCurrentGoalWaypoint(node_s *pNode);
  291.      void SetCurrentGoalWaypoint(waypoint_s *pWP);
  292.      bool CurrentWPIsValid(void);
  293.      bool ReachedGoalWP(void);
  294.      bool HeadToGoal(void);
  295.      waypoint_s *GetWPFromNode(node_s *pNode);
  296.      waypoint_s *GetNearestWaypoint(vec v_src, float flRange);
  297.      waypoint_s *GetNearestWaypoint(float flRange) { return GetNearestWaypoint(m_pMyEnt->o, flRange); };
  298.      waypoint_s *GetNearestTriggerWaypoint(vec v_src, float flRange);
  299. #ifdef WP_FLOOD
  300.      waypoint_s *GetNearestFloodWP(vec v_origin, float flRange);
  301.      waypoint_s *GetNearestFloodWP(float flRange) { return GetNearestFloodWP(m_pMyEnt->o, flRange); };
  302.      waypoint_s *GetNearestTriggerFloodWP(vec v_origin, float flRange);
  303. #endif
  304.      void SyncWaypoints(void);
  305.         
  306.      friend class CBotManager;
  307.      friend class CWaypointClass;
  308.  
  309.      bool m_bSendC2SInit;
  310.      
  311.      virtual ~CBot(void);
  312.      
  313.      virtual void Spawn(void);
  314.      virtual void Think(void);
  315.      void GoToDebugGoal(vec o);        
  316. };
  317.  
  318. class CStoredBot // Used to store bots after mapchange, so that they can be readded
  319. {
  320. public:
  321.      char m_szName[32];
  322.      char m_szTeam[32];
  323.      short m_sSkillNr;
  324.  
  325.      CStoredBot(char *name, char *team, short skill) : m_sSkillNr(skill)
  326.           { strcpy(m_szName, name); strcpy(m_szTeam, team); };
  327. };
  328.  
  329. extern vector<botent *> bots;
  330.  
  331. class CBotManager
  332. {
  333.      char m_szBotNames[150][16]; // Max 150 bot names with a length of 16 characters
  334.      short m_sBotNameCount;
  335.      char m_szBotTeams[20][5]; // Max 100 bot teams co a length of 5 characters
  336.      short m_sBotTeamCount;        
  337.      bool m_bInit;
  338.      bool m_bBotsShoot;
  339.      bool m_bIdleBots;
  340.      bot_skill_s m_BotSkills[5]; // 5 different bot skills, 0 = best 4 = worst
  341.      int m_iFrameTime;
  342.      int m_iPrevTime;
  343.      short m_sBotSkill; // Bad - Worse - Medium - Good - Best
  344.      short m_sMaxAStarBots; // Max bots that can use a* at the same time
  345.      short m_sUsingAStarBotsCount; // Number of bots that are using a*
  346.      short m_sCurrentTriggerNr; // Current waypoint trigger bots should use
  347.      TLinkedList<CStoredBot *> m_StoredBots; // List of bots that should be re-added after map change
  348.      float m_fReAddBotDelay;
  349.      
  350.      void LoadBotNamesFile(void);
  351.      char *GetBotName(void);
  352.      void LoadBotTeamsFile(void);
  353.      char *GetBotTeam(void);
  354.      void CreateSkillData(void);
  355.      void InitSkillData(void);
  356.      void InitBotItems(void);
  357.                
  358.      friend class CBot;
  359.      friend class CCubeBot;
  360.      friend class CACBot;
  361.      friend class CWaypointClass;
  362.      
  363. public:
  364.      botent *m_pBotToView;
  365.  
  366.      // Construction
  367.      CBotManager(void) { m_bInit = true; m_fReAddBotDelay = -1.0f; };
  368.      
  369.      // Destruction
  370.      ~CBotManager(void);
  371.      
  372.      void Init(void);
  373.      void Think(void);
  374.      void RenderBots(void);
  375.      void RespawnBots(void) { loopv(bots) if (bots[i] && bots[i]->pBot) bots[i]->pBot->Spawn(); };
  376.      void ClearStoredBots(void) { while(!m_StoredBots.Empty()) delete m_StoredBots.Pop(); }
  377.      void ReAddBot(CStoredBot *bot) { CreateBot(bot->m_szTeam, SkillNrToSkillName(bot->m_sSkillNr), bot->m_szName); };
  378.      void EndMap(void);
  379.      void BeginMap(char *szMapName);
  380.      int GetBotIndex(botent *m);
  381.      void LetBotsUpdateStats(void);
  382.      void LetBotsHear(int n, vec *loc);
  383.      void AddWaypoint(node_s *pNode);
  384.      void DelWaypoint(node_s *pNode);
  385.      bool BotsShoot(void) { return m_bBotsShoot; };
  386.      bool IdleBots(void) { return m_bIdleBots; };
  387.      void SetBotsShoot(bool bShoot) { m_bBotsShoot = bShoot; };
  388.      void SetIdleBots(bool bIdle) { m_bIdleBots = bIdle; };
  389.      void EnableBotView(botent *bot) { m_pBotToView = bot; };
  390.      void DisableBotView(void);
  391.      void ChangeBotSkill(short Skill, botent *bot = NULL);
  392.      botent *CreateBot(const char *team, const char *skill, const char *name);
  393.      void ViewBot(void);
  394.      void CalculateMaxAStarCount(void);
  395.      void PickNextTrigger(void);
  396.      
  397.      void MakeBotFileName(const char *szFileName, const char *szDir1, const char *szDir2,
  398.                           char *szOutput);        
  399. };
  400.   
  401. #if defined VANILLA_CUBE
  402. #include "cube_bot.h"
  403. #elif defined AC_CUBE
  404. #include "ac_bot.h"
  405. #endif
  406.  
  407. extern CBotManager BotManager;
  408. extern const vec g_vecZero;
  409.  
  410. #if defined AC_CUBE
  411. extern CACWaypointClass WaypointClass;
  412. #elif defined VANILLA_CUBE
  413. extern CCubeWaypointClass WaypointClass;
  414. #endif
  415.  
  416. extern void kickallbots();
  417.  
  418. #endif
  419.