// // Yet Another POD-Bot, based on PODBot by Markus Klinge ("CountFloyd"). // Copyright (c) YaPB Development Team. // // This software is licensed under the BSD-style license. // Additional exceptions apply. For full license details, see LICENSE.txt or visit: // https://yapb.jeefo.net/license // #pragma once #include #include #include #include using namespace Math; #include #include #include #include #include // defines bots tasks enum TaskID { TASK_NORMAL, TASK_PAUSE, TASK_MOVETOPOSITION, TASK_FOLLOWUSER, TASK_WAITFORGO, TASK_PICKUPITEM, TASK_CAMP, TASK_PLANTBOMB, TASK_DEFUSEBOMB, TASK_ATTACK, TASK_HUNTENEMY, TASK_SEEKCOVER, TASK_THROWHEGRENADE, TASK_THROWFLASHBANG, TASK_THROWSMOKE, TASK_DOUBLEJUMP, TASK_ESCAPEFROMBOMB, TASK_SHOOTBREAKABLE, TASK_HIDE, TASK_BLINDED, TASK_SPRAY, TASK_MAX }; // supported cs's enum GameFlags { GAME_CSTRIKE16 = (1 << 0), // Counter-Strike 1.6 and Above GAME_XASH_ENGINE = (1 << 1), // Counter-Strike 1.6 under the xash engine (additional flag) GAME_CZERO = (1 << 2), // Counter-Strike: Condition Zero GAME_LEGACY = (1 << 3), // Counter-Strike 1.3-1.5 with/without Steam GAME_MOBILITY = (1 << 4), // additional flag that bot is running on android (additional flag) GAME_OFFICIAL_CSBOT = (1 << 5), // additional flag that indicates official cs bots are in game GAME_METAMOD = (1 << 6), // game running under metamod GAME_SUPPORT_SVC_PINGS = (1 << 7), // on that game version we can fake bots pings GAME_SUPPORT_BOT_VOICE = (1 << 8) // on that game version we can use chatter }; // bot menu ids enum MenuId { BOT_MENU_INVALID = 0, BOT_MENU_MAIN, BOT_MENU_FEATURES, BOT_MENU_CONTROL, BOT_MENU_WEAPON_MODE, BOT_MENU_PERSONALITY, BOT_MENU_DIFFICULTY, BOT_MENU_TEAM_SELECT, BOT_MENU_TERRORIST_SELECT, BOT_MENU_CT_SELECT, BOT_MENU_COMMANDS, BOT_MENU_WAYPOINT_MAIN_PAGE1, BOT_MENU_WAYPOINT_MAIN_PAGE2, BOT_MENU_WAYPOINT_RADIUS, BOT_MENU_WAYPOINT_TYPE, BOT_MENU_WAYPOINT_FLAG, BOT_MENU_WAYPOINT_AUTOPATH, BOT_MENU_WAYPOINT_PATH, BOT_MENU_KICK_PAGE_1, BOT_MENU_KICK_PAGE_2, BOT_MENU_KICK_PAGE_3, BOT_MENU_KICK_PAGE_4, BOT_MENU_TOTAL_MENUS }; // log levels enum LogLevel { LL_DEFAULT = 1, // default log message LL_WARNING = 2, // warning log message LL_ERROR = 3, // error log message LL_IGNORE = 4, // additional flag LL_FATAL = 5 // fatal error log message (terminate the game!) }; // chat types id's enum ChatType { CHAT_KILLING = 0, // id to kill chat array CHAT_DEAD, // id to dead chat array CHAT_BOMBPLANT, // id to bomb chat array CHAT_TEAMATTACK, // id to team-attack chat array CHAT_TEAMKILL, // id to team-kill chat array CHAT_WELCOME, // id to welcome chat array CHAT_NOKW, // id to no keyword chat array CHAT_TOTAL // number for array }; // personalities defines enum Personality { PERSONALITY_NORMAL = 0, PERSONALITY_RUSHER, PERSONALITY_CAREFUL }; // collision states enum CollisionState { COLLISION_NOTDECICED, COLLISION_PROBING, COLLISION_NOMOVE, COLLISION_JUMP, COLLISION_DUCK, COLLISION_STRAFELEFT, COLLISION_STRAFERIGHT }; // counter-strike team id's enum Team { TERRORIST = 0, CT, SPECTATOR }; // client flags enum ClientFlags { CF_USED = (1 << 0), CF_ALIVE = (1 << 1), CF_ADMIN = (1 << 2), CF_ICON = (1 << 3) }; // bot create status enum BotCreationResult { BOT_RESULT_CREATED, BOT_RESULT_MAX_PLAYERS_REACHED, BOT_RESULT_NAV_ERROR, BOT_RESULT_TEAM_STACKED }; // radio messages enum RadioMessage_t { Radio_CoverMe = 1, Radio_YouTakePoint = 2, Radio_HoldPosition = 3, Radio_RegroupTeam = 4, Radio_FollowMe = 5, Radio_TakingFire = 6, Radio_GoGoGo = 11, Radio_Fallback = 12, Radio_StickTogether = 13, Radio_GetInPosition = 14, Radio_StormTheFront = 15, Radio_ReportTeam = 16, Radio_Affirmative = 21, Radio_EnemySpotted = 22, Radio_NeedBackup = 23, Radio_SectorClear = 24, Radio_InPosition = 25, Radio_ReportingIn = 26, Radio_ShesGonnaBlow = 27, Radio_Negative = 28, Radio_EnemyDown = 29 }; // voice system (extending enum above, messages 30-39 is reserved) enum ChatterMessage { Chatter_SpotTheBomber = 40, Chatter_FriendlyFire, Chatter_DiePain, Chatter_GotBlinded, Chatter_GoingToPlantBomb, Chatter_RescuingHostages, Chatter_GoingToCamp, Chatter_HearSomething, Chatter_TeamKill, Chatter_ReportingIn, Chatter_GuardDroppedC4, Chatter_Camp, Chatter_PlantingC4, Chatter_DefusingC4, Chatter_InCombat, Chatter_SeeksEnemy, Chatter_Nothing, Chatter_EnemyDown, Chatter_UseHostage, Chatter_FoundC4, Chatter_WonTheRound, Chatter_ScaredEmotion, Chatter_HeardEnemy, Chatter_SniperWarning, Chatter_SniperKilled, Chatter_VIPSpotted, Chatter_GuardingVipSafety, Chatter_GoingToGuardVIPSafety, Chatter_QuicklyWonTheRound, Chatter_OneEnemyLeft, Chatter_TwoEnemiesLeft, Chatter_ThreeEnemiesLeft, Chatter_NoEnemiesLeft, Chatter_FoundBombPlace, Chatter_WhereIsTheBomb, Chatter_DefendingBombSite, Chatter_BarelyDefused, Chatter_NiceshotCommander, Chatter_NiceshotPall, Chatter_GoingToGuardHostages, Chatter_GoingToGuardDoppedBomb, Chatter_OnMyWay, Chatter_LeadOnSir, Chatter_Pinned_Down, Chatter_GottaFindTheBomb, Chatter_You_Heard_The_Man, Chatter_Lost_The_Commander, Chatter_NewRound, Chatter_CoverMe, Chatter_BehindSmoke, Chatter_BombSiteSecured, Chatter_Total }; // counter-strike weapon id's enum Weapon { #ifndef XASH_CSDM WEAPON_P228 = 1, WEAPON_SHIELD = 2, WEAPON_SCOUT = 3, WEAPON_EXPLOSIVE = 4, WEAPON_XM1014 = 5, WEAPON_C4 = 6, WEAPON_MAC10 = 7, WEAPON_AUG = 8, WEAPON_SMOKE = 9, WEAPON_ELITE = 10, WEAPON_FIVESEVEN = 11, WEAPON_UMP45 = 12, WEAPON_SG550 = 13, WEAPON_GALIL = 14, WEAPON_FAMAS = 15, WEAPON_USP = 16, WEAPON_GLOCK = 17, WEAPON_AWP = 18, WEAPON_MP5 = 19, WEAPON_M249 = 20, WEAPON_M3 = 21, WEAPON_M4A1 = 22, WEAPON_TMP = 23, WEAPON_G3SG1 = 24, WEAPON_FLASHBANG = 25, WEAPON_DEAGLE = 26, WEAPON_SG552 = 27, WEAPON_AK47 = 28, WEAPON_KNIFE = 29, WEAPON_P90 = 30, WEAPON_ARMOR = 31, WEAPON_ARMORHELM = 32, WEAPON_DEFUSER = 33 #else WEAPON_KNIFE = 1, WEAPON_USP = 2, WEAPON_GLOCK = 3, WEAPON_EXPLOSIVE = 4, WEAPON_FLASHBANG = 5, WEAPON_SMOKE = 6, WEAPON_M4A1 = 7, WEAPON_AK47 = 8, WEAPON_AWP = 9, WEAPON_GALIL = 10, WEAPON_FAMAS = 11, WEAPON_DEAGLE = 12, WEAPON_AUG = 13, WEAPON_SG552 = 14, WEAPON_MP5 = 15, WEAPON_M3 = 16, WEAPON_C4 = 17, WEAPON_SCOUT = 18, WEAPON_MAC10 = 19, WEAPON_M249 = 20, WEAPON_FIVESEVEN = 21, WEAPON_UMP45 = 22, WEAPON_TMP = 23, WEAPON_G3SG1 = 24, WEAPON_SG550 = 25, WEAPON_ELITE = 26, WEAPON_P228 = 27, WEAPON_SHIELD = 28, WEAPON_XM1014 = 29, WEAPON_P90 = 30, WEAPON_ARMOR = 31, WEAPON_ARMORHELM = 32, WEAPON_DEFUSER = 33 #endif }; // buy counts enum BuyState { BUYSTATE_PRIMARY_WEAPON = 0, BUYSTATE_ARMOR_VESTHELM, BUYSTATE_SECONDARY_WEAPON, BUYSTATE_GRENADES, BUYSTATE_DEFUSER, BUYSTATE_AMMO, BUYSTATE_FINISHED }; // economics limits enum EconomyLimit { ECO_PRIMARY_GT = 0, ECO_SMG_GT_CT, ECO_SMG_GT_TE, ECO_SHOTGUN_GT, ECO_SHOTGUN_LT, ECO_HEAVY_GT, ECO_HEAVY_LT, ECO_PROSTOCK_NORMAL, ECO_PROSTOCK_RUSHER, ECO_PROSTOCK_CAREFUL, ECO_SHIELDGUN_GT }; // defines for pickup items enum PickupType { PICKUP_NONE, PICKUP_WEAPON, PICKUP_DROPPED_C4, PICKUP_PLANTED_C4, PICKUP_HOSTAGE, PICKUP_BUTTON, PICKUP_SHIELD, PICKUP_DEFUSEKIT }; // fight style type enum FightStyle { FIGHT_NONE, FIGHT_STRAFE, FIGHT_STAY }; // dodge type enum StrafeDir { STRAFE_DIR_NONE, STRAFE_DIR_LEFT, STRAFE_DIR_RIGHT }; // reload state enum ReloadState { RELOAD_NONE = 0, // no reload state currently RELOAD_PRIMARY = 1, // primary weapon reload state RELOAD_SECONDARY = 2 // secondary weapon reload state }; // collision probes enum CollisionProbe { PROBE_JUMP = (1 << 0), // probe jump when colliding PROBE_DUCK = (1 << 1), // probe duck when colliding PROBE_STRAFE = (1 << 2) // probe strafing when colliding }; // vgui menus (since latest steam updates is obsolete, but left for old cs) enum VGuiMenu { VMS_TEAM = 2, // menu select team VMS_TF = 26, // terrorist select menu VMS_CT = 27 // ct select menu }; // lift usage states enum LiftState { LIFT_NO_NEARBY = 0, LIFT_LOOKING_BUTTON_OUTSIDE, LIFT_WAITING_FOR, LIFT_ENTERING_IN, LIFT_WAIT_FOR_TEAMMATES, LIFT_LOOKING_BUTTON_INSIDE, LIFT_TRAVELING_BY, LIFT_LEAVING }; // wayponit auto-downloader enum WaypointDownloadError { WDE_SOCKET_ERROR, WDE_CONNECT_ERROR, WDE_NOTFOUND_ERROR, WDE_NOERROR }; // game start messages for counter-strike... enum GameStartMessage { GSM_IDLE = 1, GSM_TEAM_SELECT = 2, GSM_CLASS_SELECT = 3, GSM_BUY_STUFF = 100, GSM_RADIO = 200, GSM_SAY = 10000, GSM_SAY_TEAM = 10001 }; // sensing states enum SensingState { STATE_SEEING_ENEMY = (1 << 0), // seeing an enemy STATE_HEARING_ENEMY = (1 << 1), // hearing an enemy STATE_SUSPECT_ENEMY = (1 << 2), // suspect enemy behind obstacle STATE_PICKUP_ITEM = (1 << 3), // pickup item nearby STATE_THROW_HE = (1 << 4), // could throw he grenade STATE_THROW_FB = (1 << 5), // could throw flashbang STATE_THROW_SG = (1 << 6) // could throw smokegrenade }; // positions to aim at enum AimPosition { AIM_NAVPOINT = (1 << 0), // aim at nav point AIM_CAMP = (1 << 1), // aim at camp vector AIM_PREDICT_PATH = (1 << 2), // aim at predicted path AIM_LAST_ENEMY = (1 << 3), // aim at last enemy AIM_ENTITY = (1 << 4), // aim at entity like buttons, hostages AIM_ENEMY = (1 << 5), // aim at enemy AIM_GRENADE = (1 << 6), // aim for grenade throw AIM_OVERRIDE = (1 << 7) // overrides all others (blinded) }; // famas/glock burst mode status + m4a1/usp silencer enum BurstMode { BM_ON = 1, BM_OFF = 2 }; // visibility flags enum Visibility { VISIBLE_HEAD = (1 << 1), VISIBLE_BODY = (1 << 2), VISIBLE_OTHER = (1 << 3) }; // defines map type enum MapType { MAP_AS = (1 << 0), MAP_CS = (1 << 1), MAP_DE = (1 << 2), MAP_ES = (1 << 3), MAP_KA = (1 << 4), MAP_FY = (1 << 5) }; // defines for waypoint flags field (32 bits are available) enum WaypointFlag { FLAG_LIFT = (1 << 1), // wait for lift to be down before approaching this waypoint FLAG_CROUCH = (1 << 2), // must crouch to reach this waypoint FLAG_CROSSING = (1 << 3), // a target waypoint FLAG_GOAL = (1 << 4), // mission goal point (bomb, hostage etc.) FLAG_LADDER = (1 << 5), // waypoint is on ladder FLAG_RESCUE = (1 << 6), // waypoint is a hostage rescue point FLAG_CAMP = (1 << 7), // waypoint is a camping point FLAG_NOHOSTAGE = (1 << 8), // only use this waypoint if no hostage FLAG_DOUBLEJUMP = (1 << 9), // bot help's another bot (requster) to get somewhere (using djump) FLAG_SNIPER = (1 << 28), // it's a specific sniper point FLAG_TF_ONLY = (1 << 29), // it's a specific terrorist point FLAG_CF_ONLY = (1 << 30) // it's a specific ct point }; // defines for waypoint connection flags field (16 bits are available) enum PathFlag { PATHFLAG_JUMP = (1 << 0) // must jump for this connection }; // enum pathfind search type enum SearchPathType { SEARCH_PATH_FASTEST = 0, SEARCH_PATH_SAFEST_FASTER, SEARCH_PATH_SAFEST }; // defines waypoint connection types enum PathConnection { CONNECTION_OUTGOING = 0, CONNECTION_INCOMING, CONNECTION_BOTHWAYS }; // bot known file headers const char FH_WAYPOINT[] = "PODWAY!"; const char FH_EXPERIENCE[] = "PODEXP!"; const char FH_VISTABLE[] = "PODVIS!"; const int FV_WAYPOINT = 7; const int FV_EXPERIENCE = 3; const int FV_VISTABLE = 1; // some hardcoded desire defines used to override calculated ones const float TASKPRI_NORMAL = 35.0f; const float TASKPRI_PAUSE = 36.0f; const float TASKPRI_CAMP = 37.0f; const float TASKPRI_SPRAYLOGO = 38.0f; const float TASKPRI_FOLLOWUSER = 39.0f; const float TASKPRI_MOVETOPOSITION = 50.0f; const float TASKPRI_DEFUSEBOMB = 89.0f; const float TASKPRI_PLANTBOMB = 89.0f; const float TASKPRI_ATTACK = 90.0f; const float TASKPRI_SEEKCOVER = 91.0f; const float TASKPRI_HIDE = 92.0f; const float TASKPRI_THROWGRENADE = 99.0f; const float TASKPRI_DOUBLEJUMP = 99.0f; const float TASKPRI_BLINDED = 100.0f; const float TASKPRI_SHOOTBREAKABLE = 100.0f; const float TASKPRI_ESCAPEFROMBOMB = 100.0f; const float MAX_GRENADE_TIMER = 2.34f; const int MAX_HOSTAGES = 8; const int MAX_PATH_INDEX = 8; const int MAX_DAMAGE_VALUE = 2040; const int MAX_GOAL_VALUE = 2040; const int MAX_KILL_HISTORY = 16; const int MAX_WAYPOINTS = 1024; const int MAX_WEAPONS = 32; const int NUM_WEAPONS = 26; const int MAX_COLLIDE_MOVES = 3; const int MAX_ENGINE_PLAYERS = 32; // we can have 64 players with xash const int MAX_PRINT_BUFFER = 1024; // weapon masks const int WEAPON_PRIMARY = ((1 << WEAPON_XM1014) | (1 < keywords; Array replies; Array usedReplies; }; // tasks definition struct TaskItem { TaskID id; // major task/action carried out float desire; // desire (filled in) for this task int data; // additional data (waypoint index) float time; // time task expires bool resume; // if task can be continued if interrupted }; // botname structure definition struct BotName { String steamId; String name; int usedBy; }; // voice config structure definition struct ChatterItem { String name; float repeat; float duration; }; struct WeaponSelect { int id; // the weapon id value const char *weaponName; // name of the weapon when selecting it const char *modelName; // model name to separate cs weapons int price; // price when buying int minPrimaryAmmo; // minimum primary ammo int teamStandard; // used by team (number) (standard map) int teamAS; // used by team (as map) int buyGroup; // group in buy menu (standard map) int buySelect; // select item in buy menu (standard map) int newBuySelectT; // for counter-strike v1.6 int newBuySelectCT; // for counter-strike v1.6 int penetratePower; // penetrate power bool primaryFireHold; // hold down primary fire button to use? }; // struct for menus struct MenuText { MenuId id; // actual menu id int slots; // together bits for valid keys String text; // ptr to actual string }; // array of clients struct struct Client { MenuId menu; // id to opened bot menu edict_t *ent; // pointer to actual edict Vector origin; // position in the world Vector soundPos; // position sound was played int team; // bot team int team2; // real bot team in free for all mode (csdm) int flags; // client flags float hearingDistance; // distance this sound is heared float timeSoundLasting; // time sound is played/heared int iconFlags[MAX_ENGINE_PLAYERS]; // flag holding chatter icons float iconTimestamp[MAX_ENGINE_PLAYERS]; // timers for chatter icons }; // experience data hold in memory while playing struct Experience { uint16 team0Damage; uint16 team1Damage; int16 team0DangerIndex; int16 team1DangerIndex; int16 team0Value; int16 team1Value; }; // experience data when saving/loading struct ExperienceSave { uint8 team0Damage; uint8 team1Damage; int8 team0Value; int8 team1Value; }; // bot creation tab struct CreateQueue { bool console; int difficulty; int team; int member; int personality; String name; }; // weapon properties structure struct WeaponProperty { char className[64]; int ammo1; // ammo index for primary ammo int ammo1Max; // max primary ammo int slotID; // HUD slot (0 based) int position; // slot position int id; // weapon ID int flags; // flags??? }; // define chatting collection structure struct ChatCollection { int chatProbability; float chatDelay; float timeNextChat; int entityIndex; char sayText[512]; Array lastUsedSentences; }; // general waypoint header information structure struct WaypointHeader { char header[8]; int32 fileVersion; int32 pointNumber; char mapName[32]; char author[32]; }; // general experience & vistable header information structure struct ExtensionHeader { char header[8]; int32 fileVersion; int32 pointNumber; }; // define general waypoint structure struct Path { int32 pathNumber; int32 flags; Vector origin; float radius; float campStartX; float campStartY; float campEndX; float campEndY; int16 index[MAX_PATH_INDEX]; uint16 connectionFlags[MAX_PATH_INDEX]; Vector connectionVelocity[MAX_PATH_INDEX]; int32 distances[MAX_PATH_INDEX]; struct Vis { uint16 stand, crouch; } vis; }; // main bot class class Bot { friend class BotManager; private: unsigned int m_states; // sensing bitstates float m_moveSpeed; // current speed forward/backward float m_strafeSpeed; // current speed sideways float m_minSpeed; // minimum speed in normal mode float m_oldCombatDesire; // holds old desire for filtering bool m_isLeader; // bot is leader of his team bool m_checkTerrain; // check for terrain bool m_moveToC4; // ct is moving to bomb float m_prevTime; // time previously checked movement speed float m_prevSpeed; // speed some frames before Vector m_prevOrigin; // origin some frames before int m_messageQueue[32]; // stack for messages char m_tempStrings[160]; // space for strings (say text...) int m_radioSelect; // radio entry float m_headedTime; float m_blindRecognizeTime; // time to recognize enemy float m_itemCheckTime; // time next search for items needs to be done PickupType m_pickupType; // type of entity which needs to be used/picked up Vector m_breakableOrigin; // origin of breakable edict_t *m_pickupItem; // pointer to entity of item to use/pickup edict_t *m_itemIgnore; // pointer to entity to ignore for pickup edict_t *m_liftEntity; // pointer to lift entity edict_t *m_breakableEntity; // pointer to breakable entity float m_timeDoorOpen; // time to next door open check float m_lastChatTime; // time bot last chatted float m_timeLogoSpray; // time bot last spray logo float m_knifeAttackTime; // time to rush with knife (at the beginning of the round) bool m_defendedBomb; // defend action issued bool m_defendHostage; float m_askCheckTime; // time to ask team float m_collideTime; // time last collision float m_firstCollideTime; // time of first collision float m_probeTime; // time of probing different moves float m_lastCollTime; // time until next collision check float m_jumpStateTimer; // timer for jumping collision check unsigned int m_collisionProbeBits; // bits of possible collision moves unsigned int m_collideMoves[MAX_COLLIDE_MOVES]; // sorted array of movements unsigned int m_collStateIndex; // index into collide moves CollisionState m_collisionState; // collision State PathNode *m_navNode; // pointer to current node from path PathNode *m_navNodeStart; // pointer to start of path finding nodes Path *m_currentPath; // pointer to the current path waypoint SearchPathType m_pathType; // which pathfinder to use uint8 m_visibility; // visibility flags int m_currentWaypointIndex; // current waypoint index int m_travelStartIndex; // travel start index to double jump action int m_prevWptIndex[5]; // previous waypoint indices from waypoint find int m_waypointFlags; // current waypoint flags int m_loosedBombWptIndex; // nearest to loosed bomb waypoint int m_plantedBombWptIndex;// nearest to planted bomb waypoint uint16 m_currentTravelFlags; // connection flags like jumping bool m_jumpFinished; // has bot finished jumping Vector m_desiredVelocity; // desired velocity for jump waypoints float m_navTimeset; // time waypoint chosen by Bot unsigned int m_aimFlags; // aiming conditions Vector m_lookAt; // vector bot should look at Vector m_throw; // origin of waypoint to throw grenades Vector m_enemyOrigin; // target origin chosen for shooting Vector m_grenade; // calculated vector for grenades Vector m_entity; // origin of entities like buttons etc. Vector m_camp; // aiming vector when camping. float m_timeWaypointMove; // last time bot followed waypoints bool m_wantsToFire; // bot needs consider firing float m_shootAtDeadTime; // time to shoot at dying players edict_t *m_avoidGrenade; // pointer to grenade entity to avoid int m_needAvoidGrenade; // which direction to strafe away float m_followWaitTime; // wait to follow time edict_t *m_targetEntity; // the entity that the bot is trying to reach edict_t *m_hostages[MAX_HOSTAGES]; // pointer to used hostage entities bool m_moveToGoal; // bot currently moving to goal?? bool m_isStuck; // bot is stuck bool m_isReloading; // bot is reloading a gun bool m_forceRadio; // should bot use radio anyway? int m_reloadState; // current reload state int m_voicePitch; // bot voice pitch bool m_duckDefuse; // should or not bot duck to defuse bomb float m_duckDefuseCheckTime; // time to check for ducking for defuse float m_frameInterval; // bot's frame interval float m_lastCommandTime; // time bot last thinked float m_reloadCheckTime; // time to check reloading float m_zoomCheckTime; // time to check zoom again float m_shieldCheckTime; // time to check shiled drawing again float m_grenadeCheckTime; // time to check grenade usage float m_lastEquipTime; // last time we equipped in buyzone bool m_checkKnifeSwitch; // is time to check switch to knife action bool m_checkWeaponSwitch; // is time to check weapon switch bool m_isUsingGrenade; // bot currently using grenade?? StrafeDir m_combatStrafeDir; // direction to strafe FightStyle m_fightStyle; // combat style to use float m_lastFightStyleCheck; // time checked style float m_strafeSetTime; // time strafe direction was set float m_maxThrowTimer; // time that completes the throw task float m_timeCamping; // time to camp int m_campDirection; // camp Facing direction float m_nextCampDirTime; // time next camp direction change int m_campButtons; // buttons to press while camping int m_doorOpenAttempt; // attempt's to open the door int m_liftState; // state of lift handling float m_duckTime; // time to duck float m_jumpTime; // time last jump happened float m_chatterTimes[Chatter_Total]; // voice command timers float m_soundUpdateTime; // time to update the sound float m_heardSoundTime; // last time noise is heard float m_buttonPushTime; // time to push the button float m_liftUsageTime; // time to use lift int m_pingOffset[2]; int m_ping[3]; // bots pings in scoreboard Vector m_liftTravelPos; // lift travel position Vector m_moveAngles; // bot move angles Vector m_idealAngles; // angle wanted float m_lookYawVel; // look yaw velocity float m_lookPitchVel; // look pitch velocity float m_lookUpdateTime; // lookangles update time Vector m_randomizedIdealAngles; // angle wanted with noise Vector m_angularDeviation; // angular deviation from current to ideal angles Vector m_aimSpeed; // aim speed calculated float m_randomizeAnglesTime; // time last randomized location float m_playerTargetTime; // time last targeting void InstantChatterMessage (int type); void BotAI (void); void CheckSpawnTimeConditions (void); void PurchaseWeapons (void); bool IsMorePowerfulWeaponCanBeBought (void); int PickBestFromRandom (int *random, int count, int moneySave); bool CanDuckUnder (const Vector &normal); bool CanJumpUp (const Vector &normal); bool FinishCanJumpUp (const Vector &normal); bool CantMoveForward (const Vector &normal, TraceResult *tr); // split RunTask into RunTask_* functions void RunTask_Normal (void); void RunTask_Spray (void); void RunTask_HuntEnemy (void); void RunTask_SeekCover (void); void RunTask_Attack (void); void RunTask_Pause (void); void RunTask_Blinded (void); void RunTask_Camp (void); void RunTask_Hide (void); void RunTask_MoveToPos (void); void RunTask_PlantBomb (void); void RunTask_DefuseBomb (void); void RunTask_FollowUser (void); void RunTask_Throw_HE (void); void RunTask_Throw_FL (void); void RunTask_Throw_SG (void); void RunTask_DoubleJump (void); void RunTask_EscapeFromBomb (void); void RunTask_PickupItem (void); void RunTask_ShootBreakable (void); #ifdef DEAD_CODE bool CanStrafeRight (TraceResult *tr); bool CanStrafeLeft (TraceResult *tr); bool IsBlockedLeft (void); bool IsBlockedRight (void); void ChangePitch (float speed); void ChangeYaw (float speed); #endif void CheckMessageQueue (void); void CheckRadioCommands (void); void CheckReload (void); void AvoidGrenades (void); void CheckGrenadeThrow (void); void CheckBurstMode (float distance); void CheckSilencer (void); bool CheckWallOnLeft (void); bool CheckWallOnRight (void); void ChooseAimDirection (void); int ChooseBombWaypoint (void); bool DoWaypointNav (void); bool EnemyIsThreat (void); void UpdateLookAngles (void); void UpdateBodyAngles (void); void UpdateLookAnglesLowSkill (const Vector &direction, const float delta); void SetIdealReactionTimes (bool actual = false); bool IsRestricted (int weaponIndex); bool IsRestrictedAMX (int weaponIndex); bool IsInViewCone (const Vector &origin); void ReactOnSound (void); bool CheckVisibility (edict_t *target, Vector *origin, uint8 *bodyPart); bool IsEnemyViewable (edict_t *player); edict_t *FindNearestButton (const char *className); edict_t *FindBreakable (void); int FindCoverWaypoint (float maxDistance); int FindDefendWaypoint (const Vector &origin); int FindGoal (void); int FinishFindGoal (int tactic, Array *defensive, Array *offsensive); void FilterGoals (const Array &goals, int *result); void FindItem (void); void CheckTerrain (float movedDistance, const Vector &dirNormal); void CheckCloseAvoidance (const Vector &dirNormal); void GetCampDirection (Vector *dest); void CollectGoalExperience (int damage, int team); void CollectExperienceData (edict_t *attacker, int damage); int GetMessageQueue (void); bool GoalIsValid (void); bool HeadTowardWaypoint (void); int InFieldOfView (const Vector &dest); bool IsBombDefusing (const Vector &bombOrigin); bool IsPointOccupied (int index); inline bool IsOnLadder (void) { return pev->movetype == MOVETYPE_FLY; } inline bool IsOnFloor (void) { return (pev->flags & (FL_ONGROUND | FL_PARTIALGROUND)) != 0; } inline bool IsInWater (void) { return pev->waterlevel >= 2; } float GetWalkSpeed (void); bool ItemIsVisible (const Vector &dest, const char *itemName); bool LastEnemyShootable (void); bool IsBehindSmokeClouds (edict_t *ent); void RunTask (void); bool IsShootableBreakable (edict_t *ent); bool RateGroundWeapon (edict_t *ent); bool ReactOnEnemy (void); void ResetCollideState (void); void IgnoreCollisionShortly (void); void SetConditions (void); void SetConditionsOverride (void); void UpdateEmotions (void); void SetStrafeSpeed (const Vector &moveDir, float strafeSpeed); void StartGame (void); void TaskComplete (void); bool GetBestNextWaypoint (void); int GetBestWeaponCarried (void); int GetBestSecondaryWeaponCarried (void); void RunPlayerMovement (void); uint8 ThrottledMsec (void); void GetValidWaypoint (void); int ChangeWptIndex (int waypointIndex); bool IsDeadlyDrop (const Vector &to); bool OutOfBombTimer (void); Vector CheckThrow (const Vector &start, const Vector &stop); Vector CheckToss (const Vector &start, const Vector &stop); Vector CheckBombAudible (void); const Vector &GetAimPosition (void); float GetZOffset (float distance); int CheckGrenades (void); void CommandTeam (void); void AttachToUser (void); void CombatFight (void); bool IsWeaponBadInDistance (int weaponIndex, float distance); bool DoFirePause (float distance); bool LookupEnemy (void); bool IsEnemyHiddenByRendering (edict_t *enemy); void FireWeapon (void); void FinishWeaponSelection (float distance, int index, int id, int choosen); void FocusEnemy (void); void SelectBestWeapon (void); void SelectPistol (void); bool IsFriendInLineOfFire (float distance); bool IsGroupOfEnemies (const Vector &location, int numEnemies = 1, int radius = 256); bool IsShootableThruObstacle (const Vector &dest); bool IsShootableThruObstacleEx (const Vector &dest); int GetNearbyEnemiesNearPosition (const Vector &origin, float radius); int GetNearbyFriendsNearPosition (const Vector &origin, float radius); void SelectWeaponByName (const char *name); void SelectWeaponbyNumber (int num); int GetHighestWeapon (void); bool IsEnemyProtectedByShield (edict_t *enemy); bool ParseChat (char *reply); bool RepliesToPlayer (void); float GetBombTimeleft (void); float GetEstimatedReachTime (void); int GetCampAimingWaypoint (void); int GetAimingWaypoint (const Vector &to); void FindShortestPath (int srcIndex, int destIndex); void FindPath (int srcIndex, int destIndex, SearchPathType pathType = SEARCH_PATH_FASTEST); void DebugMsg (const char *format, ...); void PeriodicThink (void); public: entvars_t *pev; int m_wantedTeam; // player team bot wants select int m_wantedClass; // player model bot wants to select int m_difficulty; int m_moneyAmount; // amount of money in bot's bank Personality m_personality; float m_spawnTime; // time this bot spawned float m_timeTeamOrder; // time of last radio command float m_timePeriodicUpdate; // time to per-second think float m_timeRepotingInDelay; // time to delay report-in bool m_isVIP; // bot is vip? int m_numEnemiesLeft; // number of enemies alive left on map int m_numFriendsLeft; // number of friend alive left on map int m_retryJoin; // retry count for chosing team/class int m_startAction; // team/class selection state bool m_notKilled; // has the player been killed or has he just respawned bool m_notStarted; // team/class not chosen yet int m_voteKickIndex; // index of player to vote against int m_lastVoteKick; // last index int m_voteMap; // number of map to vote for int m_logotypeIndex; // index for logotype bool m_inBombZone; // bot in the bomb zone or not int m_buyState; // current Count in Buying float m_nextBuyTime; // next buy time bool m_inBuyZone; // bot currently in buy zone bool m_inVIPZone; // bot in the vip satefy zone bool m_buyingFinished; // done with buying bool m_buyPending; // bot buy is pending bool m_hasDefuser; // does bot has defuser bool m_hasC4; // does bot has c4 bomb bool m_hasProgressBar; // has progress bar on a HUD bool m_jumpReady; // is double jump ready bool m_canChooseAimDirection; // can choose aiming direction float m_turnAwayFromFlashbang; // bot turned away from flashbang float m_blindTime; // time when bot is blinded float m_blindMoveSpeed; // mad speeds when bot is blind float m_blindSidemoveSpeed; // mad side move speeds when bot is blind int m_blindButton; // buttons bot press, when blind edict_t *m_doubleJumpEntity; // pointer to entity that request double jump edict_t *m_radioEntity; // pointer to entity issuing a radio command int m_radioOrder; // actual command float m_duckForJump; // is bot needed to duck for double jump float m_baseAgressionLevel; // base aggression level (on initializing) float m_baseFearLevel; // base fear level (on initializing) float m_agressionLevel; // dynamic aggression level (in game) float m_fearLevel; // dynamic fear level (in game) float m_nextEmotionUpdate; // next time to sanitize emotions float m_thinkFps; // skip some frames in bot thinking float m_thinkInterval; // interval between frames int m_actMessageIndex; // current processed message int m_pushMessageIndex; // offset for next pushed message int m_goalFailed; // if bot can't reach several times in a row int m_prevGoalIndex; // holds destination goal waypoint int m_chosenGoalIndex; // used for experience, same as above float m_goalValue; // ranking value for this waypoint Vector m_waypointOrigin; // origin of waypoint Vector m_destOrigin; // origin of move destination Vector m_position; // position to move to in move to position task Vector m_doubleJumpOrigin; // origin of double jump Vector m_lastBombPosition; // origin of last remembered bomb position float m_viewDistance; // current view distance float m_maxViewDistance; // maximum view distance Vector m_lastEnemyOrigin; // vector to last enemy origin ChatCollection m_sayTextBuffer; // holds the index & the actual message of the last unprocessed text message of a player BurstMode m_weaponBurstMode; // bot using burst mode? (famas/glock18, but also silencer mode) edict_t *m_enemy; // pointer to enemy entity float m_enemyUpdateTime; // time to check for new enemies float m_enemyReachableTimer; // time to recheck if enemy reachable float m_enemyIgnoreTimer; // ignore enemy for some time bool m_isEnemyReachable; // direct line to enemy float m_seeEnemyTime; // time bot sees enemy float m_enemySurpriseTime; // time of surprise float m_idealReactionTime; // time of base reaction float m_actualReactionTime; // time of current reaction time edict_t *m_lastEnemy; // pointer to last enemy entity edict_t *m_lastVictim; // pointer to killed entity edict_t *m_trackingEdict; // pointer to last tracked player when camping/hiding float m_timeNextTracking; // time waypoint index for tracking player is recalculated float m_firePause; // time to pause firing float m_shootTime; // time to shoot float m_timeLastFired; // time to last firing int m_lastDamageType; // stores last damage int m_currentWeapon; // one current weapon for each bot int m_ammoInClip[MAX_WEAPONS]; // ammo in clip for each weapons int m_ammo[MAX_AMMO_SLOTS]; // total ammo amounts // a little optimization int m_team; Array m_tasks; Bot (edict_t *bot, int difficulty, int personality, int team, int member, const String &steamId); ~Bot (void); int GetAmmo (void); inline int GetAmmoInClip (void) { return m_ammoInClip[m_currentWeapon]; } inline edict_t *GetEntity (void) { return pev->pContainingEntity; }; int GetIndex (void); inline Vector Center (void) { return (pev->absmax + pev->absmin) * 0.5; }; inline Vector EyePosition (void) { return pev->origin + pev->view_ofs; }; // the main function that decides intervals of running bot ai void Think (void); /// the things that can be executed while skipping frames void ThinkFrame (void); void GotBlind (int alpha); void GetDamage (edict_t *inflictor, int damage, int armor, int bits); void DisplayDebugOverlay (void); void NewRound (void); void EquipInBuyzone (int buyState); void PushMessageQueue (int message); void PrepareChatMessage (char *text); bool FindWaypoint (void); bool EntityIsVisible (const Vector &dest, bool fromBody = false); void EnableChatterIcon (bool show); void DeleteSearchNodes (void); void VerifyBreakable (edict_t *touch); void PushTask (TaskID id, float desire, int data, float time, bool canContinue); void RemoveCertainTask (TaskID id); void ApplyTaskFilters (void); void ResetTasks (void); TaskItem *GetTask (void); inline TaskID GetTaskId (void) { return GetTask ()->id; }; void DiscardWeaponForUser (edict_t *user, bool discardC4); void ReleaseUsedName (void); void SayText (const char *text); void TeamSayText (const char *text); void ChatMessage (int type, bool isTeamSay = false); void RadioMessage (int message); void ChatterMessage (int message); void HandleChatterMessage (const char *sz); void TryHeadTowardRadioEntity (void); void Kill (void); void Kick (bool keepQuota = false); void ResetDoubleJumpState (void); int FindPlantedBomb(void); bool HasHostage (void); bool UsesRifle (void); bool UsesPistol (void); bool UsesSniper (void); bool UsesSubmachineGun (void); bool UsesZoomableRifle (void); bool UsesBadPrimary (void); bool UsesCampGun (void); bool HasPrimaryWeapon (void); bool HasSecondaryWeapon(void); bool HasShield (void); bool IsShieldDrawn (void); }; // manager class class BotManager : public Singleton { private: Array m_creationTab; // bot creation tab Bot *m_bots[MAX_ENGINE_PLAYERS]; // all available bots float m_maintainTime; // time to maintain bot creation float m_quotaMaintainTime; // time to maintain bot quota float m_grenadeUpdateTime; // time to update active grenades int m_lastWinner; // the team who won previous round int m_balanceCount; // limit of bots to add bool m_leaderChoosen[SPECTATOR]; // is team leader choose theese round bool m_economicsGood[SPECTATOR]; // is team able to buy anything bool m_deathMsgSent; // for fake ping Array m_activeGrenades; // holds currently active grenades in the map Array m_trackedPlayers; // holds array of connected players, and waits the player joins team edict_t *m_killerEntity; // killer entity for bots protected: BotCreationResult CreateBot (const String &name, int difficulty, int personality, int team, int member, bool isConsoleCmd); public: BotManager (void); ~BotManager (void); bool IsEcoValid (int team) { return m_economicsGood[team]; } bool IsTeamStacked (int team); int GetLastWinner (void) const { return m_lastWinner; } void SetLastWinner (int winner) { m_lastWinner = winner; } int GetIndex (edict_t *ent); Bot *GetBot (int index); Bot *GetBot (edict_t *ent); Bot *FindOneValidAliveBot (void); Bot *GetHighestFragsBot (int team); int GetHumansNum (void); int GetHumansAliveNum(void); int GetHumansJoinedTeam (void); int GetBotsNum (void); void Think (void); void PeriodicThink (void); void CreateKillerEntity (void); void DestroyKillerEntity (void); void TouchWithKillerEntity (Bot *bot); void Free (void); void Free (int index); void AddRandom (bool isConsoleCmd = true) { AddBot ("", -1, -1, -1, -1, isConsoleCmd); } void AddBot (const String &name, int difficulty, int personality, int team, int member, bool isConsoleCmd = true); void AddBot (const String &name, const String &difficulty, const String &personality, const String &team, const String &member, bool isConsoleCmd = true); void FillServer (int selection, int personality = PERSONALITY_NORMAL, int difficulty = -1, int numToAdd = -1); void RemoveAll (void); void RemoveRandom (bool keepQuota = false); void RemoveFromTeam (Team team, bool removeAll = false); void RemoveMenu (edict_t *ent, int selection); void KillAll (int team = -1); void MaintainBotQuota (void); void AdjustQuota (bool isPlayerConnection, edict_t *ent); void InitQuota (void); void AddPlayerToCheckTeamQueue (edict_t *ent); void VerifyPlayersHasJoinedTeam (int &desiredCount); void SelectLeaderEachTeam (int team, bool reset); void ListBots (void); void SetWeaponMode (int selection); void CheckTeamEconomics (int team, bool setTrue = false); static void CallGameEntity (entvars_t *vars); inline void SetDeathMsgState (bool sent) { m_deathMsgSent = sent; } // grenades void UpdateActiveGrenades (void); const Array &GetActiveGrenades (void); inline bool HasActiveGrenades (void) { return !m_activeGrenades.IsEmpty (); } public: void CalculatePingOffsets (void); void SendPingDataOffsets (edict_t *to); void SendDeathMsgFix (void); }; // waypoint operation class class Waypoint : public Singleton { friend class Bot; private: Path *m_paths[MAX_WAYPOINTS]; bool m_waypointPaths; bool m_isOnLadder; bool m_endJumpPoint; bool m_learnJumpWaypoint; bool m_waypointsChanged; float m_timeJumpStarted; Vector m_learnVelocity; Vector m_learnPosition; Vector m_foundBombOrigin; int m_loadTries; int m_cacheWaypointIndex; int m_lastJumpWaypoint; int m_visibilityIndex; Vector m_lastWaypoint; uint8 m_visLUT[MAX_WAYPOINTS][MAX_WAYPOINTS / 4]; float m_pathDisplayTime; float m_arrowDisplayTime; float m_waypointDisplayTime[MAX_WAYPOINTS]; int m_findWPIndex; int m_facingAtIndex; char m_infoBuffer[256]; int *m_distMatrix; int *m_pathMatrix; Array m_terrorPoints; Array m_ctPoints; Array m_goalPoints; Array m_campPoints; Array m_sniperPoints; Array m_rescuePoints; Array m_visitedGoals; public: bool m_redoneVisibility; Waypoint (void); ~Waypoint (void); void Init (void); void InitExperienceTab (void); void InitVisibilityTab (void); void InitTypes (void); void AddPath (int addIndex, int pathIndex, float distance); int GetFacingIndex (void); int FindFarest (const Vector &origin, float maxDistance = 32.0); int FindNearest (const Vector &origin, float minDistance = 9999.0f, int flags = -1); void FindInRadius (Array &holder, float radius, const Vector &origin, int maxCount = -1); void Add (int flags, const Vector &waypointOrigin = Vector::GetZero ()); void Delete (void); void ToggleFlags (int toggleFlag); void SetRadius (int radius); bool IsConnected (int pointA, int pointB); bool IsConnected (int num); void InitializeVisibility (void); void CreatePath (char dir); void DeletePath (void); void CacheWaypoint (void); float GetTravelTime (float maxSpeed, const Vector &src, const Vector &origin); bool IsVisible (int srcIndex, int destIndex); bool IsStandVisible (int srcIndex, int destIndex); bool IsDuckVisible (int srcIndex, int destIndex); void CalculateWayzone (int index); bool Load (void); void Save (void); void CleanupPathMemory (void); bool Reachable (Bot *bot, int index); bool IsNodeReachable (const Vector &src, const Vector &destination); void Think (void); bool NodesValid (void); void SaveExperienceTab (void); void SaveVisibilityTab (void); void CreateBasic (void); void EraseFromHardDisk (void); void InitPathMatrix (void); void SavePathMatrix (void); bool LoadPathMatrix (void); int GetPathDistance (int srcIndex, int destIndex); Path *GetPath (int id); const char *GetWaypointInfo (int id); char *GetInfo (void) { return m_infoBuffer; } bool HasChanged (void) { return m_waypointsChanged; } void SetFindIndex (int index); void SetLearnJumpWaypoint (void); bool IsGoalVisited (int index); void SetGoalVisited (int index); void ClearVisitedGoals (void); const char *GetDataDir (bool isMemoryFile = false); const char *GetFileName (bool isMemoryFile = false); void SetBombPosition (bool shouldReset = false); inline const Vector &GetBombPosition (void) { return m_foundBombOrigin; } // free's socket handle void CloseSocketHandle (int sock); // do actually downloading of waypoint file WaypointDownloadError RequestWaypoint (void); }; class BotMenu { }; #include // expose bot super-globals #define waypoints Waypoint::GetReference () #define engine Engine::GetReference () #define bots BotManager::GetReference () // prototypes of bot functions... extern int GetWeaponReturn (bool isString, const char *weaponAlias, int weaponIndex = -1); extern int GetWeaponPenetrationPower (int id); extern int GenerateBuildNumber (void); extern float GetShootingConeDeviation (edict_t *ent, Vector *position); extern bool IsVisible (const Vector &origin, edict_t *ent); extern bool IsAlive (edict_t *ent); extern bool IsInViewCone (const Vector &origin, edict_t *ent); extern bool IsValidBot (edict_t *ent); extern bool IsValidPlayer (edict_t *ent); extern bool IsPlayerVIP (edict_t *ent); extern bool OpenConfig (const char *fileName, const char *errorIfNotExists, MemoryFile *outFile, bool languageDependant = false); extern bool FindNearestPlayer (void **holder, edict_t *to, float searchDistance = 4096.0, bool sameTeam = false, bool needBot = false, bool needAlive = false, bool needDrawn = false); extern void FreeLibraryMemory (void); extern void RoundInit (void); extern void CheckWelcomeMessage (void); extern void AddLogEntry (bool outputToConsole, int logLevel, const char *format, ...); extern void DisplayMenuToClient (edict_t *ent, MenuId menu); extern void DecalTrace (entvars_t *pev, TraceResult *trace, int logotypeIndex); extern void SoundAttachToClients (edict_t *ent, const char *sample, float volume); extern void SoundSimulateUpdate (int playerIndex); extern const char *FormatBuffer (const char *format, ...); // very global convars extern ConVar yb_jasonmode; extern ConVar yb_communication_type; extern ConVar yb_csdm_mode; extern ConVar yb_ignore_enemies; #include #include #include inline int Bot::GetIndex (void) { return engine.IndexOfEntity (GetEntity ()); }