virtualintTakeDamage(entvars_t*pevInflictor,entvars_t*pevAttacker,floatflDamage,intbitsDamageType);// invoked when injured by something (EXTEND) - returns the amount of damage inflicted
virtualvoidKilled(entvars_t*pevAttacker,intiGib);// invoked when killed (EXTEND)
virtualvoidRoundRespawn();
virtualvoidBlind(floatduration,floatholdTime,floatfadeTime,intalpha=255);// player blinded by a flashbang
virtualvoidOnTouchingWeapon(CWeaponBox*box);// invoked when in contact with a CWeaponBox
virtualboolInitialize(constBotProfile*profile);// (EXTEND) prepare bot for action
virtualvoidSpawnBot();// (EXTEND) spawn the bot into the game
virtualvoidUpdate();// heavyweight algorithms, invoked less often
virtualvoidWalk();
virtualboolJump(boolmustJump=false);// returns true if jump was started
virtualvoidOnEvent(GameEventTypeevent,CBaseEntity*entity=NULL,CBaseEntity*other=NULL);// invoked when event occurs in the game (some events have NULL entity)
#define CHECK_FOV true
virtualboolIsVisible(Vector*pos,booltestFOV=false)const;// return true if we can see the point
virtualboolIsVisible(CBasePlayer*player,booltestFOV=false,unsignedchar*visParts=NULL)const;// return true if we can see any part of the player
virtualboolIsEnemyPartVisible(VisiblePartTypepart)const;// if enemy is visible, return the part we see for our current enemy
public:
voidDisconnect();
// behavior properties
floatGetCombatRange()const;
boolIsRogue()const;// return true if we dont listen to teammates or pursue scenario goals
voidSetRogue(boolrogue);
boolIsHurrying()const;// return true if we are in a hurry
voidHurry(floatduration);// force bot to hurry
boolIsSafe()const;// return true if we are in a safe region
boolIsWellPastSafe()const;// return true if it is well past the early, "safe", part of the round
boolIsEndOfSafeTime()const;// return true if we were in the safe time last update, but not now
floatGetSafeTimeRemaining()const;// return the amount of "safe time" we have left
floatGetSafeTime()const;// return what we think the total "safe time" for this map is
NOXREFboolIsUnhealthy()const;// returns true if bot is low on health
// behaviors
voidIdle();
voidHide(CNavArea*searchFromArea=NULL,floatduration=-1.0f,floathideRange=750.0f,boolholdPosition=false);// DEPRECATED: Use TryToHide() instead
#define USE_NEAREST true
boolTryToHide(CNavArea*searchFromArea=NULL,floatduration=-1.0f,floathideRange=750.0f,boolholdPosition=false,booluseNearest=false);// try to hide nearby, return false if cannot
voidHide(constVector*hidingSpot,floatduration=-1.0f,boolholdPosition=false);// move to the given hiding place
boolIsHiding()const;// returns true if bot is currently hiding
boolIsAtHidingSpot()const;// return true if we are hiding and at our hiding spot
boolTryToRetreat();// retreat to a nearby hiding spot, away from enemies
voidHunt();
boolIsHunting()const;// returns true if bot is currently hunting
voidAttack(CBasePlayer*victim);
voidFireWeaponAtEnemy();// fire our active weapon towards our current enemy
voidStopAttacking();
boolIsAttacking()const;// returns true if bot is currently engaging a target
voidMoveTo(constVector*pos,RouteTyperoute=SAFEST_ROUTE);// move to potentially distant position
boolIsMovingTo()const;// return true if we are in the MoveTo state
voidPlantBomb();
voidFetchBomb();// bomb has been dropped - go get it
boolNoticeLooseBomb()const;// return true if we noticed the bomb on the ground or on radar
boolCanSeeLooseBomb()const;// return true if we directly see the loose bomb
boolIsCarryingBomb()const;
voidDefuseBomb();
boolIsDefusingBomb()const;// returns true if bot is currently defusing the bomb
boolCanSeePlantedBomb()const;// return true if we directly see the planted bomb
voidEscapeFromBomb();
boolIsEscapingFromBomb()const;// return true if we are escaping from the bomb
voidRescueHostages();
voidUseEntity(CBaseEntity*entity);// use the entity
boolIsBuying()const;
voidPanic(CBasePlayer*enemy);// look around in panic
voidFollow(CBasePlayer*player);// begin following given Player
voidContinueFollowing();// continue following our leader after finishing what we were doing
voidStopFollowing();// stop following
boolIsFollowing()const;// return true if we are following someone (not necessarily in the follow state)
CBasePlayer*GetFollowLeader();// return the leader we are following
floatGetFollowDuration()const;// return how long we've been following our leader
boolCanAutoFollow()const;// return true if we can auto-follow
boolIsNotMoving()const;// return true if we are currently standing still
voidAimAtEnemy();// point our weapon towards our enemy
voidStopAiming();// stop aiming at enemy
boolIsAimingAtEnemy()const;// returns true if we are trying to aim at an enemy
boolIsSurprised()const;// return true if we are "surprised"
floatGetSurpriseDelay()const;
voidClearSurpriseDelay();
floatGetStateTimestamp()const;// get time current state was entered
boolIsDoingScenario()const;// return true if we will do scenario-related tasks
// scenario / gamestate
CSGameState*GetGameState();// return an interface to this bot's gamestate
constCSGameState*GetGameState()const;// return an interface to this bot's gamestate
boolIsAtBombsite();// return true if we are in a bomb planting zone
boolGuardRandomZone(floatrange=500.0f);// pick a random zone and hide near it
boolIsBusy()const;// return true if we are busy doing something important
// high-level tasks
enumTaskType
{
SEEK_AND_DESTROY,
PLANT_BOMB,
FIND_TICKING_BOMB,
DEFUSE_BOMB,
GUARD_TICKING_BOMB,
GUARD_BOMB_DEFUSER,
GUARD_LOOSE_BOMB,
GUARD_BOMB_ZONE,
ESCAPE_FROM_BOMB,
HOLD_POSITION,
FOLLOW,
VIP_ESCAPE,
GUARD_VIP_ESCAPE_ZONE,
COLLECT_HOSTAGES,
RESCUE_HOSTAGES,
GUARD_HOSTAGES,
GUARD_HOSTAGE_RESCUE_ZONE,
MOVE_TO_LAST_KNOWN_ENEMY_POSITION,
MOVE_TO_SNIPER_SPOT,
SNIPING,
NUM_TASKS
};
voidSetTask(TaskTypetask,CBaseEntity*entity=NULL);// set our current "task"
TaskTypeGetTask()const;
CBaseEntity*GetTaskEntity();
// behavior modifiers
enumDispositionType
{
ENGAGE_AND_INVESTIGATE,// engage enemies on sight and investigate enemy noises
OPPORTUNITY_FIRE,// engage enemies on sight, but only look towards enemy noises, dont investigate
SELF_DEFENSE,// only engage if fired on, or very close to enemy
IGNORE_ENEMIES,// ignore all enemies - useful for ducking around corners, running away, etc
NUM_DISPOSITIONS
};
voidSetDisposition(DispositionTypedisposition);// define how we react to enemies
DispositionTypeGetDisposition()const;// return enum describing current disposition
voidIgnoreEnemies(floatduration);// ignore enemies for a short duration
enumMoraleType
{
TERRIBLE=-3,
BAD=-2,
NEGATIVE=-1,
NEUTRAL=0,
POSITIVE=1,
GOOD=2,
EXCELLENT=3,
};
MoraleTypeGetMorale()const;// return enum describing current morale
voidIncreaseMorale();
voidDecreaseMorale();
// listening for noises
boolIsNoiseHeard()const;// return true if we have heard a noise
// BOTPORT: GetEnemy() collides with GetEnemy() in CBaseEntity - need to use different nomenclature
voidSetEnemy(CBasePlayer*enemy);// set given player as our current enemy
CBasePlayer*GetEnemy();
intGetNearbyEnemyCount()const;// return max number of nearby enemies we've seen recently
unsignedintGetEnemyPlace()const;// return location where we see the majority of our enemies
boolCanSeeBomber()const;// return true if we can see the bomb carrier
CBasePlayer*GetBomber()const;
intGetNearbyFriendCount()const;// return number of nearby teammates
CBasePlayer*GetClosestVisibleFriend()const;// return the closest friend that we can see
CBasePlayer*GetClosestVisibleHumanFriend()const;// return the closest human friend that we can see
boolIsOutnumbered()const;// return true if we are outnumbered by enemies
intOutnumberedCount()const;// return number of enemies we are outnumbered by
#define ONLY_VISIBLE_ENEMIES true
CBasePlayer*GetImportantEnemy(boolcheckVisibility=false)const;// return the closest "important" enemy for the given scenario (bomb carrier, VIP, hostage escorter)
voidUpdateReactionQueue();// update our reaction time queue
CBasePlayer*GetRecognizedEnemy();// return the most dangerous threat we are "conscious" of
boolIsRecognizedEnemyReloading();// return true if the enemy we are "conscious" of is reloading
boolIsRecognizedEnemyProtectedByShield();// return true if the enemy we are "conscious" of is hiding behind a shield
floatGetRangeToNearestRecognizedEnemy();// return distance to closest enemy we are "conscious" of
CBasePlayer*GetAttacker()const;// return last enemy that hurt us
floatGetTimeSinceAttacked()const;// return duration since we were last injured by an attacker
floatGetFirstSawEnemyTimestamp()const;// time since we saw any enemies
floatGetLastSawEnemyTimestamp()const;
floatGetTimeSinceLastSawEnemy()const;
floatGetTimeSinceAcquiredCurrentEnemy()const;
boolHasNotSeenEnemyForLongTime()const;// return true if we haven't seen an enemy for "a long time"
constVector&GetLastKnownEnemyPosition()const;
boolIsEnemyVisible()const;// is our current enemy visible
floatGetEnemyDeathTimestamp()const;
boolIsFriendInLineOfFire();// return true if a friend is in our weapon's way
boolIsAwareOfEnemyDeath()const;// return true if we *noticed* that our enemy died
intGetLastVictimID()const;// return the ID (entindex) of the last victim we killed, or zero
// navigation
boolHasPath()const;
voidDestroyPath();
floatGetFeetZ()const;// return Z of bottom of feet
enumPathResult
{
PROGRESSING,// we are moving along the path
END_OF_PATH,// we reached the end of the path
PATH_FAILURE,// we failed to reach the end of the path
};
#define NO_SPEED_CHANGE false
PathResultUpdatePathMovement(boolallowSpeedChange=true);// move along our computed path - if allowSpeedChange is true, bot will walk when near goal to ensure accuracy
NOXREFboolAStarSearch(CNavArea*startArea,CNavArea*goalArea);// find shortest path from startArea to goalArea - don't actually buid the path
boolComputePath(CNavArea*goalArea,constVector*goal,RouteTyperoute);// compute path to goal position
boolStayOnNavMesh();
CNavArea*GetLastKnownArea()const;// return the last area we know we were inside of
constVector&GetPathEndpoint()const;// return final position of our current path
floatGetPathDistanceRemaining()const;// eturn estimated distance left to travel along path
voidResetStuckMonitor();
NOXREFboolIsAreaVisible(CNavArea*area)const;// is any portion of the area visible to this bot
constVector&GetPathPosition(intnumpath)const;
boolGetSimpleGroundHeightWithFloor(constVector*pos,float*height,Vector*normal=NULL);// find "simple" ground height, treating current nav area as part of the floor
PlaceGetPlace()const;// get our current radio chatter place
boolIsUsingLadder()const;// returns true if we are in the process of negotiating a ladder
voidGetOffLadder();
voidSetGoalEntity(CBaseEntity*entity);
CBaseEntity*GetGoalEntity();
boolIsNearJump()const;// return true if nearing a jump in the path
floatGetApproximateFallDamage(floatheight)const;// return how much damage will will take from the given fall height
voidForceRun(floatduration);// force the bot to run if it moves for the given duration
voidWiggle();// random movement, for getting un-stuck
boolIsFriendInTheWay(constVector*goalPos)const;// return true if a friend is between us and the given position
voidFeelerReflexAdjustment(Vector*goalPosition);// do reflex avoidance movements if our "feelers" are touched
// looking around
voidSetLookAngles(floatyaw,floatpitch);// set our desired look angles
voidUpdateLookAngles();// move actual view angles towards desired ones
Vectorm_approachPointViewPosition;// the position used when computing current approachPoint set
boolBendLineOfSight(constVector*eye,constVector*point,Vector*bend)const;// "bend" our line of sight until we can see the target point. Return bend point, false if cant bend.
NOXREFboolFindApproachPointNearestPath(Vector*pos);// find the approach point that is nearest to our current path, ahead of us
boolm_isWaitingToTossGrenade;// lining up throw
CountdownTimerm_tossGrenadeTimer;// timeout timer for grenade tossing
SpotEncounter*m_spotEncounter;// the spots we will encounter as we move thru our current area
floatm_spotCheckTimestamp;// when to check next encounter spot
// TODO: Add timestamp for each possible client to hiding spots
enum{MAX_CHECKED_SPOTS=64};
structHidingSpotCheckInfo
{
HidingSpot*spot;
floattimestamp;
}
m_checkedHidingSpot[MAX_CHECKED_SPOTS];
intm_checkedHidingSpotCount;
// view angle mechanism
floatm_lookPitch;// our desired look pitch angle
floatm_lookPitchVel;
floatm_lookYaw;// our desired look yaw angle
floatm_lookYawVel;
// aim angle mechanism
mutableVectorm_eyePos;
Vectorm_aimOffset;// current error added to victim's position to get actual aim spot
Vectorm_aimOffsetGoal;// desired aim offset
floatm_aimOffsetTimestamp;// time of next offset adjustment
floatm_aimSpreadTimestamp;// time used to determine max spread as it begins to tighten up
voidSetAimOffset(floataccuracy);// set the current aim offset
voidUpdateAimOffset();// wiggle aim error based on m_accuracy
Vectorm_aimSpot;// the spot we are currently aiming to fire at
// attack state data
DispositionTypem_disposition;// how we will react to enemies
CountdownTimerm_ignoreEnemiesTimer;// how long will we ignore enemies
mutableEHANDLEm_enemy;// our current enemy
boolm_isEnemyVisible;// result of last visibility test on enemy
unsignedcharm_visibleEnemyParts;// which parts of the visible enemy do we see
Vectorm_lastEnemyPosition;// last place we saw the enemy
floatm_lastSawEnemyTimestamp;
floatm_firstSawEnemyTimestamp;
floatm_currentEnemyAcquireTimestamp;
floatm_enemyDeathTimestamp;// if m_enemy is dead, this is when he died
boolm_isLastEnemyDead;// true if we killed or saw our last enemy die
intm_nearbyEnemyCount;// max number of enemies we've seen recently
unsignedintm_enemyPlace;// the location where we saw most of our enemies
structWatchInfo
{
floattimestamp;
boolisEnemy;
}
m_watchInfo[MAX_CLIENTS];
mutableEHANDLEm_bomber;// points to bomber if we can see him
intm_nearbyFriendCount;// number of nearby teammates
mutableEHANDLEm_closestVisibleFriend;// the closest friend we can see
mutableEHANDLEm_closestVisibleHumanFriend;// the closest human friend we can see
CBasePlayer*m_attacker;// last enemy that hurt us (may not be same as m_enemy)
floatm_attackedTimestamp;// when we were hurt by the m_attacker
intm_lastVictimID;// the entindex of the last victim we killed, or zero
boolm_isAimingAtEnemy;// if true, we are trying to aim at our enemy
boolm_isRapidFiring;// if true, RunUpkeep() will toggle our primary attack as fast as it can
IntervalTimerm_equipTimer;// how long have we had our current weapon equipped
boolDoEquip(CBasePlayerWeapon*gun);// equip the given item
voidReloadCheck();// reload our weapon if we must
voidSilencerCheck();// use silencer
floatm_fireWeaponTimestamp;
// reaction time system
enum{MAX_ENEMY_QUEUE=20};
structReactionState
{
// NOTE: player position & orientation is not currently stored separately
EHANDLEplayer;
boolisReloading;
boolisProtectedByShield;
}
m_enemyQueue[MAX_ENEMY_QUEUE];// round-robin queue for simulating reaction times
bytem_enemyQueueIndex;
bytem_enemyQueueCount;
bytem_enemyQueueAttendIndex;// index of the timeframe we are "conscious" of
CBasePlayer*FindMostDangerousThreat();// return most dangerous threat in my field of view (feeds into reaction time queue)
// stuck detection
boolm_isStuck;
floatm_stuckTimestamp;// time when we got stuck
Vectorm_stuckSpot;// the location where we became stuck
NavRelativeDirTypem_wiggleDirection;
floatm_wiggleTimestamp;
floatm_stuckJumpTimestamp;// time for next jump when stuck
enum{MAX_VEL_SAMPLES=5};
floatm_avgVel[MAX_VEL_SAMPLES];
intm_avgVelIndex;
intm_avgVelCount;
Vectorm_lastOrigin;
// chatter mechanism
GameEventTypem_lastRadioCommand;// last radio command we recieved
voidRespondToRadioCommands();
boolIsRadioCommand(GameEventTypeevent)const;// returns true if the radio message is an order to do something
#define NO_FORCE false
voidEndVoiceFeedback(boolforce=true);
floatm_lastRadioRecievedTimestamp;// time we recieved a radio message
floatm_lastRadioSentTimestamp;// time when we send a radio message
EHANDLEm_radioSubject;// who issued the radio message
Vectorm_radioPosition;// position referred to in radio message