etqw-sdk/source/game/botai/BotAI_Main.h

1757 lines
63 KiB
C++

// Copyright (C) 2007 Id Software, Inc.
//
#ifndef __BOTAI_H__
#define __BOTAI_H__
#include "aas/AAS.h"
#include "aas/ObstacleAvoidance.h"
#include "BotAI_Routes.h"
#include "BotAI_VNodes.h"
#include "../ContentMask.h"
#define AAS_PLAYER 0
#define AAS_VEHICLE 1
#define MEDIC_RANGE 1500.0f //mal: how far a medic's "awareness" of hurt/dead mates extends by default
#define MEDIC_RANGE_BUSY 800.0f //mal: how far a medic's "awareness" of hurt/dead mates extends when busy (escorting, already healing, carrying obj, etc).
#define MEDIC_RANGE_CARRIER 500.0f //mal: how far a medic's "awareness" of hurt/dead mates extends when carrier
#define MEDIC_RANGE_REQUEST 3000.0f
#define FOLLOW_RANGE 2000.0f //mal: how far we'll follow a teammate
#define FDA_AUTO_GRAB_DIST 2500.0f
#define MAX_PATROL_DELIVER_CLIENTS 1
#define PATROL_DELIVER_TEST_DIST 350.0f
#define IGNORE_ITEM_TIME 15000
#define ITEM_PACK_OFFSET 24.0f
#define FLYER_WORRY_ABOUT_ROCKETS_MAX_DIST 2500.0f
#define MEDIC_ACK_MIN_DIST 150.0f
#define TOO_CLOSE_TO_GOAL_TO_FOLLOW_DIST 1000.0f
#define TOO_CLOSE_TO_DELIVER_TO_FOLLOW_DIST 1500.0f
#define FLYER_AVOID_DANGER_TIME 2500
#define IGNORE_PLANTED_CHARGE_TIME 10000
#define IGNORE_PATH_NODE_TIME 5000
#define BOT_WILL_ATTACK_TURRETS_IN_COMBAT_DIST 1500.0f
#define MAX_FRAMES_BLOCKED_BY_OBSTACLE_ON_FOOT 50
#define MAX_FRAMES_BLOCKED_BY_OBSTACLE_IN_VEHICLE 50
#define EASY_MODE_CHANCE_WILL_BUILD_DEPLOYABLE_OR_USE_VEHICLE 40
#define RANDOMLY_LOOK_AROUND_WHILE_VEHICLE_GUNNER_CHANCE 95
#define MAX_MOVE_ATTEMPTS 10
#define GUNNER_ATTACK_DEPLOYABLE_DIST 8192.0f
#define IGNORE_CLASS_GOALS_TIME 7000
#define IGNORE_IF_JUST_LEFT_VEHICLE_TIME 5000
#define REPAIR_DRONE_RANGE 625.0f
#define MIN_NUM_INVESTIGATE_CLIENTS 3
#define MAX_NUM_DEFEND_CHARGE_CLIENTS 3
#define MAX_REPAIR_DIST 450.0f
#define SUPPLY_CRATE_DELAY_TIME 20000
#define MAX_CONSIDER_HUMAN_FOR_RIDE_DIST 900.0f
#define MIN_CLASS_CHANGE_DELAY 15000
#define MIN_WEAPON_CHANGE_DELAY 180000
#define TAKE_SPAWN_IN_DEMO_MODE_CHANCE 25
#define CLOSE_ENOUGH_TO_INVESTIGATE_GOAL_RANGE 75.0f
#define CRITICAL_ENEMY_CLOSE_TO_GOAL_RANGE 350.0f
#define MAX_DEPLOYABLE_FLANK_POINTS 6
#define TRAINING_MODE_RANGE_ADDITION 2000.0f
#define KILLING_SPREE 4
#define MAX_ATTACK_GRIEFER_RANGE 8192.0f
#define IGNORE_NEW_ENEMIES_TIME 5000 //mal: ignore new enemies for 5 seconds when find an important one!
#define MAX_AI_NODE_SWITCH 25
#define MAX_MOVE_ERRORS 5
#define SHIELD_CONSIDER_RANGE 900.0f
#define SHIELD_FIRING_RANGE 250.0f
#define SHEILD_FIRE_CONSIDER_RANGE 1500.0f
#define SMOKE_CONSIDER_RANGE 1500.0f
#define MAX_OWN_VEHICLE_TIME 20000 //mal: time enough for the human to jump out and repair, or look around for a bit, before jumping back in.
#define BACKSTAB_DIST 145.0f
#define DEPLOYABLE_PAUSE_TIME 1500
#define THIRD_EYE_SAFE_RANGE 700.0f
#define TANK_MINIGUN_RANGE 3000.0f
#define MINIMUM_VEHICLE_IGNORE_TIME 3000.0f
#define COS_TURRET_ANGLE_ARC 0.38f
#define DRONE_REPAIR_TIME 60000
#define MIN_TELEPORTER_RANGE 2500.0f
#define MAX_TELEPORTER_RANGE 5000.0f
#define MAX_NUM_OF_FRIENDS_OF_VICTIM 1
#define SPAWNHOST_DESTROY_ORDER_RANGE 5000.0f
#define AIRCRAFT_ATTACK_DIST 10000.0f
#define SPAWN_CONSIDER_TIME 7000
#define MEDIC_IGNORE_TIME 15000 //mal: medics ignore unreachable clients
#define ENEMY_IGNORE_TIME 7000 //mal: enemies are ignored for 7 seconds
#define BODY_IGNORE_TIME 15000 //mal: bodies are ignored for 15 seconds
#define CLIENT_IGNORE_TIME 15000 //mal: regular clients are ignored for 15 seconds
#define ACTION_IGNORE_TIME 7000 //mal: actions are ignored for 7 seconds.
#define DEPLOYABLE_IGNORE_TIME 30000
#define ENEMY_SIGHT_DIST 3000.0f //2500.0f //mal: how far a bot will by default see an enemy, can be overriden by script //mal_TODO: good value?
#define ENEMY_SIGHT_BUSY_DIST 2500.0f //mal: how far a bot will see when busy with another enemy //mal_TODO: good value?
#define ENEMY_VEHICLE_SIGHT_DIST 8000.0f
#define COVERT_SIGHT_DIST 512.0f
#define MAX_PATH_FAILED_COUNT 12
#define GOAL_ORIGIN_DIST 150.0f
const int BOT_VISIBILITY_TRACE_MASK = MASK_SHOT_BOUNDINGBOX | MASK_VEHICLESOLID | CONTENTS_FORCEFIELD | CONTENTS_MONSTER | MASK_SHOT_RENDERMODEL;
#define SNIPER_HEARING_DIST 4096.0f
#define VEHICLE_HEARING_DIST 6000.0f
#define PLAYER_HEARING_DIST 1200.0f
#define DEFENSE_CAMP_MATE_RANGE 150.0f
#define WARMUP_ACTION_TIME 2500
#define PLASMA_CANNON_RANGE 8000.0f
#define FLYER_HIVE_SIGHT_DIST 1500.0f
#define FLYER_HIVE_ATTACK_DIST 125.0f
#define FLYER_HIVE_HEIGHT_OFFSET 82.0f
#define MEDIC_REQUEST_CONSIDER_TIME 10000
#define SLIPGATE_ORIGIN idVec3( -9627.0f, 9098.0f, 1627.0f )
#define NULL_AREANUM 0
#define DEPLOYABLE_ORIGIN_OFFSET 32.0f
#define DEPLOYABLE_PATH_ORIGIN_OFFSET 16.0f
#define VEHICLE_PATH_ORIGIN_OFFSET 16.0f
#define TK_REVIVE_CHAT_TIME 10000
#define HUMAN_OWN_VEHICLE_DIST 350.0f
#define CLOSE_TO_GOAL_RANGE 3000.0f
#define MAX_RIDE_DIST 6000.0f
#define MAX_MINE_CHECK_DIST 2048.0f
#define VEHICLE_NODE_TIMEOUT 10000
#define MAX_MOVE_FAILED_TIME 5000
#define MAX_MOVE_FAILED_COUNT 150
#define DEFAULT_DEPLOYABLE_COVERAGE_RANGE 6192.0f
#define AVT_NEAR_MCP_CONSIDER_RANGE 1900.0f
#define LIGHTNING_GUN_DIST 1900.0f //mal: a little shorter then the actual range - so the bots always hit the target.
#define ACTION_CHECK_TEAMMATE_DIST 512.0f
#define TRAVEL_TIME_MULTIPLY 4
#define SAFE_PLAYER_BODY_WIDTH 65.0f
#define MAX_SHOT_BLOCKED_COUNT 30
#define BOT_ATTACK_DEPLOYABLE_RANGE 1700.0f
#define ARTY_LOCKON_TIME 900 //1200
#define THIRD_EYE_RANGE 2048.0f
#define MAX_LANDMINE_DIST 256.0f
#define GRENADE_IGNORE_TIME 7000
#define ESCORT_RANGE 3000.0f
#define REQUEST_CONSIDER_TIME 5000
#define SPAWNHOST_RELEVANT_DIST 6000.0f
#define GRENADE_THROW_MAXDIST 1200.0f
#define GRENADE_THROW_MINDIST 1000.0f
#define GRENADE_ATTACK_DIST 1700.0f
#define SHOTGUN_DIST 1500.0f
#define BOT_AWARENESS_DIST 1500.0f
#define OBJ_AWARENESS_DIST 3500.0f
#define SPAWNHOST_RANGE 1500.0f
#define TACTICAL_PAUSE_ACTION 9999999
#define FIX_DEPLOYABLE_DIST 1900.0f
#define BASE_ANTI_MISSILE_RANGE 3000.0f
#define ANTI_MISSILE_RANGE 7000.0f
#define GAME_PLAY_RANGE 8192.0f
#define CLOSE_MINE_DIST 700.0f
#define INFANTRY_ATTACK_HEAVY_DIST 1200.0f
#define CLIENT_HAS_NO_VEHICLE -1
#define DEPLOYABLE_GOAL_DIST 8000.0f
#define MG_REPAIR_MAX_DIST 5000.0f
#define DEPLOYABLE_DISABLED_PERCENT 1.5f
#define ATTACK_APT_DIST 1700.0f
#define HIVE_ATTACK_APT_DIST 3000.0f
#define MINE_TOO_FAR_DIST 512.0f
#define MINE_TOO_CLOSE_DIST 300.0f
#define LOOK_AT_GOAL_DIST 350.0f
#define ATTACK_MCP_DIST 1200.0f
#define VEHICLE_PAUSE_TIME 50
#define ENEMY_CHASE_DIST 1500.0f //mal: max dist bot will chase you //mal_TODO: good value?
#define FOOTSTEP_DIST 500.0f //mal: how far your footsteps sound //mal_TODO: is this accurate?
#define FOLLOW_MATE_TIMELIMIT 120000 //mal: default is follow this teammate for a 2 minutes.
#define DEFAULT_LTG_TIME 120000 //mal: default timelimit for doing an ltg - 2 minutes.
#define TACTICAL_ACTION_TIME 5000 //mal: how long to execute a tactical action
#define TACTICAL_HIVE_TIME 30000 //mal: we do the flyer hive for longer.
#define BOT_INFINITY 99999999 //mal: something to do for a long time.
#define MAX_IGNORE_ENTITIES 8 //mal: how many enemies/clients/bodies a bot can ignore at a time.
#define TIME_BEFORE_CHARGE_BLOWS_AWARENESS_TIME 4
#define IGNORE_ICARUS_TIME 15000
#define PLIERS_RANGE 125.0f
#define ITEM_RANGE 900.0f
#define HORNET_SLOWDOWN_DIST 1700.0f //mal: ugly hacks.
#define HORNET_TOOFAST_SPEED 1500.0f
#define BOT_RECOVER_OBJ_RANGE 4500.0f
#define BOT_INVESTIGATE_RANGE 3500.0f
#define MAX_HIVE_RANGE 8192.0f
#define MAX_DELAYED_CHATS 4
#define MAX_DANGERS 8
#define SLIPGATE_DIVIDING_PLANE_X_VALUE -3120.0f //mal: HACK
#define BODY_IGNORE_RANGE 2500.0f
#define MAX_MCP_ATTRACT_DIST 2500.0f
//mal: rough approximations
#define WALKING_SPEED 78.0f
#define RUNNING_SPEED 250.0f
#define SPRINTING_SPEED 350.0f
#define BASE_VEHICLE_SPEED 512.0f
#define TK_REVIVE_HEALTH 20
#define WEAPON_LOCK_DIST 8192.0f
#define MAX_SNIPER_VIEW_DIST 12000.0f //mal: test to see if this works
#define MAX_SNIPER_CROSSHAIR_DANGER_DIST 700.0f
#define MCP_PARKED_DIST 150.0f
//mal: what kind of charge should we look for?
#define ARM true
#define DISARM false
#define PACKS_HAVE_NO_NADES //mal: put in for a last minute change to the gameplay behavior
#ifdef _XENON
#define STROGG_INSTANT_REVIVE //mal: on the console, strogg have instant revives.
#endif
enum bot_LTG_Types_t {
NO_LTG = -1,
FOLLOW_TEAMMATE,
ROAM_GOAL,
CAMP_GOAL,
BUILD_GOAL,
HACK_GOAL,
HUNT_GOAL, // the AI has a client it wants to kill for some reason.
PLANT_GOAL,
DEFUSE_GOAL,
FIRESUPPORT_CAMP_GOAL,
MINE_GOAL,
SNIPE_GOAL,
INVESTIGATE_ACTION,
ENTER_VEHICLE,
FIX_MCP,
DRIVE_MCP,
MINOR_BUILD_GOAL,
FDA_GOAL,
STEAL_SPAWN_GOAL,
STEAL_GOAL,
DELIVER_GOAL,
RECOVER_GOAL,
DROP_DEPLOYABLE_GOAL,
DESTROY_DEPLOYABLE_GOAL,
HACK_DEPLOYABLE_GOAL,
GRAB_VEHICLE_GOAL,
DEFENSE_CAMP_GOAL,
ENTER_HEAVY_VEHICLE,
MINOR_BUILD_MG,
MG_CAMP_GOAL,
FLYER_HIVE_GOAL,
MG_REPAIR_GOAL,
DROP_PRIORITY_DEPLOYABLE_GOAL,
PRIORITY_MINE_GOAL,
FOLLOW_TEAMMATE_BY_REQUEST,
ENTER_VEHICLE_GOAL,
ACTOR_GOAL,
LAST_ACTOR_GOAL,
THIRD_EYE_GOAL,
PROTECT_CHARGE,
PATROL_DELIVER_GOAL
//mal_TODO: add more here as you add them in the AI network
};
enum bot_Vehicle_LTG_Types_t {
NO_VEHICLE_LTG = -1,
V_ROAM_GOAL, //mal: this is vehicle specific
V_CAMP_GOAL,
V_GOTO_REVIVE_MATE,
V_TRAVEL_GOAL,
V_FOLLOW_TEAMMATE,
V_STOP_VEHICLE,
V_DRIVE_MCP,
V_DESTROY_DEPLOYABLE,
V_ORIGIN_GOAL,
V_DRIVE_MCP_ROUTE,
V_HUNT_GOAL
};
enum bot_NBG_Types_t {
NO_NBG = -1,
REVIVE_TEAMMATE,
TK_REVIVE_TEAMMATE,
SUPPLY_TEAMMATE,
CREATE_SPAWNHOST,
HAZE_ENEMY,
CAMP,
BUILD,
PLANT_MINE,
PLANT_BOMB,
HACK,
STEAL_UNIFORM,
STALK_VICTIM,
DEFUSE_BOMB,
GRAB_SUPPLIES,
BUG_FOR_SUPPLIES,
AVOID_DANGER,
SNIPE,
DESTROY_DANGER,
FIX_VEHICLE,
DESTROY_MCP,
DESTORY_SPAWNHOST,
GRAB_SPAWN,
FIX_DEPLOYABLE,
DROP_DEPLOYABLE,
DESTROY_DEPLOYABLE,
GRAB_SPAWNHOST,
HACK_DEPLOYABLE,
DEFENSE_CAMP,
MG_CAMP,
FLYER_HIVE_ATTACK,
FIX_GUN,
PAUSE,
ENG_ATTACK_AVT,
FIXING_MCP,
DROPPING_SHIELD,
INVESTIGATE_CAMP,
DROPPING_SMOKE_FOR_MATE
//mal_TODO: add more here as you add them in the AI network
};
enum bombStates_t {
BOMB_NULL, // the bot has no bomb out there, or its not armed yet.
BOMB_ARMED // the bot's bomb is hot!
};
enum entityTypes_t {
ENTITY_NULL,
ENTITY_PLAYER,
ENTITY_DEPLOYABLE,
ENTITY_VEHICLE
};
struct dangerList_t {
int num;
int time;
int ownerNum;
dangerTypes_t type;
idVec3 origin;
idMat3 dir; //mal: only airstrikes need this.
};
struct genericNumTimeList_t {
int num;
int time;
};
struct plantedChargeInfo_t { //mal: tracks the player's HE/Plasma charges
bool checkedAreaNum;
bool isOnObjective;
int entNum;
int areaNum;
int spawnID;
int explodeTime; //mal: when this charge will explode
int ownerSpawnID;
int ownerEntNum;
bombStates_t state; //mal: 0 = not deployed, 1 = deployed, 2 = armed.
playerTeamTypes_t team;
idVec3 origin;
idBounds bbox;
};
struct plantedMineInfo_t { //mal: tracks the player's landmines
bool spotted;
bool selfArming;
int entNum;
int spawnID;
float xySpeed;
bombStates_t state; //mal: 0 = not deployed, 1 = deployed, 2 = armed.
idBounds bbox;
idVec3 origin;
};
struct grenadeInfo_t { //mal: tracks the player's EMP/Shrap grenades
int entNum;
int spawnID;
float xySpeed;
idVec3 origin;
};
struct airstrikeInfo_t { //mal: tracks the player's airstrikes
int entNum;
int spawnID;
int timeTilStrike;
int oldEntNum;
float xySpeed;
idVec3 origin;
idMat3 dir;
};
struct botChats_t {
bool forceChat;
int delayTime;
botChatTypes_t chat;
};
struct deployableFlankPoints_t {
bool checked;
idVec3 flankPoint;
};
struct deployableInfo_t {
bool inPlace; //mal: will be false if its being dropped in still
bool disabled; //mal: will be true if health < 50%, or is emped.
int ownerClientNum;
int health;
int type;
int enemyEntNum; //mal: who our current enemy is. Could be a player or a vehicle.
int areaNum;
int areaNumVehicle;
int entNum;
int spawnID;
int maxHealth;
float maxAttackRange; //mal: how far this deployable can reach.
float minAttackRange; //mal: if your closer then this, it wont attack you.
playerTeamTypes_t team;
deployableFlankPoints_t flankPoints[ MAX_DEPLOYABLE_FLANK_POINTS ];
idVec3 origin;
idMat3 axis;
idBounds bbox;
idBox dangerAreaBox;
};
struct proxyInfo_t { //mal_TODO: keep adding more info for vehicles, as its needed
bool isEmpty;
bool isDeployed;
bool isEMPed;
bool isOwned;
bool neverDriven;
bool isFlipped;
bool isAmphibious;
bool isAirborneVehicle;
bool isAirborneAttackVehicle;
bool isImmobilized;
bool inWater;
bool inPlayZone;
bool inSiegeMode;
bool hasGroundContact;
bool hasFreeSeat; //mal: does this vehicle have a seat open?
bool isCareening; //mal: this vehicle is out of control!
bool canRotateInPlace;
bool isBoobyTrapped;
int damagedPartsCount; //mal: this will only be true if the vehicle has missing wheels/legs/whatever that affect its ability to drive properly, NOT health.
int entNum;
int spawnID;
int ownerNum;
int health;
int maxHealth;
int areaNum;
int areaNumVehicle;
int driverEntNum;
int flags;
int actionRouteNumber;
float xyspeed;
float forwardSpeed;
float wheelsAreOnGround;
playerTeamTypes_t team;
playerVehicleTypes_t type;
idBounds bbox;
idVec3 origin;
idVec3 aasOrigin;
idVec3 aasVehicleOrigin;
idMat3 axis;
};
struct supplyPackInfo_t {
bool checkedAreaNum;
bool inPlayZone;
bool available;
bool inWater;
int entNum;
int spawnID;
int areaNum;
float xySpeed; //mal: want to make sure the pack isn't moving!
playerTeamTypes_t team; //mal: team that my owner was in when I was born ( in case he changes ).
idVec3 origin; //mal: my current origin - this will be actively tracked while I'm alive ( in case I move for some reason ).
idBounds bbox; //mal: only supply crates really need this.
};
struct killedPlayersInfo_t {
int clientNum; //mal: client we killed last.
idVec3 ourOrigin; //mal: where we were when client died.
};
enum bot_COMBAT_Types_t {
NO_COMBAT_TYPE = -1,
COMBAT_REVIVE_MATE,
COMBAT_GRAB_VEHICLE,
COMBAT_ATTACK_TURRET
//mal_TODO: add more here as you add them in the AI network
};
enum weaponBankTypes_t {
RESET_WEAPON = -2, //mal: if the bot needs to reset the weapon for some purpose.
NO_WEAPON = -1, // when the bot doesn't want to switch weapons
MELEE, // 0: KNIFE, blade, fists, whatever.
SIDEARM, // 1:
GUN, // 2:
NADE, // 3:
SPECIAL1, // 4: defrib, pliers, tools, deploy tools
SPECIAL2, // 5: health pack, HE charge, landmine, aircan
GUN_ALT, // 6: the alt fire mode of the main gun (nade launcher, homing missle, etc).
SPECIAL1_ALT // 7: deploy tools
};
enum bot_AI_States_t {
LTG,
NBG,
COMBAT,
VLTG,
VCOMBAT
};
enum targetTypes_t {
NOTYPE = -1,
CLIENT,
BODY,
LOCATION,
HEAL,
REARM,
HEAL_REQUESTED,
REARM_REQUESTED,
LANDMINE_DANGER,
DEPLOYABLE_DANGER,
STROGG_HIVE_DANGER,
GDF_CAM_DANGER,
VEHICLE,
DEPLOYABLE,
SUPPLY_CRATE,
MCP_DANGER,
MCP_GOAL,
REARM_REVIVE
};
enum botTurnTypes_t {
INSTANT_TURN,
SMOOTH_TURN,
AIM_TURN,
FAST_TURN // a bit inbetween INSTANT and SMOOTH
};
enum botViewTypes_t {
VIEW_ANGLES, // look at a specific angle
VIEW_ORIGIN, // look at a specific point
VIEW_ENTITY, // look at a specific entity
VIEW_MOVEMENT, // look in the direction we're moving
VIEW_RANDOM, // look at a random point - gets us off a ladder we may be stuck on.
VIEW_REVERSE
};
enum botMoveTypes_t {
NULLMOVETYPE = -1,
RANDOM_JUMP, // straight jump, doesn't veer off move direction
QUICK_JUMP, // straight jump, MUCH faster then a random jump
LOCATION_JUMP, //mal: theres a certain spot we need to jump at, so bot will need to know to look for the goal spot we're jumping to.
LOCATION_BARRIERJUMP,
LOCATION_WALKOFFLEDGE,
STRAFE_RIGHT,
STRAFE_LEFT,
RANDOM_JUMP_RIGHT,
RANDOM_JUMP_LEFT,
HAND_BRAKE,
AIR_BRAKE, //mal: for planes
FULL_STOP, //mal: stop NOW!
LAND, //mal: for planes - land this craft!
LEAN_LEFT,
LEAN_RIGHT,
TAUNT_MOVE,
AIR_COAST,
SLOWMOVE,
REVERSEMOVE,
RANDOM_DIR_JUMP,
ICARUS_BOOST,
IGNORE_ALTITUDE,
BACKSTEP,
SKIP_MOVE
};
enum botAttackMoveTypes_t {
COMBAT_MOVE_NULL = -1,
KNIFE_ATTACK, //movements we do with a knife
RUN_N_GUN_ATTACK, // bascially run towards the enemy, blasting them as we go.
CROUCH_ATTACK, // will crouch down and fire.
PRONE_ATTACK, // usually snipers/campers use this
HAL_STRAFE_ATTACK, // various strafes....
SIDE_STRAFE_ATTACK,
CIRCLE_STRAFE_ATTACK,
CRAZY_JUMP_ATTACK, // jump around wildly, to make yourself a harder to hit target. Usually used by guys with knifes, but also in close quarters when reloading
STAND_GROUND_ATTACK, // stands there and fights
GRENADE_ATTACK,
AVOID_DANGER_ATTACK,
NULL_MOVE_ATTACK,
MOVETO_SHIELD_ATTACK,
REVIVE_MATE_ATTACK,
//mal: vehicle based combat movements
VEHICLE_STAND_GROUND,
VEHICLE_NULL_MOVEMENT, // used mostly by gunners in a vehicle.
VEHICLE_RANDOM_MOVEMENT,
VEHICLE_RAM_ATTACK_MOVEMENT,
VEHICLE_CHASE_MOVEMENT,
VEHICLE_AIR_MOVEMENT
};
struct clientInfo_t;
struct botAIOutput_t;
struct sharedWorldState_t;
class idBotAI {
public:
idBotAI();
~idBotAI();
void Think();
void VThink(); //mal: vehicle specific think function.
void Spawn( int playerClass, int playerTeam );
void SetBotClientNum( int clientNum ) { botNum = clientNum; }
void UpdateAAS();
const bot_AI_States_t GetAIState() { return aiState; }
const bot_LTG_Types_t GetLTGType() { return ltgType; }
const bool GetLTGUseVehicle() { return ltgUseVehicle; }
const bot_NBG_Types_t GetNBGType() { return nbgType; }
const int GetLTGTarget() { return ltgTarget; }
const int GetNBGTarget() { return nbgTarget; }
const bot_Vehicle_LTG_Types_t GetVehicleLTGType() { return vLTGType; }
const int GetVehicleLTGTarget() { return vLTGTarget; }
const int GetEnemyNum() { return enemy; }
const int GetActionNum() { return actionNum; }
const int GetVehicleSurrenderTime() { return vehicleSurrenderTime; }
const int GetVehicleSurrenderClient() { return vehicleSurrenderClient; }
void ResetLastActionNum() { lastActionNum = ACTION_NULL; }
void ClearBotUcmd( int clientNum );
//mal: major AI nodes
bool Run_LTG_Node();
bool Run_NBG_Node();
bool Run_Combat_Node();
bool Enter_Run_Dead_Node();
bool Run_Dead_Node();
bool Run_Intermission_Node();
bool Run_Warmup_Node();
//mal: major vehicle AI nodes
bool Run_VLTG_Node(); //mal: vehicle specific LTG node.
bool Run_VCombat_Node(); //mal: vehicle specific Combat node.
//mal: LTG nodes....
bool Enter_LTG_FollowMate();
bool LTG_FollowMate();
bool Enter_LTG_RoamGoal();
bool LTG_RoamGoal();
bool Enter_LTG_CampGoal();
bool LTG_CampGoal();
bool Enter_LTG_BuildGoal();
bool LTG_BuildGoal();
bool LTG_ErrorThink(); //mal: a special node to think when the bot has nothing to think about ( i.e. no goals on map ).
bool Enter_LTG_PlantGoal();
bool LTG_PlantGoal();
bool Enter_LTG_HackGoal();
bool LTG_HackGoal();
bool Enter_LTG_DefuseGoal();
bool LTG_DefuseGoal();
bool Enter_LTG_HuntGoal();
bool LTG_HuntGoal();
bool Enter_LTG_MineGoal();
bool LTG_MineGoal();
bool Enter_LTG_SnipeGoal();
bool LTG_SnipeGoal();
bool Enter_LTG_InvestigateGoal();
bool LTG_InvestigateGoal();
bool Enter_LTG_UseVehicle();
bool LTG_UseVehicle();
bool Enter_LTG_FixMCP();
bool LTG_FixMCP();
bool Enter_LTG_SpawnPointGoal();
bool LTG_SpawnPointGoal();
bool Enter_LTG_DeliverGoal();
bool LTG_DeliverGoal();
bool Enter_LTG_StealGoal();
bool LTG_StealGoal();
bool Enter_LTG_RecoverDroppedGoal();
bool LTG_RecoverDroppedGoal();
bool Enter_LTG_DeployableGoal();
bool LTG_DeployableGoal();
bool Enter_LTG_DestroyDeployable();
bool LTG_DestroyDeployable();
bool Enter_LTG_FireSupportGoal();
bool LTG_FireSupportGoal();
bool Enter_LTG_HackDeployableGoal();
bool LTG_HackDeployableGoal();
bool Enter_LTG_MG_CampGoal();
bool LTG_MG_CampGoal();
bool Enter_LTG_FlyerHiveGoal();
bool LTG_FlyerHiveGoal();
bool Enter_LTG_RepairGunGoal();
bool LTG_RepairGunGoal();
bool Enter_LTG_EnterVehicleGoal();
bool LTG_EnterVehicleGoal();
bool Enter_LTG_ActorEscortPlayerToGoal();
bool LTG_ActorEscortPlayerToGoal();
bool Enter_LTG_ActorGiveFinalBriefingToPlayer();
bool LTG_ActorGiveFinalBriefingToPlayer();
bool Enter_LTG_ThirdEyeCameraGoal();
bool LTG_ThirdEyeCameraGoal();
bool Enter_LTG_ProtectCharge();
bool LTG_ProtectCharge();
bool Enter_LTG_PatrolDeliverGoal();
bool LTG_PatrolDeliverGoal();
//mal: vehicle LTG nodes...
bool Enter_VLTG_RoamGoal();
bool VLTG_RoamGoal();
bool Enter_VLTG_GotoReviveMate();
bool VLTG_GotoReviveMate();
bool Enter_VLTG_TravelGoal();
bool VLTG_TravelGoal();
bool Enter_VLTG_RideWithMate();
bool VLTG_RideWithMate();
bool Enter_VLTG_StopVehicle();
bool VLTG_StopVehicle();
bool Enter_VLTG_CampGoal();
bool VLTG_CampGoal();
bool Enter_VLTG_DriveMCPToGoal();
bool VLTG_DriveMCPToGoal();
bool Enter_VLTG_GroundVehicleDestroyDeployable();
bool VLTG_GroundVehicleDestroyDeployable();
bool Enter_VLTG_AircraftDestroyDeployable();
bool VLTG_AircraftDestroyDeployable();
bool Enter_VLTG_TravelToGoalOrigin();
bool VLTG_TravelToGoalOrigin();
bool Enter_VLTG_DriveMCPToRouteGoal();
bool VLTG_DriveMCPToRouteGoal();
bool Enter_VLTG_HuntGoal();
bool VLTG_HuntGoal();
//mal: some NBG nodes...
bool Enter_NBG_SupplyTeammate();
bool NBG_SupplyTeammate();
bool Enter_NBG_ReviveTeammate();
bool NBG_ReviveTeammate();
bool Enter_NBG_TKReviveTeammate();
bool NBG_TKReviveTeammate();
bool Enter_NBG_CreateSpawnHost();
bool NBG_CreateSpawnHost();
bool Enter_NBG_HumiliateEnemy();
bool NBG_HumiliateEnemy();
bool Enter_NBG_Camp();
bool NBG_Camp();
bool Enter_NBG_Build();
bool NBG_Build();
bool Enter_NBG_PlantBomb();
bool NBG_PlantBomb();
bool Enter_NBG_Hack();
bool NBG_Hack();
bool Enter_NBG_StealUniform();
bool NBG_StealUniform();
bool Enter_NBG_HuntVictim();
bool NBG_HuntVictim();
bool Enter_NBG_DefuseBomb();
bool NBG_DefuseBomb();
bool Enter_NBG_GetSupplies();
bool NBG_GetSupplies();
bool Enter_NBG_BugForSupplies();
bool NBG_BugForSupplies();
bool Enter_NBG_AvoidDanger();
bool NBG_AvoidDanger();
bool Enter_NBG_PlantMine();
bool NBG_PlantMine();
bool Enter_NBG_Snipe();
bool NBG_Snipe();
bool Enter_NBG_DestroyDanger();
bool NBG_DestroyDanger();
bool Enter_NBG_FixProxyEntity();
bool NBG_FixProxyEntity();
bool Enter_NBG_DestroyMCP();
bool NBG_DestroyMCP();
bool Enter_NBG_DestroySpawnHost();
bool NBG_DestroySpawnHost();
bool Enter_NBG_GrabSpawnPoint();
bool NBG_GrabSpawnPoint();
bool Enter_NBG_FixDeployable();
bool NBG_FixDeployable();
bool Enter_NBG_PlaceDeployable();
bool NBG_PlaceDeployable();
bool Enter_NBG_DestroyAPTDanger();
bool NBG_DestroyAPTDanger();
bool Enter_NBG_GrabSpawnHost();
bool NBG_GrabSpawnHost();
bool Enter_NBG_HackDeployable();
bool NBG_HackDeployable();
bool Enter_NBG_MG_Camp();
bool NBG_MG_Camp();
bool Enter_NBG_FlyerHive();
bool NBG_FlyerHive();
bool Enter_NBG_FixGun();
bool NBG_FixGun();
bool Enter_NBG_Pause();
bool NBG_Pause();
bool Enter_NBG_EngAttackAVTNearMCP();
bool NBG_EngAttackAVTNearMCP();
bool Enter_NBG_ShieldTeammate();
bool NBG_ShieldTeammate();
bool Enter_NBG_SmokeTeammate();
bool NBG_SmokeTeammate();
//mal: some COMBAT nodes
bool Enter_COMBAT_Foot_AttackEnemy();
bool COMBAT_Foot_AttackEnemy();
bool Enter_COMBAT_Foot_ChaseEnemy();
bool COMBAT_Foot_ChaseEnemy();
bool Enter_COMBAT_Foot_RetreatFromEnemy();
bool COMBAT_Foot_RetreatFromEnemy();
bool Enter_COMBAT_Foot_EvadeEnemy();
bool COMBAT_Foot_EvadeEnemy();
bool Enter_COMBAT_Foot_LostEnemyInSmoke();
bool COMBAT_Foot_LostEnemyInSmoke();
bool Enter_COMBAT_Foot_ReviveTeammate();
bool COMBAT_Foot_ReviveTeammate();
bool Enter_COMBAT_Foot_ChaseEnemy_Grenade();
bool COMBAT_Foot_ChaseEnemy_Grenade();
bool Enter_COMBAT_Foot_ChaseEnemy_Aircan();
bool COMBAT_Foot_ChaseEnemy_Aircan();
bool Enter_COMBAT_Foot_Hide();
bool COMBAT_Foot_Hide();
bool Enter_COMBAT_Foot_ChaseUnseenEnemy();
bool COMBAT_Foot_ChaseUnseenEnemy();
bool Enter_COMBAT_Foot_GrabVehicle();
bool COMBAT_Foot_GrabVehicle();
bool Enter_COMBAT_Foot_AttackTurret();
bool COMBAT_Foot_AttackTurret();
// vehicle combat nodes
bool Enter_COMBAT_Vehicle_EvadeEnemy();
bool COMBAT_Vehicle_EvadeEnemy();
bool Enter_COMBAT_Vehicle_AttackEnemy();
bool COMBAT_Vehicle_AttackEnemy();
bool Enter_COMBAT_Vehicle_ChaseEnemy();
bool COMBAT_Vehicle_ChaseEnemy();
//mal: some COMBAT movement nodes
bool Enter_Run_And_Gun_Movement();
bool Run_And_Gun_Movement();
bool Enter_Knife_Attack_Movement();
bool Knife_Attack_Movement();
bool Enter_Stand_Ground_Attack_Movement();
bool Stand_Ground_Attack_Movement();
bool Enter_Hal_Strafe_Attack_Movement();
bool Hal_Strafe_Attak_Movement();
bool Enter_Crazy_Jump_Attack_Movement();
bool Crazy_Jump_Attack_Movement();
bool Enter_Side_Strafe_Attack_Movement();
bool Side_Strafe_Attack_Movement();
bool Enter_Crouch_Attack_Movement();
bool Enter_Prone_Attack_Movement();
bool Prone_Attack_Movement();
bool Crouch_Attack_Movement();
bool Enter_Circle_Strafe_Attack_Movement();
bool Circle_Strafe_Attack_Movement();
bool Enter_Grenade_Attack_Movement();
bool Grenade_Attack_Movement();
bool Enter_Avoid_Danger_Movement();
bool Avoid_Danger_Movement();
bool Enter_Null_Move_Attack();
bool Null_Move_Attack();
bool Enter_MoveTo_Shield_Attack_Movement();
bool MoveTo_Shield_Attack_Movement();
//mal: some vehicle COMBAT movement nodes
bool Enter_Vehicle_Stand_Ground_Movement();
bool Vehicle_Stand_Ground_Movement();
bool Enter_Vehicle_NULL_Movement(); //mal: only used by bots who are gunners/passengers in someone else's ride.
bool Vehicle_NULL_Movement();
bool Enter_Vehicle_Ram_Attack_Movement();
bool Vehicle_Ram_Attack_Movement();
bool Enter_Vehicle_Chase_Movement();
bool Vehicle_Chase_Movement();
bool Enter_Vehicle_Random_Movement();
bool Vehicle_Random_Movement();
bool Enter_Vehicle_Air_Movement();
bool Vehicle_Air_To_Air_Movement();
bool Vehicle_Air_To_Ground_Movement();
bool Buffalo_Air_To_Air_Movement();
bool Buffalo_Air_To_Ground_Movement();
// ram, stand and fight, chase, random move, etc.
//mal: combat utility functions
bool Bot_FindEnemy ( int ignoreClientNum );
bool Bot_FindBetterEnemy ();
bool ClientIsVisibleToBot ( int clientNum, bool useFOV, bool saveEnt );
bool ClientIsAudibleToBot ( int clientNum );
bool ClientObscuredBySmokeToBot ( int clientNum );
void Bot_SetAttackTimeDelay ( bool inFront ); //mal: this sets a delay on how long the bot should take to see enemy, based on bot's state.
void Bot_FindBestCombatMovement();
bool BotLeftEnemysSight(); //mal: did the bot move out of the enemies sight, or vice-versa?
void Bot_ResetEnemy();
void Bot_PickBestWeapon( bool useNades );
bool Bot_PickPostCombatGoal();
bool ClassWeaponCharged( const playerWeaponTypes_t weaponNum ); //mal: does weaponNum have enough charge to be fired this frame?
void UpdateEnemyInfo(); //mal: updates the enemy visibility info.
void UpdateNonVisEnemyInfo(); //mal: updates the enemy visibility info.
bool Bot_ThrowGrenade( const idVec3 &origin, bool fastNade );
void Bot_CheckCurrentStateForCombat();
bool Bot_ShouldChaseHiddenEnemy( bool chase );
bool Bot_CheckShouldUseGrenade( bool targetVisible );
bool Bot_CheckShouldUseAircan( bool targetVisible );
void Bot_UseCannister( const playerWeaponTypes_t weapType, const idVec3 &origin );
bool EnemyValid();
void Bot_CheckAttack(); //mal: is it OK to fire our weapon now?
int CheckClientAttacker( int clientNum, int checkTimeInSeconds ); // returns which client is attacking the client in question.
bool Bot_CanBackStabClient( int clientNum, float backStabDist = BACKSTAB_DIST );
bool ClientHasAttackedTeammate( int clientNum, bool criticalOnly, int time );
bool DisguisedKillerInArea();
bool EnemyIsIgnored( int clientNum );
void Bot_IgnoreEnemy( int clientNum, int time );
bool VehicleIsIgnored( int vehicleNum );
void Bot_IgnoreVehicle( int vehicleNum, int time );
bool ClientIsDefusingOurTeamCharge( int clientNum );
void Bot_PickChaseType();
int Bot_ShouldInvestigateNoise( int clientNum );
void Bot_SetTimeOnTarget( bool inVehicle );
void Bot_CheckForNearbyVehicleToGrab();
bool Bot_CheckEnemyHasLockOn( int clientNum, bool ignoreTargetIfRangeIsGreat = false );
bool Client_HasMultipleAttackers( int clientNum );
bool Bot_IsNearTeamGoalUnderAttack();
bool Bot_IsNearForwardSpawnToGrab();
bool DisguisedClientIsActingOdd( int clientNum );
bool ClientHasNadeInWorld( int clientNum );
bool ClientHasFireSupportInWorld( int clientNum );
bool ClientIsDangerous( int clientNum );
bool Bot_EnemyAITInArea( const idVec3& org );
bool ClientIsMarkedForDeath( int clientNum, bool clearRequest );
bool DeployableIsMarkedForDeath( int entNum, bool clearRequest );
bool Bot_CheckCovertToolState();
int Flyer_FindEnemy( float range );
bool Bot_IsUnderAttackFromUnknownEnemy();
bool Bot_CanAttackVehicles();
bool Bot_HasEnemySniperInArea( float range );
bool Bot_IsUnderAttackByAPT( idVec3& turretLocation );
bool Bot_TeammateHasClientAsEnemy( int clientNum, int& attackingClient );
bool ClientHasAttackedActorsMate( int clientNum, int time );
bool Bot_ShouldIgnoreEnemies();
bool Bot_CheckIfEnemyHasUsInTheirSightsWhenInAirVehicle();
//mal: vehicle combat/misc utility functions
int FindClosestVehicle( float range, const idVec3& org, const playerVehicleTypes_t vehicleType, int vehicleFlags, int vehicleIgnoreFlags, bool emptyOnly );
void GetVehicleInfo( int entNum, proxyInfo_t& vehicleInfo ) const;
const proxyInfo_t * GetBotVehicleInfo( int entNum ) const;
void Bot_FindDeadWhileInVehicle();
bool Bot_ShouldUseVehicleForAction( int actionNumber, bool ignoreArmor = false );
bool Bot_MeetsVehicleRequirementsForAction( int actionNumber );
bool Bot_GetIntoVehicle( int vehicleNum );
void Bot_ExitVehicle( bool ignoreMCP = true );
bool Bot_VehicleFindEnemy();
bool Bot_FindParkingSpotAoundLocaction( idVec3 &loc ); //mal: finds a parking spot near location - something the bot can move toward, without running over its goal.
bool VehicleIsValid( int entNum, bool skipSpeedCheck = false, bool addDriverCheck = false );
bool VehicleHasGunnerSeatOpen( int entNum );
bool InFrontOfVehicle( int vehicleNum, const idVec3 &org, bool precise = false, float preciseValue = 0.60f );
void Bot_CheckCurrentStateForVehicleCombat();
bool Bot_VehicleCanAttackEnemy( int clientNum );
void Bot_PickBestVehicleWeapon();
void Bot_PickBestVehiclePosition();
void Bot_CheckVehicleAttack();
bool Bot_VehicleFindBetterEnemy();
bool Bot_ShouldVehicleChaseHiddenEnemy();
bool Bot_FindBestVehicleCombatMovement();
bool Bot_VehicleCanRamClient( int clientNum );
void Bot_PickVehicleChaseType();
void Bot_ExitVehicleAINode( bool resetStack );
bool Bot_VehicleCanMove( const moveDirections_t direction, float gUnits, bool copyEndPos );
bool InAirVehicleGunSights( int vehicleNum, const idVec3 &org );
bool Bot_CheckMoveIsClear( idVec3& goalOrigin );
bool Bot_CheckVehicleNodePath( const idVec3& goalOrigin, idVec3& pathPoint, bool& resetGoal );
bool FindEntityByEntNum( int entNum, idVec3& origin, idBox& bbox );
bool Bot_IsInHeavyAttackVehicle( bool ignoreGroundVehicles = false );
int Bot_VehicleIsUnderAVTAttack();
bool Bot_CheckHumanRequestingTransport();
bool Bot_CheckIfClientHasRideWaiting( int clientNum );
void IcarusCombatMove();
bool ClientIsAudibleToVehicle( int clientNum );
bool HumanVehicleOwnerNearby( const playerTeamTypes_t playerTeam, const idVec3 &loc, float range, int vehicleSpawnID );
bool Bot_CheckFriendlyEngineerIsNearbyOurVehicle();
bool Bot_CheckForHumanNearByWhoMayWantRide();
int Bot_GetVehicleGunnerClientNum( int vehicleEntNum );
bool VehicleGoalsExistForVehicle( const proxyInfo_t& vehicleInfo );
bool Bot_WithObjShouldLeaveVehicle();
int Bot_CheckForDeployableTargetsWhileVehicleGunner();
void Bot_AttackDeployableTargetsWhileVehicleGunner( int deployableTargetToKill );
bool Bot_WhoIsCriticalForCurrentObjShouldLeaveVehicle();
//mal: misc utility functions
void UpdateBotsInformation( const playerClassTypes_t playerClass, const playerTeamTypes_t playerTeam, bool botInit );
void BotAI_ResetUcmd();
bool BotAI_CheckThinkState();
void ClearBotState();
void Bot_ResetState( bool resetEnemy, bool resetStack );
void InitAAS(); //mal: setup the aas for this bot
void Bot_IgnoreClient( int clientNum, int time );
void Bot_IgnoreAction( int actionNumber, int time );
bool Bot_RandomLook( idVec3 &position, bool ignoreDelay = false ); //mal: picks a random position for the bot to look towards
void Bot_ExitAINode();
bool Bot_NBGIsAvailable( int clientNum, int actionNumber, const bot_NBG_Types_t goalType, int &busyClient );
bool Bot_LTGIsAvailable( int clientNum, int actionNumber, const bot_LTG_Types_t goalType, int minNumClients );
int Bot_NumClientsDoingLTGGoal( int clientNum, int actionNumber, const bot_LTG_Types_t goalType, idList< int >& busyClients );
void Bot_Input(); //mal: sends the bots current user cmds to the game thread.
void Bot_LookAtLocation( const idVec3 &spot, const botTurnTypes_t turnType, bool useOriginOnly = false ); // where the bot wants to look
void Bot_LookAtEntity( int entityNum, const botTurnTypes_t turnType ); // what the bot wants to look at
void Bot_LookAtNothing( const botTurnTypes_t turnType); // just look straight ahead
int ClientsInArea( int ignoreClientNum, const idVec3 &org, float range, int team, const playerClassTypes_t clientClass, bool inFront, bool vis2Sky, bool ignoreInvulnerable, bool ignoreDisguised, bool ignoreInVehicle, bool humanOnly = false ); //looks for clients of a specific team, possibly infront of client[ clientNum ].
int VehiclesInArea( int ignoreClientNum, const idVec3 &org, float range, int team, bool vis2Sky, int ignoreVehicleNum, bool humanOnly = false ); //looks for vehicles in an area
bool InFrontOfClient( int clientNum, const idVec3 &origin, bool precise = false, float preciseValue = 0.80f ); //mal: is this location infront of the bot?
void Bot_ClearAngleMods();
void CheckBotStuckState();
void ResetRandomLook() { randomLookRange = 900.0f; randomLookOrg = vec3_zero; randomLookDelay = 0; }
void Bot_CheckWeapon();
void BotAI_UpdateStateInfo();
bool Bot_CheckHasVisibleMedicNearby();
bool LocationVis2Sky( const idVec3 &loc );
void ResetBotsAI( bool critical );
bool ClientIsValid( int clientNum, int spawnID );
bool ClientIsIgnored( int clientNum );
bool BodyIsIgnored( int bodyNum );
bool SpawnHostIsIgnored( int bodyNum );
void Bot_IgnoreBody( int bodyNum, int time );
void Bot_IgnoreSpawnHost( int bodyNum, int time );
bool ActionIsIgnored( int actionNumber );
bool ItemIsIgnored( int itemNumber );
void Bot_IgnoreItem( int itemNumber, int time );
bool ClientHasChargeInWorld( int clientNum, bool armedOnly, int actionNumber, bool unArmedOnly = false );
bool FindChargeInWorld( int actionNumber, plantedChargeInfo_t &bombInfo, bool chargeState, bool ignoreZCheck = false );
bool CheckItemPackIsValid( int entNum, idVec3 &packOrg, idBounds &entBounds, int& spawnID );
void Bot_AddDelayedChat( int botClientNum, const botChatTypes_t chatType, int delayTimeInSecs, bool forceChat = false );
void Bot_CheckDelayedChats();
bool Client_IsCriticalForCurrentObj( int clientNum, float range );
int FindBodyOfClient( int clientNum, bool stealUniform, const idVec3 &org );
float LocationDistFromCurrentObj( const playerTeamTypes_t team, const idVec3 &org );
bool Bot_IsAwareOfDanger( int entNum, const idVec3 &org, const idMat3& dir );
int AddDangerToAwareList( int entNum, const idVec3 &org, const dangerTypes_t dangerType, int time, int ownerClientNum, const idMat3& dir = mat3_identity );
void Bot_CheckForDangers( bool inCombat );
void FindMineInWorld( plantedMineInfo_t &mineInfo );
int NumPlayerMines();
bool DangerStillExists( int entNum, int ownerClientNum );
bool Bot_HasExplosives( bool inCombat, bool makeSureSoldierWeaponReady = false );
void Bot_RunTacticalAction();
bool TeamHasHuman( const playerTeamTypes_t playerTeam );
bool NeedsReload();
int FindClosestDangerIndex();
void ClearDangerFromDangerList( int dangerIndex, bool isEntNum );
bool TeamHumanNearLocation( const playerTeamTypes_t playerTeam, const idVec3 &loc, float range, bool ignorePlayersInVehicle = true, const playerClassTypes_t playerClass = NOCLASS, bool ignoreDeadMates = true, bool ignoreIfJustLeftAVehicle = false );
bool ClientHasVehicleInWorld( int clientNum, float range );
bool BodyIsObstructed( int entNum, bool isCorpse, bool isSpawnHost = false );
int Bot_ApproxTravelTimeToLocation( const idVec3 & from, const idVec3 &to, bool inVehicle ) const;
bool ClientIsDead( int clientNum );
bool ClientCanBeTKRevived( int clientNum );
bool DeployableIsIgnored( int deployableNum );
void Bot_IgnoreDeployable( int deployableNum, int time );
bool GetDeployableInfo( bool selfDeployable, int entNum, deployableInfo_t& deployableInfo );
bool DeployableAtAction( int actionNumber, bool checkOwnDeployable );
bool Bot_HasWorkingDeployable( bool allowDisabledDeployables = false, int deployableType = NULL_DEPLOYABLE );
bool FindMCPStartAction( idVec3& origin );
int Bot_GetDeployableTypeForAction( int actionNumber );
bool Bot_CheckTeamHasDeployableTypeNearAction( const playerTeamTypes_t playerTeam, int deployableType, int actionNumber, float dist );
bool Bot_CheckTeamHasDeployableTypeNearLocation( const playerTeamTypes_t playerTeam, int deployableType, const idVec3& location, float dist );
bool PointIsClearOfTeammates( const idVec3& point );
bool EntityIsClient( int entNum, bool enemyOnly );
bool EntityIsVehicle( int entNum, bool enemyOnly, bool occupiedOnly );
bool EntityIsDeployable( int entNum, bool enemyOnly );
bool SpawnHostIsUsed( int entNum );
bool TeamMineInArea( const idVec3& org, float range );
bool Bot_CheckActionIsValid( int actionNumber );
const entityTypes_t FindEntityType( int entNum, int spawnID );
bool VehicleIsMarkedForRepair( int entNum, bool clearRequest );
bool DeployableIsMarkedForRepair( int entNum, bool clearRequest );
bool Bot_CheckAdrenaline( const idVec3& goalOrigin );
void Flyer_LookAtLocation( const idVec3 &spot );
bool CurrentActionIsLinkedToAction( int curActionNum, int testActionNum );
void FindLinkedActionsForAction( int testActionNum, idList< int >& testActionList, idList< int >& linkedActionList );
bool Bot_CheckLocationIsOnSameSideOfSlipGate( const idVec3& origin );
bool Bot_CheckLocationIsVisible( const idVec3& location, int scanEntityNum = -1, int ignoreEntNum = -1, bool scanFromCrouch = false );
bool Bot_CheckHasUnArmedMineNearby();
void Bot_CheckMountedGPMGState();
bool Bot_CheckIfClientHasChargeAsGoal( int chargeEntNum );
bool Bot_IsClearOfObstacle( const idBox& box, const float bboxHeight, const idVec3& botOrigin );
bool OtherBotsWantVehicle( const proxyInfo_t& vehicle );
idVec3 GetPlayerViewPosition( int clientNum );
float Bot_GetDeployableOffSet( int deployableType );
int Bot_FindNearbySafeActionToMoveToward( const idVec3& origin, float minAvoidDist, bool pickRandom = false );
bool ClientHasShieldInWorld( int clientNum, float considerRange );
float Bot_DistSqrToClosestForceShield( idVec3& shieldOrg );
bool Bot_UseTeleporter();
bool Bot_UseRepairDrone( int entNum, const idVec3& entOrg );
int Bot_FindClosestAVTDanger( const idVec3& location, float range, bool useAngleCheck = false );
bool SpawnHostIsMarkedForDeath( int spawnHostSpawnID );
int Bot_GetRequestedEscortClient();
bool Bot_CheckForHumanInteractingWithEntity( int entNum );
int Bot_HasTeammateWhoCouldUseShieldCoverNearby();
bool ClientHasCloseShieldNearby( int clientNum, float considerRange );
const playerClassTypes_t TeamCriticalClass( const playerTeamTypes_t playerTeam );
int FindHumanOnTeam( const playerTeamTypes_t playerTeam );
void Bot_CheckHealthCrateState();
bool Bot_CheckIfHealthCrateInArea( float range );
bool FindChargeBySpawnID( int spawnID, plantedChargeInfo_t& bombInfo );
int Bot_NumShieldsInWorld();
bool Bot_CheckChargeExistsOnObjInWorld();
bool GetDeployableAtAction( int actionNum, deployableInfo_t& deployable );
//mal: movement utilities
void Bot_MoveToGoal( const idVec3 &spot1, const idVec3 &spot2, const botMoveFlags_t moveFlag, const botMoveTypes_t moveType );
bool Run_OnFoot_Movement();
bool Bot_CanMove( const moveDirections_t direction, float gUnits, bool copyEndPos, bool endPosMustBeOutside = false ); //mal: checks "direction" out the number of "units" to see if a move is possible
void Bot_SetupMove( const idVec3 &org, int clientNum, int actionNumber, int areaNum = 0 );
void Bot_SetupVehicleMove( const idVec3 &org, int clientNum, int actionNumber, bool ignoreNodes = false );
bool Bot_CanProne( int clientNum ); //mal: checks to see if bot can prone in its current location, and still be able to see clientNum.
bool Bot_CanCrouch( int clientNum ); //mal: checks to see if bot can crouch in currect loc, and still see clientNum
const botMoveFlags_t Bot_ShouldStrafeJump( const idVec3 &targetOrigin );
bool MoveIsInvalid();
int Bot_CheckBlockingOtherClients( int ignoreClient, float avoidDist = 50.0f );
void Bot_MoveAwayFromClient( int clientNum, bool randomStrafe = false );
bool AddGroundObstacles( bool largePlayerBBox, bool inVehicle );
bool AddGroundAndAirObstacles( bool largePlayerBBox, bool inVehicle, bool inAirVehicle );
bool BuildObstacleList( bool largePlayerBBox, bool inVehicle );
void Bot_SetupQuickMove( const idVec3 &org, bool largePlayerBBox );
void Bot_SetupVehicleQuickMove( const idVec3 &org, bool largePlayerBBox );
const botMoveFlags_t Bot_FindStanceForLocation( const idVec3 &org, bool allowProne );
void Bot_FindRouteToCurrentGoal();
void Bot_FindNextRouteToGoal();
bool Bot_ReachedCurrentRouteNode();
void Bot_MoveAlongPath( botMoveFlags_t defaultMoveFlags ); // helper function used by all the LTG nodes
const moveDirections_t Bot_DirectionToLocation( const idVec3& location, bool precise );
bool LocationHasHeadRoom( const idVec3 &loc );
bool Bot_LocationIsReachable( bool inVehicle, const idVec3& loc, int& travelTime );
void Bot_SetupIcarusMove( const idVec3 &org, int clientNum, int actionNumber );
void Bot_SetupFlyerMove( idVec3& goalOrigin, int areaNum );
void FlyerHive_BuildPlayerObstacleList();
int TravelFlagForTeam() const;
int TravelFlagWalkForTeam() const;
int TravelFlagInvalidForTeam() const;
bool LocationIsReachable( bool inVehicle, const idVec3& loc1, const idVec3& loc2, int& travelTime );
bool Bot_CheckIfObstacleInArea( float minAvoidDist );
//mal: goal related utilities
int Bot_MedicCheckForWoundedMate( int healClientNum, int escortClientNum, float range, int mateHealth );
int Bot_MedicCheckForDeadMate( int reviveClientNum, int escortClientNum, float range );
int Bot_StroggCheckForGDFBodies( float range );
bool Bot_CheckCombatExceptions();
int Bot_MedicCheckForDeadMateDuringCombat( const idVec3 &dangerOrg, float range );
bool Bot_MedicCheckNBGState_InCombat();
bool Bot_MedicCheckNBGState_InLTG();
bool Bot_MedicCheckNBGState_InNBG();
bool Bot_CovertOpsCheckNBGState();
bool Bot_Check_NBG_Goals();
void Bot_FindLongTermGoal(); //mal: finds the bot a LTG in life - called on every spawn/revive/completion of previous goal.
bool Bot_CheckSelfState();
void Bot_CheckClassState();
bool Bot_CheckSelfSupply();
bool Bot_IsBusy(); //mal: lets me quickly know if bot is running important LTG/NBG and cant be buggered!
bool PopAINodeOffStack();
void Bot_ClearVehicleOffAIStack();
void PushAINodeOntoStack( int clientNum, int entNum, int actionNumber, int timeLimit, bool isPriority, bool useVehicle, bool useRoute = false );
void Bot_ClearAIStack(); //mal: clears the AI stack
bool Bot_CheckForTeamGoals();
bool Bot_CheckMapScripts();
bool Bot_CheckForFallBackGoals();
bool Bot_CheckForVehicleFallBackGoals();
bool ClientHasObj( int clientNum );
int Bot_CovertCheckForUniforms( float range );
int Bot_CovertCheckForVictims( float range );
bool Bot_FindCloseSupplyPack( bool healthOnly, bool grenadesOnly );
bool Bot_FindCloseSupplyTeammate( bool buggerForHealth );
bool Bot_FopsCheckNBGState();
int Bot_CheckForNeedyTeammates( float range );
bool Bot_CheckForSoldierGoals();
bool Bot_CheckForEngineerGoals();
bool Bot_CheckForCovertGoals();
bool Bot_CheckForEscortGoals();
bool Bot_CheckForFieldOpsGoals();
int Bot_CheckForTacticalAction();
int Bot_CheckForNeedyVehicles( float range, bool& chatRequest );
bool Bot_EngCheckNBGState();
int Bot_CheckForSpawnHostsToDestroy( float range, bool& useChat );
bool ObjIsOnGround();
bool Bot_CheckForDroppedObjGoals();
int Bot_CheckForNeedyDeployables( float range );
bool Bot_CheckForSpawnHostToGrab();
bool Bot_HasTeamWoundedInArea( bool deadOnly, float medicRange = MEDIC_RANGE );
bool Bot_CheckForHumanWantingEscort();
int Bot_HasDeployableTargetGoals( bool hackDeployable );
bool ClientsNearObj( const playerTeamTypes_t& playerTeam );
bool CriticalEnemyClientNearUs( const playerClassTypes_t& playerClass );
bool Bot_CheckNeedClientsOnDefense();
bool Bot_IsInvestigatingTeamObj();
bool Bot_VehicleLTGIsAvailable( int clientNum, int actionNumber, const bot_Vehicle_LTG_Types_t goalType, int minNumClients );
bool Bot_IsAttackingDeployables();
bool Bot_CheckMCPGoals();
bool Bot_IsNearDroppedObj();
bool Bot_WantsVehicle();
bool ClientIsCloseToDeliverObj( int clientNum, float desiredRange = -1.0f );
int Bot_CheckForGrieferTargetGoals();
bool ActionIsActiveForTrainingMode( int actionNumber, int numSecondsToDelay );
bool TeamHumanMissionIsObjective();
int Bot_CheckForNearbyTeammateWhoCouldUseSmoke();
bool Bot_CheckThereIsHeavyVehicleInUseAlready();
bool Bot_HasShieldInWorldNearLocation( const idVec3& checkOrg, float checkDist );
bool CarrierInWorld();
bool Bot_IsDefendingTeamCharge();
//mal: debug utilities
void SetupDebugHud();
void RunDebugChecks();
idBotAI * nextRemoved;
idObstacleAvoidance obstacles;
private:
const clientInfo_t * botInfo;
const sharedWorldState_t* botWorld;
const proxyInfo_t * botVehicleInfo;
botAIOutput_t * botUcmd;
bool CallFuncPtr( bool ( idBotAI::*funcPtr )() ) { assert( funcPtr != NULL ); return ( this->*funcPtr )(); }
//mal: AI node pointers
bool ( idBotAI::*LTG_CHECK_FOR_CLASS_NBG )(); //mal: this is class/team specific sub goal check, while in process of long term goal
bool ( idBotAI::*NBG_CHECK_FOR_CLASS_NBG )(); //mal: is sub goal check while in process of short term goals
bool ( idBotAI::*COMBAT_MOVEMENT_STATE )(); //mal: the current move state of the bot (on foot, in vehicle (and type), etc.
bool ( idBotAI::*ROOT_AI_NODE )();
bool ( idBotAI::*V_ROOT_AI_NODE )();
bool ( idBotAI::*NBG_AI_SUB_NODE )();
bool ( idBotAI::*LTG_AI_SUB_NODE )();
bool ( idBotAI::*V_LTG_AI_SUB_NODE )();
bool ( idBotAI::*COMBAT_AI_SUB_NODE )();
bool ( idBotAI::*VEHICLE_COMBAT_AI_SUB_NODE )();
bool ( idBotAI::*VEHICLE_COMBAT_MOVEMENT_STATE )(); //mal: the current move state of the bot (on foot, in vehicle (and type), etc.
struct botAAS_t {
bool hasPath;
bool hasClearPath;
bool hasReachedVehicleNodeGoal;
bool triedToMoveThisFrame;
int obstacleNum;
int aasType;
int blockedByObstacleCounterOnFoot;
int blockedByObstacleCounterInVehicle;
idAASPath path;
idAAS * aas; // pointer to the AAS used by this AI
};
botAAS_t botAAS;
idList< idBotNode::botLink_t > botVehiclePathList;
botChats_t delayedChats[ MAX_DELAYED_CHATS ];
int botNum; //mal: lets me track which client slot this bot has.
int botExitTime;
genericNumTimeList_t ignoreClients[ MAX_IGNORE_ENTITIES ];
genericNumTimeList_t ignoreVehicles[ MAX_IGNORE_ENTITIES ];
genericNumTimeList_t ignoreDeployables[ MAX_IGNORE_ENTITIES ];
genericNumTimeList_t ignoreEnemies[ MAX_IGNORE_ENTITIES ];
genericNumTimeList_t ignoreBodies[ MAX_IGNORE_ENTITIES ];
genericNumTimeList_t ignoreSpawnHosts[ MAX_IGNORE_ENTITIES ];
genericNumTimeList_t ignoreActions[ MAX_IGNORE_ENTITIES ];
genericNumTimeList_t ignoreItems[ MAX_IGNORE_ENTITIES ];
dangerList_t currentDangers[ MAX_DANGERS ];
dangerList_t currentArtyDanger; //mal: only track one at a time.
int actionNumInsideDanger;
int ignoreDangersTime;
bot_AI_States_t aiState; //mal: a var to track the bots current overall AI State
idVec3 botCanMoveGoal; //mal: a test location, set by Bot_CanMove - use if desired.
idVec3 botBackStabMoveGoal; //mal: a test location, set by Bot_CanMove - use if desired.
int actionNum; //mal: the action that is our current goal
int lastActionNum; //mal: the last action we were doing
int lastCheckActionTime; //mal: last time we checked an action for some event.
int tacticalActionNum;
int tacticalActionTime;
int tacticalActionTimer;
int tacticalActionTimer2;
idVec3 tacticalActionOrigin;
int tacticalDeviceCharge;
int tacticalActionIgnoreTime;
int tacticalActionPauseTime;
// Long Term Goal Stuff
bot_LTG_Types_t ltgType; //mal: what kind of LTG....
int ltgTarget; //mal: the entity that is our LTG goal, if exists!
int ltgTargetSpawnID;
int ltgTime; //mal: how long we should persue this goal.
bool ltgReached; //mal: tracks goal progress
bool ltgReachedTarget;
bool ltgUseVehicle;
bool ltgChat;
bool ltgExit;
int ltgTimer;
targetTypes_t ltgTargetType; //mal: the type of target, for special cases.
float ltgDist;
int ltgPauseTime;
botMoveFlags_t ltgPosture; //mal: some actions can have a random amount of postures, track which the bot picked here.
idVec3 ltgOrigin;
moveDirections_t ltgMoveDir;
int ltgCounter;
int ltgMoveTime;
int ltgTryMoveCounter;
bool ltgUseShield;
bool ltgUseSmoke;
bool ltgUseMine;
// Vehicle Long Term Goal Stuff
bot_Vehicle_LTG_Types_t vLTGType; //mal: what kind of vehicle LTG....
int vLTGTarget; //mal: the entity that is our vehicle LTG goal, if exists!
int vLTGTargetSpawnID;
int vLTGTime; //mal: how long we should persue this goal.
bool vLTGReached; //mal: tracks goal progress
bool vLTGExit;
int vLTGTimer;
int vLTGMoveTimer;
int vLTGVisTimer;
int vLTGTimer2;
targetTypes_t vLTGTargetType; //mal: the type of target, for special cases.
float vLTGDist;
float vLTGMoveTooCloseRange;
idVec3 vLTGOrigin;
moveDirections_t vLTGMoveDir;
int vLTGMoveTime;
int vLTGSightTime;
int vLTGDriveTime;
int vLTGPauseTime;
int vLTGMoveActionGoal;
bool vLTGChat;
float vLTGDistFoundDeployable;
bool vLTGUseAltAttackPointOnDeployable;
int vLTGAttackDeployableCounter;
int vLTGKeepMovingTime;
int vLTGDeployableTarget;
int vLTGDeployableTargetAttackTime;
// Short Term Goal Stuff
bot_NBG_Types_t nbgType; //mal: ... and NBG we have currently
int nbgTarget; //mal: the entity that is our NBG goal, if exists!
int nbgTargetSpawnID;
int nbgTime; //mal: how long we should do this goal.
bool nbgReached; //mal: tracks goal progress
bool nbgReachedTarget;
bool nbgExit;
bool nbgSwitch;
int nbgClientNum;
int nbgTimer; //mal: can be used to time certain things
int nbgTimer2;
int nbgMoveTimer;
int nbgTryMoveCounter;
int nbgMoveTime;
targetTypes_t nbgTargetType; //mal: what type of target this is, for special cases.
float nbgDist;
idVec3 nbgOrigin;
botMoveFlags_t nbgPosture; //mal: some actions can have a random amount of postures, track which the bot picked here.
botMoveTypes_t nbgMoveType;
moveDirections_t nbgMoveDir;
bool nbgChat;
// Combat Goal Stuff
int combatNBGTarget; //mal: the entity that is our NBG goal, if exists!
int combatNBGTime; //mal: how long we should do this goal.
int combatTryMoveCounter;
int combatTryMoveTime;
bool combatNBGReached; //mal: tracks goal progress
bool combatDangerExists;
bot_COMBAT_Types_t combatNBGType;
botMoveFlags_t combatMoveFlag;
int botIsBlocked;
int vehicleWheelsAreOffGroundCounter;
int botIsBlockedTime;
//mal: enemy stuff
idVec3 bot_FS_Enemy_Pos; // FS = First Seen - where the bot was when he first saw the enemy
idVec3 bot_LS_Enemy_Pos; // LS = Last Seen - where the bot was when he last saw the enemy
int numVisEnemies; //mal: how many visible enemies FindEnemy found this frame - useful for tactical thinking
int enemy; //mal: the entity that is the bot's current enemy.
int enemySpawnID;
int enemyAcquireTime;
int heardClient; //mal: a client we're aware of because we heard them, but we haven't seen yet.
moveDirections_t combatMoveDir;
botAttackMoveTypes_t combatMoveType;
int combatMoveTime; //mal: how long to move this direction
int combatMoveFailedCount; //mal: how many times the bot has tried a move that failed.
int combatMoveActionGoal;
float combatMoveTooCloseRange;
int combatKeepMovingTime;
int gunTargetEntNum; // the ent, if exists, thats in front of us ATM.
int shotIsBlockedCounter;
bool hammerVehicle;
bool hammerTime;
idVec3 hammerLocation;
int hammerClient;
bool resetEnemy;
bool turretDangerExists;
int turretDangerEntNum;
int classAbilityDelay; // how long we should wait before use class ability
struct enemyInfo_t {
bool enemyVisible;
bool enemyFacingBot;
bool enemyInfont;
int enemyLastVisTime; // when this enemy was last visible.
int enemyHeight; // how far above/below the bot this enemy is.
float enemyDist;
idVec3 enemy_FS_Pos; // FS = First Seen - where the enemy was when the bot first saw him
idVec3 enemy_LS_Pos; // LS = Last Seen - where the enemy was when the bot last saw him
idVec3 enemy_NS_Pos; // NS = Not Seen - one location bot could use to chase enemies in complicated map areas
};
enemyInfo_t enemyInfo;
bool ignoreWeapChange;
bool lefty;
int botTeleporterAttempts;
idBotRoutes* routeNode;
idBotNode* vehicleNode;
playerWeaponTypes_t botIdealWeapNum; // the specific weapon the bot wants to use.
weaponBankTypes_t botIdealWeapSlot; //mal: tracks which weapon bank the bot wants to switch to.
int lastGrenadeTime;
bool safeGrenade;
bool chaseEnemy; // should the bot really chase this enemy around - otherwise will give up once reach place enemy last seen.
int timeTilAttackEnemy; //mal: allows me to set a delay in how long from when a bot sees and enemy, til he attacks.
bool useNadeOnEnemy; // does this bot want to use a nade on its enemy?
bool useAircanOnEnemy;
int vehicleGunnerTime;
int vehicleDriverTime;
int vehicleUpdateTime;
int rocketTime;
int crateGoodTime;
int ignoreNewEnemiesTime;
int ignoreNewEnemiesWhileInVehicleTime;
int timeOnTarget; // the time the bot should wait untill it attacks the target.
int weapSwitchTime;
int reachedPatrolPointTime;
int rocketLauncherLockFailedTime;
int lastVehicleSpawnID;
int lastVehicleTime;
int lastNearbySafeActionToMoveTowardActionNum;
struct bot_AI_Stack_t {
bool ( idBotAI::*STACK_AI_NODE )(); //mal: node to run when get back to stack
bool ( idBotAI::*VEHICLE_STACK_AI_NODE )(); //mal: vehicle node to run when get back to stack
bool isPriority; //mal: if true - we should do a combat evade, if its combat that makes us stack our goal.
bool useVehicle; //mal: if true - bot will find a vehicle to reach this goal.
int stackClientNum; //mal: client to target, if exists
int stackClientSpawnID; //mal: make sure we grab the right client, incase he disconnected, etc.
int stackEntNum; //mal: entity to target, if exists
int stackTimeLimit; //mal: time to do target, if exists
int stackActionNum; //mal: the action the bot was doing, if exists.
idBotRoutes* routeNode;
bot_Vehicle_LTG_Types_t vehicleStackLTGType;
bot_LTG_Types_t stackLTGType;
};
int framesStuck;
int noAASCounter;
int overallFramesStuck;
int vehicleFramesStuck;
bool enemyIsHuntGoal;
struct vehicleAINodeSwitch_t {
int nodeSwitchCount;
int nodeSwitchTime;
};
vehicleAINodeSwitch_t vehicleAINodeSwitch;
struct moveErrorCounter_t {
int moveErrorCount;
int moveErrorTime;
};
moveErrorCounter_t moveErrorCounter;
int ignoreSpyTime;
int framesVehicleStuck;
int blockingTeammateCounter;
int chaseEnemyTime;
int fdaUpdateTime;
int framesFlipped;
int bugForSuppliesDelay;
int ignorePlantedChargeTime;
bool vehicleEnemyWasInheritedFromFootCombat;
bool ignoreMCPRouteAction;
bool stayInPosition;
bool weaponLocked;
bool chasingEnemy;
bool hasGreetedServer;
float randomLookRange;
int botWantsVehicleBackTime;
int checkRoadKillTime;
int vehicleObstacleSpawnID;
int vehicleObstacleTime;
bool isStrafeJumping;
bool isBoosting;
int vehiclePauseTime;
int vehicleReverseTime;
int nextObjChargeCheckTime;
int vehicleSurrenderTime;
bool vehicleSurrenderChatSent;
int vehicleSurrenderClient;
int vehicleCheckForPossibleHumanPassengerChatTime;
int nextMissionUpdateTime;
int botPathFailedCounter;
bool fastAwareness;
int skipStrafeJumpTime; //mal: how long we should ignore the strafe jump check
int badMoveTime;
bool testFireShot;
int ignoreNadeTime; //mal: sometimes the bot won't use his grenade in combat, just to mix it up a bit.
int supplySelfTime; //mal: prevents the bots from trying to supply self, and stop doing it because it has no charge.
int randomLookDelay; //mal: a minimum time to ignore randomLook calls, so that the bots dont swivel around like maniacs.
int pistolTime; //mal: how long the bot should have the pistol out.
idVec3 randomLookOrg; //mal: keep track of where we've been looking, in case we need to look somewhere else...
idVec3 hopMoveGoal;
int stuckRandomMoveTime;
bool wantsVehicle;
int ignoreIcarusTime;
int selfShockTime;
int nodeTimeOut;
int newPathTime;
int strafeToAvoidDangerTime;
moveDirections_t strafeToAvoidDangerDir;
int warmupActionMoveGoal;
int warmupUseActionMoveGoalTime;
struct ignoreNodeTimer_t {
idBotNode* ignorePathNode;
int ignorePathNodeTime;
int ignorePathNodeUpdateTime;
};
ignoreNodeTimer_t pathNodeTimer;
bot_AI_Stack_t AIStack; //mal: only important AI nodes will be put on the stack, so that the bots can resume them after doing a NBG/COMBAT
char *lastAINode;
char *lastMoveNode;
#ifdef _DEBUG
int debugVar1;
int debugVar2;
#endif
};
idEntity *GetGameEntity( int entityNumber );
#endif /* !__BOTAI_H__ */